]> git.proxmox.com Git - mirror_qemu.git/blobdiff - docs/writing-qmp-commands.txt
qcow2: Discard unaligned tail when wiping image
[mirror_qemu.git] / docs / writing-qmp-commands.txt
index 0472fc391442e0cb1633405440d0468380f7ecf1..1e6375495be71c7406b7d87097fc0213fffc12f4 100644 (file)
@@ -7,8 +7,8 @@ This document doesn't discuss QMP protocol level details, nor does it dive
 into the QAPI framework implementation.
 
 For an in-depth introduction to the QAPI framework, please refer to
-docs/qapi-code-gen.txt. For documentation about the QMP protocol, please
-check the files in QMP/.
+docs/qapi-code-gen.txt. For documentation about the QMP protocol,
+start with docs/qmp-intro.txt.
 
 == Overview ==
 
@@ -119,17 +119,6 @@ There are a few things to be noticed:
 5. Printing to the terminal is discouraged for QMP commands, we do it here
    because it's the easiest way to demonstrate a QMP command
 
-Now a little hack is needed. As we're still using the old QMP server we need
-to add the new command to its internal dispatch table. This step won't be
-required in the near future. Open the qmp-commands.hx file and add the
-following in the botton:
-
-    {
-        .name       = "hello-world",
-        .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_input_hello_world,
-    },
-
 You're done. Now build qemu, run it as suggested in the "Testing" section,
 and then type the following QMP command:
 
@@ -174,21 +163,6 @@ There are two important details to be noticed:
 2. The C implementation signature must follow the schema's argument ordering,
    which is defined by the "data" member
 
-The last step is to update the qmp-commands.hx file:
-
-    {
-        .name       = "hello-world",
-        .args_type  = "message:s?",
-        .mhandler.cmd_new = qmp_marshal_input_hello_world,
-    },
-
-Notice that the "args_type" member got our "message" argument. The character
-"s" stands for "string" and "?" means it's optional. This too must be ordered
-according to the C implementation and schema file. You can look for more
-examples in the qmp-commands.hx file if you need to define more arguments.
-
-Again, this step won't be required in the future.
-
 Time to test our new version of the "hello-world" command. Build qemu, run it as
 described in the "Testing" section and then send two commands:
 
@@ -210,19 +184,16 @@ if you don't see these strings, then something went wrong.
 === Errors ===
 
 QMP commands should use the error interface exported by the error.h header
-file. The basic function used to set an error is the error_set() one.
+file. Basically, most errors are set by calling the error_setg() function.
 
 Let's say we don't accept the string "message" to contain the word "love". If
-it does contain it, we want the "hello-world" command to the return the
-InvalidParameter error.
-
-Only one change is required, and it's in the C implementation:
+it does contain it, we want the "hello-world" command to return an error:
 
 void qmp_hello_world(bool has_message, const char *message, Error **errp)
 {
     if (has_message) {
         if (strstr(message, "love")) {
-            error_set(errp, QERR_INVALID_PARAMETER, "message");
+            error_setg(errp, "the word 'love' is not allowed");
             return;
         }
         printf("%s\n", message);
@@ -231,30 +202,39 @@ void qmp_hello_world(bool has_message, const char *message, Error **errp)
     }
 }
 
-Let's test it. Build qemu, run it as defined in the "Testing" section, and
-then issue the following command:
+The first argument to the error_setg() function is the Error pointer
+to pointer, which is passed to all QMP functions. The next argument is a human
+description of the error, this is a free-form printf-like string.
 
-{ "execute": "hello-world", "arguments": { "message": "we love qemu" } }
+Let's test the example above. Build qemu, run it as defined in the "Testing"
+section, and then issue the following command:
+
+{ "execute": "hello-world", "arguments": { "message": "all you need is love" } }
 
 The QMP server's response should be:
 
 {
     "error": {
-        "class": "InvalidParameter",
-        "desc": "Invalid parameter 'message'",
-        "data": {
-            "name": "message"
-        }
+        "class": "GenericError",
+        "desc": "the word 'love' is not allowed"
     }
 }
 
-Which is the InvalidParameter error.
+As a general rule, all QMP errors should use ERROR_CLASS_GENERIC_ERROR
+(done by default when using error_setg()). There are two exceptions to
+this rule:
+
+ 1. A non-generic ErrorClass value exists* for the failure you want to report
+    (eg. DeviceNotFound)
+
+ 2. Management applications have to take special action on the failure you
+    want to report, hence you have to add a new ErrorClass value so that they
+    can check for it
 
-When you have to return an error but you're unsure what error to return or
-which arguments an error takes, you should look at the qerror.h file. Note
-that you might be required to add new errors if needed.
+If the failure you want to report falls into one of the two cases above,
+use error_set() with a second argument of an ErrorClass value.
 
-FIXME: describe better the error API and how to add new errors.
+ * All existing ErrorClass values are defined in the qapi-schema.json file
 
 === Command Documentation ===
 
@@ -272,10 +252,9 @@ here goes "hello-world"'s new entry for the qapi-schema.json file:
 #
 # Print a client provided string to the standard output stream.
 #
-# @message: #optional string to be printed
+# @message: string to be printed
 #
 # Returns: Nothing on success.
-#          If @message contains "love", InvalidParameter
 #
 # Notes: if @message is not provided, the "Hello, world" string will
 #        be printed instead
