diff mbox

[05/12] monitor: register the qapi generated commands

Message ID 20160623000809.4522-6-marcandre.lureau@redhat.com
State New
Headers show

Commit Message

Marc-André Lureau June 23, 2016, 12:08 a.m. UTC
From: Marc-André Lureau <marcandre.lureau@redhat.com>

Stop using the so-called 'middle' mode. Instead, use qmp_find_command()
from generated qapi commands registry.

Note: this commit requires a 'make clean' prior to make, since the
generated files do not depend on Makefile (due to a cyclic rule
introduced in 4115852bb0).

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 Makefile        |   2 +-
 monitor.c       |  12 +++--
 qmp-commands.hx | 143 --------------------------------------------------------
 vl.c            |   1 +
 4 files changed, 11 insertions(+), 147 deletions(-)

Comments

Paolo Bonzini June 23, 2016, 4:38 a.m. UTC | #1
On 23/06/2016 02:08, marcandre.lureau@redhat.com wrote:
> 
> Stop using the so-called 'middle' mode. Instead, use qmp_find_command()
> from generated qapi commands registry.
> 
> Note: this commit requires a 'make clean' prior to make, since the
> generated files do not depend on Makefile (due to a cyclic rule
> introduced in 4115852bb0).
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

What is the cyclic dependency?

Paolo
Marc-Andre Lureau June 23, 2016, 9:02 a.m. UTC | #2
Hi

----- Original Message -----
> 
> 
> On 23/06/2016 02:08, marcandre.lureau@redhat.com wrote:
> > 
> > Stop using the so-called 'middle' mode. Instead, use qmp_find_command()
> > from generated qapi commands registry.
> > 
> > Note: this commit requires a 'make clean' prior to make, since the
> > generated files do not depend on Makefile (due to a cyclic rule
> > introduced in 4115852bb0).
> > 
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> 
> What is the cyclic dependency?

We have in Makefile.target:

Makefile: $(GENERATED_HEADERS)

But we should also or rather have:

$(GENERATED_HEADERS) $(GENERATED_SOURCES): Makefile:

That would be cyclic.


I understand the first rule was added to simplify the dependencies and make sure the generated files are done prior to any building. But it sounds like it's not a conventional way to write your rules and prevent proper dependencies.

Do you know another trick we could use for the generated files?

regards
Eric Blake June 24, 2016, 4:31 a.m. UTC | #3
On 06/22/2016 06:08 PM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
> 
> Stop using the so-called 'middle' mode. Instead, use qmp_find_command()
> from generated qapi commands registry.
> 
> Note: this commit requires a 'make clean' prior to make, since the
> generated files do not depend on Makefile (due to a cyclic rule
> introduced in 4115852bb0).

I'm not as well-versed as Paolo on Makefile issues, so I won't comment
on that part of the patch.

> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  Makefile        |   2 +-
>  monitor.c       |  12 +++--
>  qmp-commands.hx | 143 --------------------------------------------------------
>  vl.c            |   1 +
>  4 files changed, 11 insertions(+), 147 deletions(-)
> 

> +++ b/monitor.c
> @@ -3884,6 +3884,7 @@ static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens)
>      QObject *obj, *data;
>      QDict *input, *args;
>      const mon_cmd_t *cmd;
> +    QmpCommand *qcmd;
>      const char *cmd_name;
>      Monitor *mon = cur_mon;
>  
> @@ -3909,7 +3910,8 @@ static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens)
>      cmd_name = qdict_get_str(input, "execute");
>      trace_handle_qmp_command(mon, cmd_name);
>      cmd = qmp_find_cmd(cmd_name);
> -    if (!cmd) {
> +    qcmd = qmp_find_command(cmd_name);

Is it worth creating a single type that contains both mon_cmd_t and
QmpCommand information, so that we don't need two similarly-named
functions to look up two related pieces of information?  Not necessarily
in this patch.

> +    if (!qcmd || !cmd) {
>          error_set(&local_err, ERROR_CLASS_COMMAND_NOT_FOUND,
>                    "The command %s has not been found", cmd_name);
>          goto err_out;
> @@ -3931,7 +3933,7 @@ static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens)
>          goto err_out;
>      }
>  
> -    cmd->mhandler.cmd_new(args, &data, &local_err);
> +    qcmd->fn(args, &data, &local_err);
>  
>  err_out:
>      monitor_protocol_emitter(mon, data, local_err);
> @@ -4000,9 +4002,13 @@ void monitor_resume(Monitor *mon)
>  
>  static QObject *get_qmp_greeting(void)
>  {
> +    QmpCommand *cmd;
>      QObject *ver = NULL;
>  
> -    qmp_marshal_query_version(NULL, &ver, NULL);
> +    cmd = qmp_find_command("query-version");
> +    assert(cmd && cmd->fn);
> +    cmd->fn(NULL, &ver, NULL);
> +
>      return qobject_from_jsonf("{'QMP':{'version': %p,'capabilities': []}}",ver);

Worth fixing the missing space after ',' while touching near here?

>  }
>  
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index ee88e48..95c1e7d 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -63,7 +63,6 @@ EQMP
>      {
>          .name       = "quit",
>          .args_type  = "",
> -        .mhandler.cmd_new = qmp_marshal_quit,

At one point, I posted an RFC patch for removing .args_type on most QMP
command listings in this file. Maybe you still do that later in your
series, but as my work definitely conflicts with yours, and your series
is older, I don't mind getting through your series first.

Overall, I like the general idea of automating things rather than having
to duplicate information in qmp-commands.hx.
Marc-André Lureau June 24, 2016, 2:17 p.m. UTC | #4
On Fri, Jun 24, 2016 at 6:31 AM, Eric Blake <eblake@redhat.com> wrote:
>> +    qcmd = qmp_find_command(cmd_name);
>
> Is it worth creating a single type that contains both mon_cmd_t and
> QmpCommand information, so that we don't need two similarly-named
> functions to look up two related pieces of information?  Not necessarily
> in this patch.

Well, this is only temporary. Theuse 'qmp_dispatch()' get rid of all that.

>
>> +    if (!qcmd || !cmd) {
>>          error_set(&local_err, ERROR_CLASS_COMMAND_NOT_FOUND,
>>                    "The command %s has not been found", cmd_name);
>>          goto err_out;
>> @@ -3931,7 +3933,7 @@ static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens)
>>          goto err_out;
>>      }
>>
>> -    cmd->mhandler.cmd_new(args, &data, &local_err);
>> +    qcmd->fn(args, &data, &local_err);
>>
>>  err_out:
>>      monitor_protocol_emitter(mon, data, local_err);
>> @@ -4000,9 +4002,13 @@ void monitor_resume(Monitor *mon)
>>
>>  static QObject *get_qmp_greeting(void)
>>  {
>> +    QmpCommand *cmd;
>>      QObject *ver = NULL;
>>
>> -    qmp_marshal_query_version(NULL, &ver, NULL);
>> +    cmd = qmp_find_command("query-version");
>> +    assert(cmd && cmd->fn);
>> +    cmd->fn(NULL, &ver, NULL);
>> +
>>      return qobject_from_jsonf("{'QMP':{'version': %p,'capabilities': []}}",ver);
>
> Worth fixing the missing space after ',' while touching near here?

fine by me ;)

