>From 6839ead5ac4a77ac82aee2fe1365e72e276aa89d Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Fri, 13 Jul 2012 23:49:09 +0200 Subject: [PATCH] support NetLegacy::id and clean up QemuOpts::id usage NetLegacy::id is actually allowed and takes precedence over NetLegacy::name. Factor opts_visitor_insert() out of opts_start_struct() and call it separately for opts_root->id if there's any. Signed-off-by: Laszlo Ersek --- net.c | 2 +- qapi-schema.json | 5 ++++- qapi/opts-visitor.c | 49 +++++++++++++++++++++++++++++++++++++------------ 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/net.c b/net.c index 1612f64..dbca77b 100644 --- a/net.c +++ b/net.c @@ -869,7 +869,7 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp) u.net = object; opts = u.net->opts; /* missing optional values have been initialized to "all bits zero" */ - name = u.net->name; + name = u.net->has_id ? u.net->id : u.net->name; } if (net_client_init_fun[opts->kind]) { diff --git a/qapi-schema.json b/qapi-schema.json index ed345ee..cc48127 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2116,7 +2116,9 @@ # # @vlan: #optional vlan number # -# @name: #optional identifier for monitor commands +# @id: #optional identifier for monitor commands +# +# @name: #optional identifier for monitor commands, ignored if @id is present # # @traits: device type specific properties (legacy) # @@ -2125,6 +2127,7 @@ { 'type': 'NetLegacy', 'data': { '*vlan': 'int32', + '*id': 'str', '*name': 'str', 'opts': 'NetClientOptions' } } diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c index 9187c86..a261cf3 100644 --- a/qapi/opts-visitor.c +++ b/qapi/opts-visitor.c @@ -35,6 +35,12 @@ struct OptsVisitor * schema, with a single mandatory scalar member. */ GQueue *repeated_opts; bool repeated_opts_first; + + /* If "opts_root->id" is set, reinstantiate it as a fake QemuOpt for + * uniformity. Only its "name" and "str" fields are set. "fake_id_opt" does + * not survive or escape the OptsVisitor object. + */ + QemuOpt *fake_id_opt; }; @@ -46,6 +52,27 @@ destroy_list(gpointer list) static void +opts_visitor_insert(GHashTable *unprocessed_opts, const QemuOpt *opt) +{ + GQueue *list; + + list = g_hash_table_lookup(unprocessed_opts, opt->name); + if (list == NULL) { + list = g_queue_new(); + + /* GHashTable will never try to free the keys -- we supply NULL as + * "key_destroy_func" in opts_start_struct(). Thus cast away key + * const-ness in order to suppress gcc's warning. + */ + g_hash_table_insert(unprocessed_opts, (gpointer)opt->name, list); + } + + /* Similarly, destroy_list() doesn't call g_queue_free_full(). */ + g_queue_push_tail(list, (gpointer)opt); +} + + +static void opts_start_struct(Visitor *v, void **obj, const char *kind, const char *name, size_t size, Error **errp) { @@ -60,21 +87,18 @@ opts_start_struct(Visitor *v, void **obj, const char *kind, ov->unprocessed_opts = g_hash_table_new_full(&g_str_hash, &g_str_equal, NULL, &destroy_list); QTAILQ_FOREACH(opt, &ov->opts_root->head, next) { - GQueue *list; + /* ensured by qemu-option.c::opts_do_parse() */ + assert(strcmp(opt->name, "id") != 0); - list = g_hash_table_lookup(ov->unprocessed_opts, opt->name); - if (list == NULL) { - list = g_queue_new(); + opts_visitor_insert(ov->unprocessed_opts, opt); + } - /* GHashTable will never try to free the keys -- we supplied NULL - * as "key_destroy_func" above. Thus cast away key const-ness in - * order to suppress gcc's warning. */ - g_hash_table_insert(ov->unprocessed_opts, (gpointer)opt->name, - list); - } + if (ov->opts_root->id != NULL) { + ov->fake_id_opt = g_malloc0(sizeof *ov->fake_id_opt); - /* Similarly, destroy_list() doesn't call g_queue_free_full(). */ - g_queue_push_tail(list, (gpointer)opt); + ov->fake_id_opt->name = "id"; + ov->fake_id_opt->str = ov->opts_root->id; + opts_visitor_insert(ov->unprocessed_opts, ov->fake_id_opt); } } @@ -390,6 +414,7 @@ opts_visitor_cleanup(OptsVisitor *ov) if (ov->unprocessed_opts != NULL) { g_hash_table_destroy(ov->unprocessed_opts); } + g_free(ov->fake_id_opt); memset(ov, '\0', sizeof *ov); } -- 1.7.1