@@ -301,12 +280,12 @@ Here's the implementation of the "hello-world" HMP command:
 void hmp_hello_world(Monitor *mon, const QDict *qdict)
 {
     const char *message = qdict_get_try_str(qdict, "message");
-    Error *errp = NULL;
+    Error *err = NULL;
 
-    qmp_hello_world(!!message, message, &errp);
-    if (error_is_set(&errp)) {
-        monitor_printf(mon, "%s\n", error_get_pretty(errp));
-        error_free(errp);
+    qmp_hello_world(!!message, message, &err);
+    if (err) {
+        monitor_printf(mon, "%s\n", error_get_pretty(err));
+        error_free(err);
         return;
     }
 }
@@ -321,7 +300,7 @@ There are three important points to be noticed:
 2. hmp_hello_world() performs error checking. In this example we just print
    the error description to the user, but we could do more, like taking
    different actions depending on the error qmp_hello_world() returns
-3. The "errp" variable must be initialized to NULL before performing the
+3. The "err" variable must be initialized to NULL before performing the
    QMP call
 
 There's one last step to actually make the command available to monitor users,
@@ -332,7 +311,7 @@ we should add it to the hmp-commands.hx file:
         .args_type  = "message:s?",
         .params     = "hello-world [message]",
         .help       = "Print message to the standard output",
-        .mhandler.cmd = hmp_hello_world,
+        .cmd        = hmp_hello_world,
     },
 
 STEXI
@@ -358,6 +337,8 @@ documentation for information about the other types.
 
 === User Defined Types ===
 
+FIXME This example needs to be redone after commit 6d32717
+
 For this example we will write the query-alarm-clock command, which returns
 information about QEMU's timer alarm. For more information about it, please
 check the "-clock" command-line option.
@@ -377,7 +358,7 @@ The best way to return that data is to create a new QAPI type, as shown below:
 #
 # @clock-name: The alarm clock method's name.
 #
-# @next-deadline: #optional The time (in nanoseconds) the next alarm will fire.
+# @next-deadline: The time (in nanoseconds) the next alarm will fire.
 #
 # Since: 1.0
 ##
@@ -435,7 +416,7 @@ There are a number of things to be noticed:
    for all QMP functions)
 3. The "clock" variable (which will point to our QAPI type instance) is
    allocated by the regular g_malloc0() function. Note that we chose to
-   initialize the memory to zero. This is recomended for all QAPI types, as
+   initialize the memory to zero. This is recommended for all QAPI types, as
    it helps avoiding bad surprises (specially with booleans)
 4. Remember that "next_deadline" is optional? All optional members have a
    'has_TYPE_NAME' member that should be properly set by the implementation,
@@ -447,14 +428,6 @@ There are a number of things to be noticed:
 6. You have to include the "qmp-commands.h" header file in qemu-timer.c,
    otherwise qemu won't build
 
-The last step is to add the correspoding entry in the qmp-commands.hx file:
-
-    {
-        .name       = "query-alarm-clock",
-        .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_input_query_alarm_clock,
-    },
-
 Time to test the new command. Build qemu, run it as described in the "Testing"
 section and try this:
 
@@ -473,12 +446,12 @@ Here's the HMP counterpart of the query-alarm-clock command:
 void hmp_info_alarm_clock(Monitor *mon)
 {
     QemuAlarmClock *clock;
-    Error *errp = NULL;
+    Error *err = NULL;
 
-    clock = qmp_query_alarm_clock(&errp);
-    if (error_is_set(&errp)) {
+    clock = qmp_query_alarm_clock(&err);
+    if (err) {
         monitor_printf(mon, "Could not query alarm clock information\n");
-        error_free(errp);
+        error_free(err);
         return;
     }
 
@@ -511,7 +484,7 @@ in the monitor.c file. The entry for the "info alarmclock" follows:
         .args_type  = "",
         .params     = "",
         .help       = "show information about the alarm clock",
-        .mhandler.info = hmp_info_alarm_clock,
+        .cmd        = hmp_info_alarm_clock,
     },
 
 To test this, run qemu and type "info alarmclock" in the user monitor.
@@ -589,18 +562,10 @@ stored in its "value" member. In our example, the "value" member is a pointer
 to an TimerAlarmMethod instance.
 
 Notice that the "current" variable is used as "true" only in the first
-interation of the loop. That's because the alarm timer method in use is the
+iteration of the loop. That's because the alarm timer method in use is the
 first element of the alarm_timers array. Also notice that QAPI lists are handled
 by hand and we return the head of the list.
 
-To test this you have to add the corresponding qmp-commands.hx entry:
-
-    {
-        .name       = "query-alarm-methods",
-        .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_input_query_alarm_methods,
-    },
-
 Now Build qemu, run it as explained in the "Testing" section and try our new
 command:
 
@@ -624,12 +589,12 @@ has to traverse the list, it's shown below for reference:
 void hmp_info_alarm_methods(Monitor *mon)
 {
     TimerAlarmMethodList *method_list, *method;
-    Error *errp = NULL;
+    Error *err = NULL;
 
-    method_list = qmp_query_alarm_methods(&errp);
-    if (error_is_set(&errp)) {
+    method_list = qmp_query_alarm_methods(&err);
+    if (err) {
         monitor_printf(mon, "Could not query alarm methods\n");
-        error_free(errp);
+        error_free(err);
         return;
     }