>
>>  }
>>
>> diff --git a/qmp-commands.hx b/qmp-commands.hx
>> index ee88e48..95c1e7d 100644
>> --- a/qmp-commands.hx
>> +++ b/qmp-commands.hx
>> @@ -63,7 +63,6 @@ EQMP
>>      {
>>          .name       = "quit",
>>          .args_type  = "",
>> -        .mhandler.cmd_new = qmp_marshal_quit,
>
> At one point, I posted an RFC patch for removing .args_type on most QMP
> command listings in this file. Maybe you still do that later in your
> series, but as my work definitely conflicts with yours, and your series
> is older, I don't mind getting through your series first.

> Overall, I like the general idea of automating things rather than having
> to duplicate information in qmp-commands.hx.

Yeah, I basically get rid of qmp-commands.hx in my series (and the doc
follow up in https://github.com/elmarco/qemu/commits/qapi-doc)
diff mbox

Patch

diff --git a/Makefile b/Makefile
index 7087fc2..81faf4b 100644
--- a/Makefile
+++ b/Makefile
@@ -311,7 +311,7 @@  $(qapi-modules) $(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
 qmp-commands.h qmp-marshal.c :\
 $(qapi-modules) $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
 	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
-		$(gen-out-type) -o "." -m $<, \
+		$(gen-out-type) -o "." $<, \
 		"  GEN   $@")
 qmp-introspect.h qmp-introspect.c :\
 $(qapi-modules) $(SRC_PATH)/scripts/qapi-introspect.py $(qapi-py)
diff --git a/monitor.c b/monitor.c
index 585bc1f..1dadc2a 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3884,6 +3884,7 @@  static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens)
     QObject *obj, *data;
     QDict *input, *args;
     const mon_cmd_t *cmd;
+    QmpCommand *qcmd;
     const char *cmd_name;
     Monitor *mon = cur_mon;
 
@@ -3909,7 +3910,8 @@  static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens)
     cmd_name = qdict_get_str(input, "execute");
     trace_handle_qmp_command(mon, cmd_name);
     cmd = qmp_find_cmd(cmd_name);
-    if (!cmd) {
+    qcmd = qmp_find_command(cmd_name);
+    if (!qcmd || !cmd) {
         error_set(&local_err, ERROR_CLASS_COMMAND_NOT_FOUND,
                   "The command %s has not been found", cmd_name);
         goto err_out;
@@ -3931,7 +3933,7 @@  static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens)
         goto err_out;
     }
 
-    cmd->mhandler.cmd_new(args, &data, &local_err);
+    qcmd->fn(args, &data, &local_err);
 
 err_out:
     monitor_protocol_emitter(mon, data, local_err);
@@ -4000,9 +4002,13 @@  void monitor_resume(Monitor *mon)
 
 static QObject *get_qmp_greeting(void)
 {
+    QmpCommand *cmd;
     QObject *ver = NULL;
 
-    qmp_marshal_query_version(NULL, &ver, NULL);
+    cmd = qmp_find_command("query-version");
+    assert(cmd && cmd->fn);
+    cmd->fn(NULL, &ver, NULL);
+
     return qobject_from_jsonf("{'QMP':{'version': %p,'capabilities': []}}",ver);
 }
 
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ee88e48..95c1e7d 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -63,7 +63,6 @@  EQMP
     {
         .name       = "quit",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_quit,
     },
 
 SQMP
