From 05875687806b71ae980ca59a46777b742b20ac06 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 3 Mar 2017 13:32:24 +0100 Subject: qmp: Dumb down how we run QMP command registration The way we get QMP commands registered is high tech: * qapi-commands.py generates qmp_init_marshal() that does the actual work * it also generates the magic to register it as a MODULE_INIT_QAPI function, so it runs when someone calls module_call_init(MODULE_INIT_QAPI) * main() calls module_call_init() QEMU needs to register a few non-qapified commands. Same high tech works: monitor.c has its own qmp_init_marshal() along with the magic to make it run in module_call_init(MODULE_INIT_QAPI). QEMU also needs to unregister commands that are not wanted in this build's configuration (commit 5032a16). Simple enough: qmp_unregister_commands_hack(). The difficulty is to make it run after the generated qmp_init_marshal(). We can't simply run it in monitor.c's qmp_init_marshal(), because the order in which the registered functions run is indeterminate. So qmp_init_marshal() registers qmp_unregister_commands_hack() separately. Since registering *appends* to the list of registered functions, this will make it run after all the functions that have been registered already. I suspect it takes a long and expensive computer science education to not find this silly. Dumb it down as follows: * Drop MODULE_INIT_QAPI entirely * Give the generated qmp_init_marshal() external linkage. * Call it instead of module_call_init(MODULE_INIT_QAPI) * Except in QEMU proper, call new monitor_init_qmp_commands() that in turn calls the generated qmp_init_marshal(), registers the additional commands and unregisters the unwanted ones. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1488544368-30622-5-git-send-email-armbru@redhat.com> --- scripts/qapi-commands.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'scripts/qapi-commands.py') diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py index 09e8467d90..a75946f47e 100644 --- a/scripts/qapi-commands.py +++ b/scripts/qapi-commands.py @@ -208,14 +208,12 @@ def gen_register_command(name, success_response): def gen_registry(registry): ret = mcgen(''' -static void qmp_init_marshal(void) +void qmp_init_marshal(void) { ''') ret += registry ret += mcgen(''' } - -qapi_init(qmp_init_marshal); ''') return ret @@ -308,6 +306,7 @@ fdecl.write(mcgen(''' #include "qapi/qmp/qdict.h" #include "qapi/error.h" +void qmp_init_marshal(void); ''', prefix=prefix)) -- cgit 1.4.1 From 1527badb954f2d8c17b86e2a258812def5ea3dcc Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 3 Mar 2017 13:32:25 +0100 Subject: qapi: Support multiple command registries per program The command registry encapsulates a single command list. Give the functions using it a parameter instead. Define suitable command lists in monitor, guest agent and test-qmp-commands. Signed-off-by: Markus Armbruster Message-Id: <1488544368-30622-6-git-send-email-armbru@redhat.com> [Debugging turds buried] Reviewed-by: Eric Blake --- include/qapi/qmp/dispatch.h | 22 ++++++++++++++-------- monitor.c | 31 +++++++++++++++++-------------- qapi/qmp-dispatch.c | 9 +++++---- qapi/qmp-registry.c | 37 ++++++++++++++++++------------------- qga/commands.c | 2 +- qga/guest-agent-core.h | 2 ++ qga/main.c | 19 ++++++++++--------- scripts/qapi-commands.py | 16 ++++++++++------ tests/test-qmp-commands.c | 12 +++++++----- 9 files changed, 84 insertions(+), 66 deletions(-) (limited to 'scripts/qapi-commands.py') diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index 57651ea955..20578dcd48 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -34,18 +34,24 @@ typedef struct QmpCommand bool enabled; } QmpCommand; -void qmp_register_command(const char *name, QmpCommandFunc *fn, - QmpCommandOptions options); -void qmp_unregister_command(const char *name); -QmpCommand *qmp_find_command(const char *name); -QObject *qmp_dispatch(QObject *request); -void qmp_disable_command(const char *name); -void qmp_enable_command(const char *name); +typedef QTAILQ_HEAD(QmpCommandList, QmpCommand) QmpCommandList; + +void qmp_register_command(QmpCommandList *cmds, const char *name, + QmpCommandFunc *fn, QmpCommandOptions options); +void qmp_unregister_command(QmpCommandList *cmds, const char *name); +QmpCommand *qmp_find_command(QmpCommandList *cmds, const char *name); +QObject *qmp_dispatch(QmpCommandList *cmds, QObject *request); +void qmp_disable_command(QmpCommandList *cmds, const char *name); +void qmp_enable_command(QmpCommandList *cmds, const char *name); + bool qmp_command_is_enabled(const QmpCommand *cmd); const char *qmp_command_name(const QmpCommand *cmd); bool qmp_has_success_response(const QmpCommand *cmd); QObject *qmp_build_error_object(Error *err); + typedef void (*qmp_cmd_callback_fn)(QmpCommand *cmd, void *opaque); -void qmp_for_each_command(qmp_cmd_callback_fn fn, void *opaque); + +void qmp_for_each_command(QmpCommandList *cmds, qmp_cmd_callback_fn fn, + void *opaque); #endif diff --git a/monitor.c b/monitor.c index 53f5f5a378..c7f7602466 100644 --- a/monitor.c +++ b/monitor.c @@ -221,6 +221,8 @@ static int mon_refcount; static mon_cmd_t mon_cmds[]; static mon_cmd_t info_cmds[]; +QmpCommandList qmp_commands; + Monitor *cur_mon; static QEMUClockType event_clock_type = QEMU_CLOCK_REALTIME; @@ -919,7 +921,7 @@ CommandInfoList *qmp_query_commands(Error **errp) { CommandInfoList *list = NULL; - qmp_for_each_command(query_commands_cb, &list); + qmp_for_each_command(&qmp_commands, query_commands_cb, &list); return list; } @@ -973,39 +975,40 @@ static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data, static void qmp_unregister_commands_hack(void) { #ifndef CONFIG_SPICE - qmp_unregister_command("query-spice"); + qmp_unregister_command(&qmp_commands, "query-spice"); #endif #ifndef TARGET_I386 - qmp_unregister_command("rtc-reset-reinjection"); + qmp_unregister_command(&qmp_commands, "rtc-reset-reinjection"); #endif #ifndef TARGET_S390X - qmp_unregister_command("dump-skeys"); + qmp_unregister_command(&qmp_commands, "dump-skeys"); #endif #ifndef TARGET_ARM - qmp_unregister_command("query-gic-capabilities"); + qmp_unregister_command(&qmp_commands, "query-gic-capabilities"); #endif #if !defined(TARGET_S390X) && !defined(TARGET_I386) - qmp_unregister_command("query-cpu-model-expansion"); + qmp_unregister_command(&qmp_commands, "query-cpu-model-expansion"); #endif #if !defined(TARGET_S390X) - qmp_unregister_command("query-cpu-model-baseline"); - qmp_unregister_command("query-cpu-model-comparison"); + qmp_unregister_command(&qmp_commands, "query-cpu-model-baseline"); + qmp_unregister_command(&qmp_commands, "query-cpu-model-comparison"); #endif #if !defined(TARGET_PPC) && !defined(TARGET_ARM) && !defined(TARGET_I386) \ && !defined(TARGET_S390X) - qmp_unregister_command("query-cpu-definitions"); + qmp_unregister_command(&qmp_commands, "query-cpu-definitions"); #endif } void monitor_init_qmp_commands(void) { - qmp_init_marshal(); + qmp_init_marshal(&qmp_commands); - qmp_register_command("query-qmp-schema", qmp_query_qmp_schema, + qmp_register_command(&qmp_commands, "query-qmp-schema", + qmp_query_qmp_schema, QCO_NO_OPTIONS); - qmp_register_command("device_add", qmp_device_add, + qmp_register_command(&qmp_commands, "device_add", qmp_device_add, QCO_NO_OPTIONS); - qmp_register_command("netdev_add", qmp_netdev_add, + qmp_register_command(&qmp_commands, "netdev_add", qmp_netdev_add, QCO_NO_OPTIONS); qmp_unregister_commands_hack(); @@ -3787,7 +3790,7 @@ static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens) goto err_out; } - rsp = qmp_dispatch(req); + rsp = qmp_dispatch(&qmp_commands, req); err_out: if (err) { diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 621922ffa2..72827a30ba 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -67,7 +67,8 @@ static QDict *qmp_dispatch_check_obj(const QObject *request, Error **errp) return dict; } -static QObject *do_qmp_dispatch(QObject *request, Error **errp) +static QObject *do_qmp_dispatch(QmpCommandList *cmds, QObject *request, + Error **errp) { Error *local_err = NULL; const char *command; @@ -81,7 +82,7 @@ static QObject *do_qmp_dispatch(QObject *request, Error **errp) } command = qdict_get_str(dict, "execute"); - cmd = qmp_find_command(command); + cmd = qmp_find_command(cmds, command); if (cmd == NULL) { error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND, "The command %s has not been found", command); @@ -121,13 +122,13 @@ QObject *qmp_build_error_object(Error *err) error_get_pretty(err)); } -QObject *qmp_dispatch(QObject *request) +QObject *qmp_dispatch(QmpCommandList *cmds, QObject *request) { Error *err = NULL; QObject *ret; QDict *rsp; - ret = do_qmp_dispatch(request, &err); + ret = do_qmp_dispatch(cmds, request, &err); rsp = qdict_new(); if (err) { diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c index e8053686f3..5af484cd9a 100644 --- a/qapi/qmp-registry.c +++ b/qapi/qmp-registry.c @@ -15,11 +15,8 @@ #include "qemu/osdep.h" #include "qapi/qmp/dispatch.h" -static QTAILQ_HEAD(QmpCommandList, QmpCommand) qmp_commands = - QTAILQ_HEAD_INITIALIZER(qmp_commands); - -void qmp_register_command(const char *name, QmpCommandFunc *fn, - QmpCommandOptions options) +void qmp_register_command(QmpCommandList *cmds, const char *name, + QmpCommandFunc *fn, QmpCommandOptions options) { QmpCommand *cmd = g_malloc0(sizeof(*cmd)); @@ -27,22 +24,22 @@ void qmp_register_command(const char *name, QmpCommandFunc *fn, cmd->fn = fn; cmd->enabled = true; cmd->options = options; - QTAILQ_INSERT_TAIL(&qmp_commands, cmd, node); + QTAILQ_INSERT_TAIL(cmds, cmd, node); } -void qmp_unregister_command(const char *name) +void qmp_unregister_command(QmpCommandList *cmds, const char *name) { - QmpCommand *cmd = qmp_find_command(name); + QmpCommand *cmd = qmp_find_command(cmds, name); - QTAILQ_REMOVE(&qmp_commands, cmd, node); + QTAILQ_REMOVE(cmds, cmd, node); g_free(cmd); } -QmpCommand *qmp_find_command(const char *name) +QmpCommand *qmp_find_command(QmpCommandList *cmds, const char *name) { QmpCommand *cmd; - QTAILQ_FOREACH(cmd, &qmp_commands, node) { + QTAILQ_FOREACH(cmd, cmds, node) { if (strcmp(cmd->name, name) == 0) { return cmd; } @@ -50,11 +47,12 @@ QmpCommand *qmp_find_command(const char *name) return NULL; } -static void qmp_toggle_command(const char *name, bool enabled) +static void qmp_toggle_command(QmpCommandList *cmds, const char *name, + bool enabled) { QmpCommand *cmd; - QTAILQ_FOREACH(cmd, &qmp_commands, node) { + QTAILQ_FOREACH(cmd, cmds, node) { if (strcmp(cmd->name, name) == 0) { cmd->enabled = enabled; return; @@ -62,14 +60,14 @@ static void qmp_toggle_command(const char *name, bool enabled) } } -void qmp_disable_command(const char *name) +void qmp_disable_command(QmpCommandList *cmds, const char *name) { - qmp_toggle_command(name, false); + qmp_toggle_command(cmds, name, false); } -void qmp_enable_command(const char *name) +void qmp_enable_command(QmpCommandList *cmds, const char *name) { - qmp_toggle_command(name, true); + qmp_toggle_command(cmds, name, true); } bool qmp_command_is_enabled(const QmpCommand *cmd) @@ -87,11 +85,12 @@ bool qmp_has_success_response(const QmpCommand *cmd) return !(cmd->options & QCO_NO_SUCCESS_RESP); } -void qmp_for_each_command(qmp_cmd_callback_fn fn, void *opaque) +void qmp_for_each_command(QmpCommandList *cmds, qmp_cmd_callback_fn fn, + void *opaque) { QmpCommand *cmd; - QTAILQ_FOREACH(cmd, &qmp_commands, node) { + QTAILQ_FOREACH(cmd, cmds, node) { fn(cmd, opaque); } } diff --git a/qga/commands.c b/qga/commands.c index edd3e830e6..4d92946820 100644 --- a/qga/commands.c +++ b/qga/commands.c @@ -75,7 +75,7 @@ struct GuestAgentInfo *qmp_guest_info(Error **errp) GuestAgentInfo *info = g_new0(GuestAgentInfo, 1); info->version = g_strdup(QEMU_VERSION); - qmp_for_each_command(qmp_command_info, info); + qmp_for_each_command(&ga_commands, qmp_command_info, info); return info; } diff --git a/qga/guest-agent-core.h b/qga/guest-agent-core.h index 63e9d398ae..3e8a4acff2 100644 --- a/qga/guest-agent-core.h +++ b/qga/guest-agent-core.h @@ -18,7 +18,9 @@ typedef struct GAState GAState; typedef struct GACommandState GACommandState; + extern GAState *ga_state; +extern QmpCommandList ga_commands; GList *ga_command_blacklist_init(GList *blacklist); void ga_command_state_init(GAState *s, GACommandState *cs); diff --git a/qga/main.c b/qga/main.c index 6f8c614420..9435bc74b8 100644 --- a/qga/main.c +++ b/qga/main.c @@ -92,6 +92,7 @@ struct GAState { }; struct GAState *ga_state; +QmpCommandList ga_commands; /* commands that are safe to issue while filesystems are frozen */ static const char *ga_freeze_whitelist[] = { @@ -370,7 +371,7 @@ static void ga_disable_non_whitelisted(QmpCommand *cmd, void *opaque) } if (!whitelisted) { g_debug("disabling command: %s", name); - qmp_disable_command(name); + qmp_disable_command(&ga_commands, name); } } @@ -383,7 +384,7 @@ static void ga_enable_non_blacklisted(QmpCommand *cmd, void *opaque) if (g_list_find_custom(blacklist, name, ga_strcmp) == NULL && !qmp_command_is_enabled(cmd)) { g_debug("enabling command: %s", name); - qmp_enable_command(name); + qmp_enable_command(&ga_commands, name); } } @@ -420,7 +421,7 @@ void ga_set_frozen(GAState *s) return; } /* disable all non-whitelisted (for frozen state) commands */ - qmp_for_each_command(ga_disable_non_whitelisted, NULL); + qmp_for_each_command(&ga_commands, ga_disable_non_whitelisted, NULL); g_warning("disabling logging due to filesystem freeze"); ga_disable_logging(s); s->frozen = true; @@ -456,7 +457,7 @@ void ga_unset_frozen(GAState *s) } /* enable all disabled, non-blacklisted commands */ - qmp_for_each_command(ga_enable_non_blacklisted, s->blacklist); + qmp_for_each_command(&ga_commands, ga_enable_non_blacklisted, s->blacklist); s->frozen = false; if (!ga_delete_file(s->state_filepath_isfrozen)) { g_warning("unable to delete %s, fsfreeze may not function properly", @@ -555,7 +556,7 @@ static void process_command(GAState *s, QDict *req) g_assert(req); g_debug("processing command"); - rsp = qmp_dispatch(QOBJECT(req)); + rsp = qmp_dispatch(&ga_commands, QOBJECT(req)); if (rsp) { ret = send_response(s, rsp); if (ret < 0) { @@ -1119,7 +1120,7 @@ static void config_parse(GAConfig *config, int argc, char **argv) break; case 'b': { if (is_help_option(optarg)) { - qmp_for_each_command(ga_print_cmd, NULL); + qmp_for_each_command(&ga_commands, ga_print_cmd, NULL); exit(EXIT_SUCCESS); } config->blacklist = g_list_concat(config->blacklist, @@ -1247,7 +1248,7 @@ static int run_agent(GAState *s, GAConfig *config) s->deferred_options.log_filepath = config->log_filepath; } ga_disable_logging(s); - qmp_for_each_command(ga_disable_non_whitelisted, NULL); + qmp_for_each_command(&ga_commands, ga_disable_non_whitelisted, NULL); } else { if (config->daemonize) { become_daemon(config->pid_filepath); @@ -1277,7 +1278,7 @@ static int run_agent(GAState *s, GAConfig *config) s->blacklist = config->blacklist; do { g_debug("disabling command: %s", (char *)l->data); - qmp_disable_command(l->data); + qmp_disable_command(&ga_commands, l->data); l = g_list_next(l); } while (l); } @@ -1321,7 +1322,7 @@ int main(int argc, char **argv) config->log_level = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL; - qmp_init_marshal(); + qga_qmp_init_marshal(&ga_commands); init_dfl_pathnames(); config_load(config); diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py index a75946f47e..2b062ad1fd 100644 --- a/scripts/qapi-commands.py +++ b/scripts/qapi-commands.py @@ -198,7 +198,8 @@ def gen_register_command(name, success_response): options = 'QCO_NO_SUCCESS_RESP' ret = mcgen(''' - qmp_register_command("%(name)s", qmp_marshal_%(c_name)s, %(opts)s); + qmp_register_command(cmds, "%(name)s", + qmp_marshal_%(c_name)s, %(opts)s); ''', name=name, c_name=c_name(name), opts=options) @@ -208,9 +209,12 @@ def gen_register_command(name, success_response): def gen_registry(registry): ret = mcgen(''' -void qmp_init_marshal(void) +void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds) { -''') + QTAILQ_INIT(cmds); + +''', + c_prefix=c_name(prefix, protect=False)) ret += registry ret += mcgen(''' } @@ -289,7 +293,6 @@ fdef.write(mcgen(''' #include "qemu-common.h" #include "qemu/module.h" #include "qapi/qmp/types.h" -#include "qapi/qmp/dispatch.h" #include "qapi/visitor.h" #include "qapi/qobject-output-visitor.h" #include "qapi/qobject-input-visitor.h" @@ -304,11 +307,12 @@ fdef.write(mcgen(''' fdecl.write(mcgen(''' #include "%(prefix)sqapi-types.h" #include "qapi/qmp/qdict.h" +#include "qapi/qmp/dispatch.h" #include "qapi/error.h" -void qmp_init_marshal(void); +void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds); ''', - prefix=prefix)) + prefix=prefix, c_prefix=c_name(prefix, protect=False))) schema = QAPISchema(input_file) gen = QAPISchemaGenCommandVisitor() diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c index c4e20d1bb3..1cf413bc39 100644 --- a/tests/test-qmp-commands.c +++ b/tests/test-qmp-commands.c @@ -8,6 +8,8 @@ #include "tests/test-qapi-types.h" #include "tests/test-qapi-visit.h" +static QmpCommandList qmp_commands; + void qmp_user_def_cmd(Error **errp) { } @@ -94,7 +96,7 @@ static void test_dispatch_cmd(void) qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd"))); - resp = qmp_dispatch(QOBJECT(req)); + resp = qmp_dispatch(&qmp_commands, QOBJECT(req)); assert(resp != NULL); assert(!qdict_haskey(qobject_to_qdict(resp), "error")); @@ -111,7 +113,7 @@ static void test_dispatch_cmd_failure(void) qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2"))); - resp = qmp_dispatch(QOBJECT(req)); + resp = qmp_dispatch(&qmp_commands, QOBJECT(req)); assert(resp != NULL); assert(qdict_haskey(qobject_to_qdict(resp), "error")); @@ -125,7 +127,7 @@ static void test_dispatch_cmd_failure(void) qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd"))); - resp = qmp_dispatch(QOBJECT(req)); + resp = qmp_dispatch(&qmp_commands, QOBJECT(req)); assert(resp != NULL); assert(qdict_haskey(qobject_to_qdict(resp), "error")); @@ -139,7 +141,7 @@ static QObject *test_qmp_dispatch(QDict *req) QDict *resp; QObject *ret; - resp_obj = qmp_dispatch(QOBJECT(req)); + resp_obj = qmp_dispatch(&qmp_commands, QOBJECT(req)); assert(resp_obj); resp = qobject_to_qdict(resp_obj); assert(resp && !qdict_haskey(resp, "error")); @@ -273,7 +275,7 @@ int main(int argc, char **argv) g_test_add_func("/0.15/dealloc_types", test_dealloc_types); g_test_add_func("/0.15/dealloc_partial", test_dealloc_partial); - qmp_init_marshal(); + test_qmp_init_marshal(&qmp_commands); g_test_run(); return 0; -- cgit 1.4.1 From 048abb7b20c9f822ad9d4b730bade73b3311a47a Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 3 Mar 2017 13:32:39 +0100 Subject: qapi: Drop unused non-strict qobject input visitor The split between tests/test-qobject-input-visitor.c and tests/test-qobject-input-strict.c now makes less sense than ever. The next commit will take care of that. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <1488544368-30622-20-git-send-email-armbru@redhat.com> --- block/nbd.c | 2 +- block/nfs.c | 2 +- block/ssh.c | 2 +- docs/qapi-code-gen.txt | 2 +- include/qapi/qobject-input-visitor.h | 5 +---- qapi/qobject-input-visitor.c | 30 +++++++++++------------------- qmp.c | 2 +- qom/qom-qobject.c | 2 +- scripts/qapi-commands.py | 2 +- target/s390x/cpu_models.c | 2 +- tests/check-qnull.c | 2 +- tests/qmp-test.c | 2 +- tests/test-qmp-commands.c | 2 +- tests/test-qobject-input-strict.c | 2 +- tests/test-qobject-input-visitor.c | 2 +- tests/test-visitor-serialization.c | 2 +- 16 files changed, 26 insertions(+), 37 deletions(-) (limited to 'scripts/qapi-commands.py') diff --git a/block/nbd.c b/block/nbd.c index a7f9108fe5..f478f80b4a 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -278,7 +278,7 @@ static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options, Error **errp) goto done; } - iv = qobject_input_visitor_new(crumpled_addr, true); + iv = qobject_input_visitor_new(crumpled_addr); visit_type_SocketAddress(iv, NULL, &saddr, &local_err); if (local_err) { error_propagate(errp, local_err); diff --git a/block/nfs.c b/block/nfs.c index 890d5d4aff..3f43f6e26a 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -474,7 +474,7 @@ static NFSServer *nfs_config(QDict *options, Error **errp) goto out; } - iv = qobject_input_visitor_new(crumpled_addr, true); + iv = qobject_input_visitor_new(crumpled_addr); visit_type_NFSServer(iv, NULL, &server, &local_error); if (local_error) { error_propagate(errp, local_error); diff --git a/block/ssh.c b/block/ssh.c index 835932e6a4..278e66faa6 100644 --- a/block/ssh.c +++ b/block/ssh.c @@ -601,7 +601,7 @@ static InetSocketAddress *ssh_config(QDict *options, Error **errp) goto out; } - iv = qobject_input_visitor_new(crumpled_addr, true); + iv = qobject_input_visitor_new(crumpled_addr); visit_type_InetSocketAddress(iv, NULL, &inet, &local_error); if (local_error) { error_propagate(errp, local_error); diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt index 7eb7be12ab..6746c1052c 100644 --- a/docs/qapi-code-gen.txt +++ b/docs/qapi-code-gen.txt @@ -1138,7 +1138,7 @@ Example: Visitor *v; UserDefOneList *arg1 = NULL; - v = qobject_input_visitor_new(QOBJECT(args), true); + v = qobject_input_visitor_new(QOBJECT(args)); visit_start_struct(v, NULL, NULL, 0, &err); if (err) { goto out; diff --git a/include/qapi/qobject-input-visitor.h b/include/qapi/qobject-input-visitor.h index cde328da9f..21db9c4b4a 100644 --- a/include/qapi/qobject-input-visitor.h +++ b/include/qapi/qobject-input-visitor.h @@ -21,10 +21,7 @@ typedef struct QObjectInputVisitor QObjectInputVisitor; /* * Return a new input visitor that converts a QObject to a QAPI object. - * - * Set @strict to reject a parse that doesn't consume all keys of a - * dictionary; otherwise excess input is ignored. */ -Visitor *qobject_input_visitor_new(QObject *obj, bool strict); +Visitor *qobject_input_visitor_new(QObject *obj); #endif diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c index 8015a986b0..eafcdf4625 100644 --- a/qapi/qobject-input-visitor.c +++ b/qapi/qobject-input-visitor.c @@ -43,9 +43,6 @@ struct QObjectInputVisitor { * QDict or QList). */ QSLIST_HEAD(, StackObject) stack; - /* True to reject parse in visit_end_struct() if unvisited keys remain. */ - bool strict; - GString *errname; /* Accumulator for full_name() */ }; @@ -157,11 +154,12 @@ static const QListEntry *qobject_input_push(QObjectInputVisitor *qiv, tos->obj = obj; tos->qapi = qapi; - if (qiv->strict && qobject_type(obj) == QTYPE_QDICT) { + if (qobject_type(obj) == QTYPE_QDICT) { h = g_hash_table_new(g_str_hash, g_str_equal); qdict_iter(qobject_to_qdict(obj), qdict_add_key, h); tos->h = h; - } else if (qobject_type(obj) == QTYPE_QLIST) { + } else { + assert(qobject_type(obj) == QTYPE_QLIST); tos->entry = qlist_first(qobject_to_qlist(obj)); tos->index = -1; } @@ -175,20 +173,15 @@ static void qobject_input_check_struct(Visitor *v, Error **errp) { QObjectInputVisitor *qiv = to_qiv(v); StackObject *tos = QSLIST_FIRST(&qiv->stack); + GHashTableIter iter; + const char *key; assert(tos && !tos->entry); - if (qiv->strict) { - GHashTable *const top_ht = tos->h; - if (top_ht) { - GHashTableIter iter; - const char *key; - - g_hash_table_iter_init(&iter, top_ht); - if (g_hash_table_iter_next(&iter, (void **)&key, NULL)) { - error_setg(errp, "Parameter '%s' is unexpected", - full_name(qiv, key)); - } - } + + g_hash_table_iter_init(&iter, tos->h); + if (g_hash_table_iter_next(&iter, (void **)&key, NULL)) { + error_setg(errp, "Parameter '%s' is unexpected", + full_name(qiv, key)); } } @@ -465,7 +458,7 @@ static void qobject_input_free(Visitor *v) g_free(qiv); } -Visitor *qobject_input_visitor_new(QObject *obj, bool strict) +Visitor *qobject_input_visitor_new(QObject *obj) { QObjectInputVisitor *v; @@ -489,7 +482,6 @@ Visitor *qobject_input_visitor_new(QObject *obj, bool strict) v->visitor.type_null = qobject_input_type_null; v->visitor.optional = qobject_input_optional; v->visitor.free = qobject_input_free; - v->strict = strict; v->root = obj; qobject_incref(obj); diff --git a/qmp.c b/qmp.c index dfaabac1a6..fa82b598c6 100644 --- a/qmp.c +++ b/qmp.c @@ -675,7 +675,7 @@ void qmp_object_add(const char *type, const char *id, pdict = qdict_new(); } - v = qobject_input_visitor_new(QOBJECT(pdict), true); + v = qobject_input_visitor_new(QOBJECT(pdict)); obj = user_creatable_add_type(type, id, pdict, v, errp); visit_free(v); if (obj) { diff --git a/qom/qom-qobject.c b/qom/qom-qobject.c index bbdedda74a..4aec20d73c 100644 --- a/qom/qom-qobject.c +++ b/qom/qom-qobject.c @@ -23,7 +23,7 @@ void object_property_set_qobject(Object *obj, QObject *value, { Visitor *v; - v = qobject_input_visitor_new(value, true); + v = qobject_input_visitor_new(value); object_property_set(obj, v, name, errp); visit_free(v); } diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py index 2b062ad1fd..0c05449cb6 100644 --- a/scripts/qapi-commands.py +++ b/scripts/qapi-commands.py @@ -130,7 +130,7 @@ def gen_marshal(name, arg_type, boxed, ret_type): push_indent() ret += mcgen(''' - v = qobject_input_visitor_new(QOBJECT(args), true); + v = qobject_input_visitor_new(QOBJECT(args)); visit_start_struct(v, NULL, NULL, 0, &err); if (err) { goto out; diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c index 2a894eec65..4ea3a2de80 100644 --- a/target/s390x/cpu_models.c +++ b/target/s390x/cpu_models.c @@ -346,7 +346,7 @@ static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info, } if (qdict) { - visitor = qobject_input_visitor_new(info->props, true); + visitor = qobject_input_visitor_new(info->props); visit_start_struct(visitor, NULL, NULL, 0, errp); if (*errp) { object_unref(obj); diff --git a/tests/check-qnull.c b/tests/check-qnull.c index b50bb8a81a..8dd1c9686f 100644 --- a/tests/check-qnull.c +++ b/tests/check-qnull.c @@ -47,7 +47,7 @@ static void qnull_visit_test(void) g_assert(qnull_.refcnt == 1); obj = qnull(); - v = qobject_input_visitor_new(obj, true); + v = qobject_input_visitor_new(obj); qobject_decref(obj); visit_type_null(v, NULL, &error_abort); visit_free(v); diff --git a/tests/qmp-test.c b/tests/qmp-test.c index 405e49ec34..5d0260b2be 100644 --- a/tests/qmp-test.c +++ b/tests/qmp-test.c @@ -34,7 +34,7 @@ static void test_version(QObject *version) VersionInfo *vinfo; g_assert(version); - v = qobject_input_visitor_new(version, true); + v = qobject_input_visitor_new(version); visit_type_VersionInfo(v, "version", &vinfo, &error_abort); qapi_free_VersionInfo(vinfo); visit_free(v); diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c index 1cf413bc39..0f81a98be2 100644 --- a/tests/test-qmp-commands.c +++ b/tests/test-qmp-commands.c @@ -246,7 +246,7 @@ static void test_dealloc_partial(void) ud2_dict = qdict_new(); qdict_put_obj(ud2_dict, "string0", QOBJECT(qstring_from_str(text))); - v = qobject_input_visitor_new(QOBJECT(ud2_dict), true); + v = qobject_input_visitor_new(QOBJECT(ud2_dict)); visit_type_UserDefTwo(v, NULL, &ud2, &err); visit_free(v); QDECREF(ud2_dict); diff --git a/tests/test-qobject-input-strict.c b/tests/test-qobject-input-strict.c index 4087ea3dd3..7d26113013 100644 --- a/tests/test-qobject-input-strict.c +++ b/tests/test-qobject-input-strict.c @@ -53,7 +53,7 @@ static Visitor *validate_test_init_internal(TestInputVisitorData *data, data->obj = qobject_from_jsonv(json_string, ap); g_assert(data->obj); - data->qiv = qobject_input_visitor_new(data->obj, true); + data->qiv = qobject_input_visitor_new(data->obj); g_assert(data->qiv); return data->qiv; } diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c index 125e34c101..658fa2c24d 100644 --- a/tests/test-qobject-input-visitor.c +++ b/tests/test-qobject-input-visitor.c @@ -49,7 +49,7 @@ static Visitor *visitor_input_test_init_internal(TestInputVisitorData *data, data->obj = qobject_from_jsonv(json_string, ap); g_assert(data->obj); - data->qiv = qobject_input_visitor_new(data->obj, true); + data->qiv = qobject_input_visitor_new(data->obj); g_assert(data->qiv); return data->qiv; } diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c index 66b2b1c564..c7e64f022c 100644 --- a/tests/test-visitor-serialization.c +++ b/tests/test-visitor-serialization.c @@ -1040,7 +1040,7 @@ static void qmp_deserialize(void **native_out, void *datap, obj = qobject_from_json(qstring_get_str(output_json)); QDECREF(output_json); - d->qiv = qobject_input_visitor_new(obj, true); + d->qiv = qobject_input_visitor_new(obj); qobject_decref(obj_orig); qobject_decref(obj); visit(d->qiv, native_out, errp); -- cgit 1.4.1