@@ -84,7 +83,6 @@  EQMP
     {
         .name       = "eject",
         .args_type  = "force:-f,device:B",
-        .mhandler.cmd_new = qmp_marshal_eject,
     },
 
 SQMP
@@ -110,7 +108,6 @@  EQMP
     {
         .name       = "change",
         .args_type  = "device:B,target:F,arg:s?",
-        .mhandler.cmd_new = qmp_marshal_change,
     },
 
 SQMP
@@ -146,7 +143,6 @@  EQMP
     {
         .name       = "screendump",
         .args_type  = "filename:F",
-        .mhandler.cmd_new = qmp_marshal_screendump,
     },
 
 SQMP
@@ -169,7 +165,6 @@  EQMP
     {
         .name       = "stop",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_stop,
     },
 
 SQMP
@@ -190,7 +185,6 @@  EQMP
     {
         .name       = "cont",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_cont,
     },
 
 SQMP
@@ -211,7 +205,6 @@  EQMP
     {
         .name       = "system_wakeup",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_system_wakeup,
     },
 
 SQMP
@@ -232,7 +225,6 @@  EQMP
     {
         .name       = "system_reset",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_system_reset,
     },
 
 SQMP
@@ -253,7 +245,6 @@  EQMP
     {
         .name       = "system_powerdown",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_system_powerdown,
     },
 
 SQMP
@@ -276,7 +267,6 @@  EQMP
         .args_type  = "device:O",
         .params     = "driver[,prop=value][,...]",
         .help       = "add device, like -device on the command line",
-        .mhandler.cmd_new = qmp_device_add,
     },
 
 SQMP
@@ -310,7 +300,6 @@  EQMP
     {
         .name       = "device_del",
         .args_type  = "id:s",
-        .mhandler.cmd_new = qmp_marshal_device_del,
     },
 
 SQMP
@@ -338,7 +327,6 @@  EQMP
     {
         .name       = "send-key",
         .args_type  = "keys:q,hold-time:i?",
-        .mhandler.cmd_new = qmp_marshal_send_key,
     },
 
 SQMP
@@ -369,7 +357,6 @@  EQMP
     {
         .name       = "cpu",
         .args_type  = "index:i",
-        .mhandler.cmd_new = qmp_marshal_cpu,
     },
 
 SQMP
@@ -394,7 +381,6 @@  EQMP
     {
         .name       = "cpu-add",
         .args_type  = "id:i",
-        .mhandler.cmd_new = qmp_marshal_cpu_add,
     },
 
 SQMP
@@ -417,7 +403,6 @@  EQMP
     {
         .name       = "memsave",
         .args_type  = "val:l,size:i,filename:s,cpu:i?",
-        .mhandler.cmd_new = qmp_marshal_memsave,
     },
 
 SQMP
@@ -446,7 +431,6 @@  EQMP
     {
         .name       = "pmemsave",
         .args_type  = "val:l,size:i,filename:s",
-        .mhandler.cmd_new = qmp_marshal_pmemsave,
     },
 
 SQMP
@@ -474,7 +458,6 @@  EQMP
     {
         .name       = "inject-nmi",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_inject_nmi,
     },
 
 SQMP
@@ -497,7 +480,6 @@  EQMP
     {
         .name       = "ringbuf-write",
         .args_type  = "device:s,data:s,format:s?",
-        .mhandler.cmd_new = qmp_marshal_ringbuf_write,
     },
 
 SQMP
@@ -526,7 +508,6 @@  EQMP
     {
         .name       = "ringbuf-read",
         .args_type  = "device:s,size:i,format:s?",
-        .mhandler.cmd_new = qmp_marshal_ringbuf_read,
     },
 
 SQMP
@@ -562,7 +543,6 @@  EQMP
     {
         .name       = "xen-save-devices-state",
         .args_type  = "filename:F",
-    .mhandler.cmd_new = qmp_marshal_xen_save_devices_state,
     },
 
 SQMP
@@ -589,7 +569,6 @@  EQMP
     {
         .name       = "xen-load-devices-state",
         .args_type  = "filename:F",
-        .mhandler.cmd_new = qmp_marshal_xen_load_devices_state,
     },
 
 SQMP
@@ -616,7 +595,6 @@  EQMP
     {
         .name       = "xen-set-global-dirty-log",
         .args_type  = "enable:b",
-        .mhandler.cmd_new = qmp_marshal_xen_set_global_dirty_log,
     },
 
 SQMP
@@ -640,7 +618,6 @@  EQMP
     {
         .name       = "migrate",
         .args_type  = "detach:-d,blk:-b,inc:-i,uri:s",
-        .mhandler.cmd_new = qmp_marshal_migrate,
     },
 
 SQMP
@@ -673,7 +650,6 @@  EQMP
     {
         .name       = "migrate_cancel",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_migrate_cancel,
     },
 
 SQMP
@@ -694,7 +670,6 @@  EQMP
     {
         .name       = "migrate-incoming",
         .args_type  = "uri:s",
-        .mhandler.cmd_new = qmp_marshal_migrate_incoming,
     },
 
 SQMP
@@ -722,7 +697,6 @@  EQMP
     {
         .name       = "migrate-set-cache-size",
         .args_type  = "value:o",
-        .mhandler.cmd_new = qmp_marshal_migrate_set_cache_size,
     },
 
 SQMP
@@ -745,7 +719,6 @@  EQMP
     {
         .name       = "migrate-start-postcopy",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_migrate_start_postcopy,
     },
 
 SQMP
@@ -764,7 +737,6 @@  EQMP
     {
         .name       = "query-migrate-cache-size",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_migrate_cache_size,
     },
 
 SQMP
@@ -786,7 +758,6 @@  EQMP
     {
         .name       = "migrate_set_speed",
         .args_type  = "value:o",
-        .mhandler.cmd_new = qmp_marshal_migrate_set_speed,
     },
 
 SQMP
@@ -809,7 +780,6 @@  EQMP
     {
         .name       = "migrate_set_downtime",
         .args_type  = "value:T",
-        .mhandler.cmd_new = qmp_marshal_migrate_set_downtime,
     },
 
 SQMP
@@ -834,7 +804,6 @@  EQMP
         .args_type  = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?",
         .params     = "protocol hostname port tls-port cert-subject",
         .help       = "set migration information for remote display",
-        .mhandler.cmd_new = qmp_marshal_client_migrate_info,
     },
 
 SQMP
@@ -868,7 +837,6 @@  EQMP
         .args_type  = "paging:b,protocol:s,detach:b?,begin:i?,end:i?,format:s?",
         .params     = "-p protocol [-d] [begin] [length] [format]",
         .help       = "dump guest memory to file",
-        .mhandler.cmd_new = qmp_marshal_dump_guest_memory,
     },
 
 SQMP
@@ -907,7 +875,6 @@  EQMP
     {
         .name       = "query-dump-guest-memory-capability",
         .args_type  = "",
-    .mhandler.cmd_new = qmp_marshal_query_dump_guest_memory_capability,
     },
 
 SQMP
@@ -929,7 +896,6 @@  EQMP
         .args_type  = "",
         .params     = "",
         .help       = "query background dump status",
-        .mhandler.cmd_new = qmp_marshal_query_dump,
     },
 
 SQMP
@@ -952,7 +918,6 @@  EQMP
     {
         .name       = "dump-skeys",
         .args_type  = "filename:F",
-        .mhandler.cmd_new = qmp_marshal_dump_skeys,
     },
 #endif
 
@@ -976,7 +941,6 @@  EQMP
     {
         .name       = "netdev_add",
         .args_type  = "netdev:O",
-        .mhandler.cmd_new = qmp_marshal_netdev_add,
     },
 
 SQMP
@@ -1007,7 +971,6 @@  EQMP
     {
         .name       = "netdev_del",
         .args_type  = "id:s",
-        .mhandler.cmd_new = qmp_marshal_netdev_del,
     },
 
 SQMP
@@ -1031,7 +994,6 @@  EQMP
     {
         .name       = "object-add",
         .args_type  = "qom-type:s,id:s,props:q?",
-        .mhandler.cmd_new = qmp_marshal_object_add,
     },
 
 SQMP
@@ -1057,7 +1019,6 @@  EQMP
     {
         .name       = "object-del",
         .args_type  = "id:s",
-        .mhandler.cmd_new = qmp_marshal_object_del,
     },
 
 SQMP
@@ -1082,7 +1043,6 @@  EQMP
     {
         .name       = "block_resize",
         .args_type  = "device:s?,node-name:s?,size:o",
-        .mhandler.cmd_new = qmp_marshal_block_resize,
     },
 
 SQMP
@@ -1107,7 +1067,6 @@  EQMP
     {
         .name       = "block-stream",
         .args_type  = "device:B,base:s?,speed:o?,backing-file:s?,on-error:s?",
-        .mhandler.cmd_new = qmp_marshal_block_stream,
     },
 
 SQMP
@@ -1150,7 +1109,6 @@  EQMP
     {
         .name       = "block-commit",
         .args_type  = "device:B,base:s?,top:s?,backing-file:s?,speed:o?",
-        .mhandler.cmd_new = qmp_marshal_block_commit,
     },
 
 SQMP
@@ -1214,7 +1172,6 @@  EQMP
         .name       = "drive-backup",
         .args_type  = "sync:s,device:B,target:s,speed:i?,mode:s?,format:s?,"
                       "bitmap:s?,on-source-error:s?,on-target-error:s?",
-        .mhandler.cmd_new = qmp_marshal_drive_backup,
     },
 
 SQMP
@@ -1268,7 +1225,6 @@  EQMP
         .name       = "blockdev-backup",
         .args_type  = "sync:s,device:B,target:B,speed:i?,"
                       "on-source-error:s?,on-target-error:s?",
-        .mhandler.cmd_new = qmp_marshal_blockdev_backup,
     },
 
 SQMP
@@ -1308,33 +1264,27 @@  EQMP
     {
         .name       = "block-job-set-speed",
         .args_type  = "device:B,speed:o",
-        .mhandler.cmd_new = qmp_marshal_block_job_set_speed,
     },
 
     {
         .name       = "block-job-cancel",
         .args_type  = "device:B,force:b?",
-        .mhandler.cmd_new = qmp_marshal_block_job_cancel,
     },
     {
         .name       = "block-job-pause",
         .args_type  = "device:B",
-        .mhandler.cmd_new = qmp_marshal_block_job_pause,
     },
     {
         .name       = "block-job-resume",
         .args_type  = "device:B",
-        .mhandler.cmd_new = qmp_marshal_block_job_resume,
     },
     {
         .name       = "block-job-complete",
         .args_type  = "device:B",
-        .mhandler.cmd_new = qmp_marshal_block_job_complete,
     },
     {
         .name       = "transaction",
         .args_type  = "actions:q,properties:q?",
-        .mhandler.cmd_new = qmp_marshal_transaction,
     },
 
 SQMP
@@ -1428,7 +1378,6 @@  EQMP
     {
         .name       = "block-dirty-bitmap-add",
         .args_type  = "node:B,name:s,granularity:i?",
-        .mhandler.cmd_new = qmp_marshal_block_dirty_bitmap_add,
     },
 
 SQMP
@@ -1456,7 +1405,6 @@  EQMP
     {
         .name       = "block-dirty-bitmap-remove",
         .args_type  = "node:B,name:s",
-        .mhandler.cmd_new = qmp_marshal_block_dirty_bitmap_remove,
     },
 
 SQMP
@@ -1484,7 +1432,6 @@  EQMP
     {
         .name       = "block-dirty-bitmap-clear",
         .args_type  = "node:B,name:s",
-        .mhandler.cmd_new = qmp_marshal_block_dirty_bitmap_clear,
     },
 
 SQMP
@@ -1513,7 +1460,6 @@  EQMP
     {
         .name       = "blockdev-snapshot-sync",
         .args_type  = "device:s?,node-name:s?,snapshot-file:s,snapshot-node-name:s?,format:s?,mode:s?",
-        .mhandler.cmd_new = qmp_marshal_blockdev_snapshot_sync,
     },
 
 SQMP
@@ -1549,7 +1495,6 @@  EQMP
     {
         .name       = "blockdev-snapshot",
         .args_type  = "node:s,overlay:s",
-        .mhandler.cmd_new = qmp_marshal_blockdev_snapshot,
     },
 
 SQMP
@@ -1587,7 +1532,6 @@  EQMP
     {
         .name       = "blockdev-snapshot-internal-sync",
         .args_type  = "device:B,name:s",
-        .mhandler.cmd_new = qmp_marshal_blockdev_snapshot_internal_sync,
     },
 
 SQMP
@@ -1616,8 +1560,6 @@  EQMP
     {
         .name       = "blockdev-snapshot-delete-internal-sync",
         .args_type  = "device:B,id:s?,name:s?",
-        .mhandler.cmd_new =
-                      qmp_marshal_blockdev_snapshot_delete_internal_sync,
     },
 
 SQMP
@@ -1661,7 +1603,6 @@  EQMP
                       "on-source-error:s?,on-target-error:s?,"
                       "unmap:b?,"
                       "granularity:i?,buf-size:i?",
-        .mhandler.cmd_new = qmp_marshal_drive_mirror,
     },
 
 SQMP
@@ -1723,7 +1664,6 @@  EQMP
         .args_type  = "sync:s,device:B,target:B,replaces:s?,speed:i?,"
                       "on-source-error:s?,on-target-error:s?,"
                       "granularity:i?,buf-size:i?",
-        .mhandler.cmd_new = qmp_marshal_blockdev_mirror,
     },
 
 SQMP
@@ -1769,7 +1709,6 @@  EQMP
     {
         .name       = "change-backing-file",
         .args_type  = "device:s,image-node-name:s,backing-file:s",
-        .mhandler.cmd_new = qmp_marshal_change_backing_file,
     },
 
 SQMP
@@ -1808,7 +1747,6 @@  EQMP
     {
         .name       = "balloon",
         .args_type  = "value:M",
-        .mhandler.cmd_new = qmp_marshal_balloon,
     },
 
 SQMP
@@ -1831,7 +1769,6 @@  EQMP
     {
         .name       = "set_link",
         .args_type  = "name:s,up:b",
-        .mhandler.cmd_new = qmp_marshal_set_link,
     },
 
 SQMP
@@ -1857,7 +1794,6 @@  EQMP
         .args_type  = "fdname:s",
         .params     = "getfd name",
         .help       = "receive a file descriptor via SCM rights and assign it a name",
-        .mhandler.cmd_new = qmp_marshal_getfd,
     },
 
 SQMP
@@ -1890,7 +1826,6 @@  EQMP
         .args_type  = "fdname:s",
         .params     = "closefd name",
         .help       = "close a file descriptor previously passed via SCM rights",
-        .mhandler.cmd_new = qmp_marshal_closefd,
     },
 
 SQMP
@@ -1915,7 +1850,6 @@  EQMP
         .args_type  = "fdset-id:i?,opaque:s?",
         .params     = "add-fd fdset-id opaque",
         .help       = "Add a file descriptor, that was passed via SCM rights, to an fd set",
-        .mhandler.cmd_new = qmp_marshal_add_fd,
     },
 
 SQMP
@@ -1954,7 +1888,6 @@  EQMP
         .args_type  = "fdset-id:i,fd:i?",
         .params     = "remove-fd fdset-id fd",
         .help       = "Remove a file descriptor from an fd set",
-        .mhandler.cmd_new = qmp_marshal_remove_fd,
     },
 
 SQMP
@@ -1986,7 +1919,6 @@  EQMP
         .name       = "query-fdsets",
         .args_type  = "",
         .help       = "Return information describing all fd sets",
-        .mhandler.cmd_new = qmp_marshal_query_fdsets,
     },
 
 SQMP
@@ -2035,7 +1967,6 @@  EQMP
     {
         .name       = "block_passwd",
         .args_type  = "device:s?,node-name:s?,password:s",
-        .mhandler.cmd_new = qmp_marshal_block_passwd,
     },
 
 SQMP
@@ -2061,7 +1992,6 @@  EQMP
     {
         .name       = "block_set_io_throttle",
         .args_type  = "device:B,bps:l,bps_rd:l,bps_wr:l,iops:l,iops_rd:l,iops_wr:l,bps_max:l?,bps_rd_max:l?,bps_wr_max:l?,iops_max:l?,iops_rd_max:l?,iops_wr_max:l?,bps_max_length:l?,bps_rd_max_length:l?,bps_wr_max_length:l?,iops_max_length:l?,iops_rd_max_length:l?,iops_wr_max_length:l?,iops_size:l?,group:s?",
-        .mhandler.cmd_new = qmp_marshal_block_set_io_throttle,
     },
 
 SQMP
@@ -2118,7 +2048,6 @@  EQMP
     {
         .name       = "set_password",
         .args_type  = "protocol:s,password:s,connected:s?",
-        .mhandler.cmd_new = qmp_marshal_set_password,
     },
 
 SQMP
@@ -2144,7 +2073,6 @@  EQMP
     {
         .name       = "expire_password",
         .args_type  = "protocol:s,time:s",
-        .mhandler.cmd_new = qmp_marshal_expire_password,
     },
 
 SQMP
@@ -2169,7 +2097,6 @@  EQMP
     {
         .name       = "add_client",
         .args_type  = "protocol:s,fdname:s,skipauth:b?,tls:b?",
-        .mhandler.cmd_new = qmp_marshal_add_client,
     },
 
 SQMP
@@ -2197,7 +2124,6 @@  EQMP
         .args_type  = "",
         .params     = "",
         .help       = "enable QMP capabilities",
-        .mhandler.cmd_new = qmp_marshal_qmp_capabilities,
     },
 
 SQMP
@@ -2220,7 +2146,6 @@  EQMP
     {
         .name       = "human-monitor-command",
         .args_type  = "command-line:s,cpu-index:i?",
-        .mhandler.cmd_new = qmp_marshal_human_monitor_command,
     },
 
 SQMP
@@ -2299,7 +2224,6 @@  EQMP
     {
         .name       = "query-version",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_version,
     },
 
 SQMP
@@ -2336,7 +2260,6 @@  EQMP
     {
         .name       = "query-commands",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_commands,
     },
 
 SQMP
@@ -2373,7 +2296,6 @@  EQMP
     {
         .name       = "query-events",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_events,
     },
 
 SQMP
@@ -2390,7 +2312,6 @@  EQMP
     {
         .name       = "query-qmp-schema",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_query_qmp_schema,
     },
 
 SQMP
@@ -2435,7 +2356,6 @@  EQMP
     {
         .name       = "query-chardev",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_chardev,
     },
 
 SQMP
@@ -2476,7 +2396,6 @@  EQMP
     {
         .name       = "query-chardev-backends",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_chardev_backends,
     },
 
 SQMP
@@ -2660,7 +2579,6 @@  EQMP
     {
         .name       = "query-block",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_block,
     },
 
 SQMP
@@ -2857,7 +2775,6 @@  EQMP
     {
         .name       = "query-blockstats",
         .args_type  = "query-nodes:b?",
-        .mhandler.cmd_new = qmp_marshal_query_blockstats,
     },
 
 SQMP
@@ -2912,7 +2829,6 @@  EQMP
     {
         .name       = "query-cpus",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_cpus,
     },
 
 SQMP
@@ -2951,7 +2867,6 @@  EQMP
     {
         .name       = "query-iothreads",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_iothreads,
     },
 
 SQMP
@@ -3168,7 +3083,6 @@  EQMP
     {
         .name       = "query-pci",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_pci,
     },
 
 SQMP
@@ -3192,7 +3106,6 @@  EQMP
     {
         .name       = "query-kvm",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_kvm,
     },
 
 SQMP
@@ -3232,7 +3145,6 @@  EQMP
     {
         .name       = "query-status",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_status,
     },
 
 SQMP
@@ -3276,7 +3188,6 @@  EQMP
     {
         .name       = "query-mice",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_mice,
     },
 
 SQMP
@@ -3339,12 +3250,10 @@  EQMP
     {
         .name       = "query-vnc",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_vnc,
     },
     {
         .name       = "query-vnc-servers",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_vnc_servers,
     },
 
 SQMP
@@ -3421,7 +3330,6 @@  EQMP
     {
         .name       = "query-spice",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_spice,
     },
 #endif
 
@@ -3445,7 +3353,6 @@  EQMP
     {
         .name       = "query-name",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_name,
     },
 
 SQMP
@@ -3468,7 +3375,6 @@  EQMP
     {
         .name       = "query-uuid",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_uuid,
     },
 
 SQMP
@@ -3517,7 +3423,6 @@  EQMP
     {
         .name       = "query-command-line-options",
         .args_type  = "option:s?",
-        .mhandler.cmd_new = qmp_marshal_query_command_line_options,
     },
 
 SQMP
@@ -3695,7 +3600,6 @@  EQMP
     {
         .name       = "query-migrate",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_migrate,
     },
 
 SQMP
@@ -3725,7 +3629,6 @@  EQMP
         .name       = "migrate-set-capabilities",
         .args_type  = "capabilities:q",
         .params     = "capability:s,state:b",
-        .mhandler.cmd_new = qmp_marshal_migrate_set_capabilities,
     },
 SQMP
 query-migrate-capabilities
@@ -3762,7 +3665,6 @@  EQMP
     {
         .name       = "query-migrate-capabilities",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_migrate_capabilities,
     },
 
 SQMP
@@ -3792,7 +3694,6 @@  EQMP
         .name       = "migrate-set-parameters",
         .args_type  =
             "compress-level:i?,compress-threads:i?,decompress-threads:i?,cpu-throttle-initial:i?,cpu-throttle-increment:i?",
-        .mhandler.cmd_new = qmp_marshal_migrate_set_parameters,
     },
 SQMP
 query-migrate-parameters
@@ -3829,7 +3730,6 @@  EQMP
     {
         .name       = "query-migrate-parameters",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_migrate_parameters,
     },
 
 SQMP
@@ -3857,88 +3757,73 @@  EQMP
     {
         .name       = "query-balloon",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_balloon,
     },
 
     {
         .name       = "query-block-jobs",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_block_jobs,
     },
 
     {
         .name       = "qom-list",
         .args_type  = "path:s",
-        .mhandler.cmd_new = qmp_marshal_qom_list,
     },
 
     {
         .name       = "qom-set",
 	.args_type  = "path:s,property:s,value:q",
-        .mhandler.cmd_new = qmp_marshal_qom_set,
     },
 
     {
         .name       = "qom-get",
 	.args_type  = "path:s,property:s",
-        .mhandler.cmd_new = qmp_marshal_qom_get,
     },
 
     {
         .name       = "nbd-server-start",
         .args_type  = "addr:q,tls-creds:s?",
-        .mhandler.cmd_new = qmp_marshal_nbd_server_start,
     },
     {
         .name       = "nbd-server-add",
         .args_type  = "device:B,writable:b?",
-        .mhandler.cmd_new = qmp_marshal_nbd_server_add,
     },
     {
         .name       = "nbd-server-stop",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_nbd_server_stop,
     },
 
     {
         .name       = "change-vnc-password",
         .args_type  = "password:s",
-        .mhandler.cmd_new = qmp_marshal_change_vnc_password,
     },
     {
         .name       = "qom-list-types",
         .args_type  = "implements:s?,abstract:b?",
-        .mhandler.cmd_new = qmp_marshal_qom_list_types,
     },
 
     {
         .name       = "device-list-properties",
         .args_type  = "typename:s",
-        .mhandler.cmd_new = qmp_marshal_device_list_properties,
     },
 
     {
         .name       = "query-machines",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_machines,
     },
 
     {
         .name       = "query-cpu-definitions",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_cpu_definitions,
     },
 
     {
         .name       = "query-target",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_target,
     },
 
     {
         .name       = "query-tpm",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_tpm,
     },
 
 SQMP
@@ -3972,7 +3857,6 @@  EQMP
     {
         .name       = "query-tpm-models",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_tpm_models,
     },
 
 SQMP
@@ -3993,7 +3877,6 @@  EQMP
     {
         .name       = "query-tpm-types",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_tpm_types,
     },
 
 SQMP
@@ -4014,7 +3897,6 @@  EQMP
     {
         .name       = "chardev-add",
         .args_type  = "id:s,backend:q",
-        .mhandler.cmd_new = qmp_marshal_chardev_add,
     },
 
 SQMP
@@ -4051,7 +3933,6 @@  EQMP
     {
         .name       = "chardev-remove",
         .args_type  = "id:s",
-        .mhandler.cmd_new = qmp_marshal_chardev_remove,
     },
 
 
@@ -4074,7 +3955,6 @@  EQMP
     {
         .name       = "query-rx-filter",
         .args_type  = "name:s?",
-        .mhandler.cmd_new = qmp_marshal_query_rx_filter,
     },
 
 SQMP
@@ -4140,7 +4020,6 @@  EQMP
     {
         .name       = "blockdev-add",
         .args_type  = "options:q",
-        .mhandler.cmd_new = qmp_marshal_blockdev_add,
     },
 
 SQMP
@@ -4199,7 +4078,6 @@  EQMP
     {
         .name       = "x-blockdev-del",
         .args_type  = "id:s?,node-name:s?",
-        .mhandler.cmd_new = qmp_marshal_x_blockdev_del,
     },
 
 SQMP
@@ -4256,7 +4134,6 @@  EQMP
     {
         .name       = "blockdev-open-tray",
         .args_type  = "device:s,force:b?",
-        .mhandler.cmd_new = qmp_marshal_blockdev_open_tray,
     },
 
 SQMP
@@ -4304,7 +4181,6 @@  EQMP
     {
         .name       = "blockdev-close-tray",
         .args_type  = "device:s",
-        .mhandler.cmd_new = qmp_marshal_blockdev_close_tray,
     },
 
 SQMP
@@ -4339,7 +4215,6 @@  EQMP
     {
         .name       = "x-blockdev-remove-medium",
         .args_type  = "device:s",
-        .mhandler.cmd_new = qmp_marshal_x_blockdev_remove_medium,
     },
 
 SQMP
@@ -4387,7 +4262,6 @@  EQMP
     {
         .name       = "x-blockdev-insert-medium",
         .args_type  = "device:s,node-name:s",
-        .mhandler.cmd_new = qmp_marshal_x_blockdev_insert_medium,
     },
 
 SQMP
@@ -4427,7 +4301,6 @@  EQMP
     {
         .name       = "x-blockdev-change",
         .args_type  = "parent:B,child:B?,node:B?",
-        .mhandler.cmd_new = qmp_marshal_x_blockdev_change,
     },
 
 SQMP
@@ -4480,7 +4353,6 @@  EQMP
     {
         .name       = "query-named-block-nodes",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_named_block_nodes,
     },
 
 SQMP
@@ -4542,7 +4414,6 @@  EQMP
     {
         .name       = "blockdev-change-medium",
         .args_type  = "device:B,filename:F,format:s?,read-only-mode:s?",
-        .mhandler.cmd_new = qmp_marshal_blockdev_change_medium,
     },
 
 SQMP
@@ -4595,7 +4466,6 @@  EQMP
     {
         .name       = "query-memdev",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_memdev,
     },
 
 SQMP
@@ -4633,7 +4503,6 @@  EQMP
     {
         .name       = "query-memory-devices",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_memory_devices,
     },
 
 SQMP
@@ -4660,7 +4529,6 @@  EQMP
     {
         .name       = "query-acpi-ospm-status",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_acpi_ospm_status,
     },
 
 SQMP
@@ -4683,7 +4551,6 @@  EQMP
     {
         .name       = "rtc-reset-reinjection",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_rtc_reset_reinjection,
     },
 #endif
 
@@ -4704,7 +4571,6 @@  EQMP
     {
         .name       = "trace-event-get-state",
         .args_type  = "name:s",
-        .mhandler.cmd_new = qmp_marshal_trace_event_get_state,
     },
 
 SQMP
@@ -4722,7 +4588,6 @@  EQMP
     {
         .name       = "trace-event-set-state",
         .args_type  = "name:s,enable:b,ignore-unavailable:b?",
-        .mhandler.cmd_new = qmp_marshal_trace_event_set_state,
     },
 
 SQMP
@@ -4740,7 +4605,6 @@  EQMP
     {
         .name       = "input-send-event",
         .args_type  = "console:i?,events:q",
-        .mhandler.cmd_new = qmp_marshal_input_send_event,
     },
 
 SQMP
@@ -4806,7 +4670,6 @@  EQMP
     {
         .name       = "block-set-write-threshold",
         .args_type  = "node-name:s,write-threshold:l",
-        .mhandler.cmd_new = qmp_marshal_block_set_write_threshold,
     },
 
 SQMP
@@ -4834,7 +4697,6 @@  EQMP
     {
         .name       = "query-rocker",
         .args_type  = "name:s",
-        .mhandler.cmd_new = qmp_marshal_query_rocker,
     },
 
 SQMP
@@ -4855,7 +4717,6 @@  EQMP
     {
         .name       = "query-rocker-ports",
         .args_type  = "name:s",
-        .mhandler.cmd_new = qmp_marshal_query_rocker_ports,
     },
 
 SQMP
@@ -4880,7 +4741,6 @@  EQMP
     {
         .name       = "query-rocker-of-dpa-flows",
         .args_type  = "name:s,tbl-id:i?",
-        .mhandler.cmd_new = qmp_marshal_query_rocker_of_dpa_flows,
     },
 
 SQMP
@@ -4909,7 +4769,6 @@  EQMP
     {
         .name       = "query-rocker-of-dpa-groups",
         .args_type  = "name:s,type:i?",
-        .mhandler.cmd_new = qmp_marshal_query_rocker_of_dpa_groups,
     },
 
 SQMP
@@ -4940,7 +4799,6 @@  EQMP
     {
         .name       = "query-gic-capabilities",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_gic_capabilities,
     },
 #endif
 
@@ -4964,7 +4822,6 @@  EQMP
     {
         .name       = "query-hotpluggable-cpus",
         .args_type  = "",
-        .mhandler.cmd_new = qmp_marshal_query_hotpluggable_cpus,
     },
 
 SQMP
diff --git a/vl.c b/vl.c
index 74bbd30..c6f0544 100644
--- a/vl.c
+++ b/vl.c
@@ -2971,6 +2971,7 @@  int main(int argc, char **argv, char **envp)
     qemu_init_exec_dir(argv[0]);
 
     module_call_init(MODULE_INIT_QOM);
+    module_call_init(MODULE_INIT_QAPI);
 
     qemu_add_opts(&qemu_drive_opts);
     qemu_add_drive_opts(&qemu_legacy_drive_opts);