qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: qemu-devel@nongnu.org
Cc: Alex Kirillov <lekiravi@yandex-team.ru>
Subject: [PULL 29/30] net: Complete qapi-fication of netdev_add
Date: Tue, 17 Mar 2020 22:01:14 +0100	[thread overview]
Message-ID: <20200317210115.8864-30-armbru@redhat.com> (raw)
In-Reply-To: <20200317210115.8864-1-armbru@redhat.com>

From: Eric Blake <eblake@redhat.com>

We've had all the required pieces for doing a type-safe representation
of netdev_add as a flat union for quite some time now (since
0e55c381f6 in v2.7.0, released in 2016), but did not make the final
switch to using it because of concern about whether a command-line
regression in accepting "1" in place of 1 for integer arguments would
be problematic.  Back then, we did not have the deprecation cycle to
allow us to make progress.  But now that we have waited so long, other
problems have crept in: for example, our desire to add
qemu-storage-daemon is hampered by the inability to express net
objects, and we are unable to introspect what we actually accept.
Additionally, our round-trip through QemuOpts silently eats any
argument that expands to an array, rendering dnssearch, hostfwd, and
guestfwd useless through QMP:

{"execute": "netdev_add", "arguments": { "id": "netdev0",
  "type": "user", "dnssearch": [
    { "str": "8.8.8.8" }, { "str": "8.8.4.4" }
  ]}}

So without further ado, let's turn on proper QAPI.  netdev_add() was a
trivial wrapper around net_client_init(), which did a few steps prior
to calling net_client_init1(); with this patch, we now skip directly
to net_client_init1().  In addition to fixing array parameters, the
following additional differences occur:

-  {"execute": "netdev_add", "arguments": {"type": "help"}}
no longer attempts to print help to stdout and exit.  Bug fix, broken
in 547203ead4 'net: List available netdevs with "-netdev help"',
v2.12.0.

-  {"execute": "netdev_add", "arguments': {... "ipv6-net": "..." }}
no longer attempts to desugar the undocumented ipv6-net magic string
into the proper "ipv6-prefix" and "ipv6-prefixlen".  Undocumented
misfeature, introduced in commit 7aac531ef2 "qapi-schema, qemu-options
& slirp: Adding Qemu options for IPv6 addresses", v2.6.0.

-  {'execute':'netdev_add',
     'arguments':{'id':'net2', 'type':'hubport', 'hubid':"2"}}
   {"error": {"class": "GenericError", "desc": "Invalid parameter type for 'hubid', expected: integer"}}
Used to succeed: since our command line treats everything as strings,
our not-so-round-trip conversion from QAPI -> QemuOpts -> QAPI lost
the original typing and turned everything into a string; now that we
skip the QemuOpts, the JSON input has to match the exact QAPI type.
But this stricter QMP is desirable, and introspection is sufficient
for any affected applications to make sure they use it correctly.

In qmp_netdev_add(), we still have to create a QemuOpts object so that
qmp_netdev_del() will be able to remove a hotplugged network device;
but the opts->head remains empty since we now manage all parsing
through the QAPI object rather than QemuOpts; a separate patch will
address the abuse of QemuOpts as a witness for whether a
NetClientState is a netdev.  In the meantime, our argument that we are
okay requires auditing all uses of option group "netdev":

- qemu_netdev_opts: option group definition, empty .desc[]
- CLI (CLI netdev parsing ends before monitors start, so while
  monitors can mess with CLI netdevs, CLI cannot mess with
  monitor netdevs):
  - main() case QEMU_OPTION_netdev: store CLI definition
  - main() case QEMU_OPTION_readconfig, case QEMU_OPTION_writeconfig:
  similar, dealing only with CLI
  - net_init_clients(): Pass CLI to net_client_init()
- Monitor:
  - hmp_netdev_add(): straightforward parse into net_client_init()
  - qmp_netdev_add(): subject of this patch, used to add full
  object to option group, now just adds bare-bones id
  - qmp_netdev_del(), netdev_del_completion(): check the option group
  solely for id, as a 'is this a netdev' predicate

Reported-by: Alex Kirillov <lekiravi@yandex-team.ru>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20200317201711.322764-2-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[Commit message typo fixed]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 qapi/net.json     | 14 +-------------
 include/net/net.h |  1 -
 monitor/misc.c    |  2 --
 net/net.c         |  6 +++---
 4 files changed, 4 insertions(+), 19 deletions(-)

diff --git a/qapi/net.json b/qapi/net.json
index 1cb9a7d782..cebb1b52e3 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -39,18 +39,8 @@
 #
 # Add a network backend.
 #
-# @type: the type of network backend. Possible values are listed in
-#        NetClientDriver (excluding 'none' and 'nic')
-#
-# @id: the name of the new network backend
-#
 # Additional arguments depend on the type.
 #
-# TODO: This command effectively bypasses QAPI completely due to its
-#       "additional arguments" business.  It shouldn't have been added to
-#       the schema in this form.  It should be qapified properly, or
-#       replaced by a properly qapified command.
-#
 # Since: 0.14.0
 #
 # Returns: Nothing on success
@@ -64,9 +54,7 @@
 # <- { "return": {} }
 #
 ##
-{ 'command': 'netdev_add',
-  'data': {'type': 'str', 'id': 'str'},
-  'gen': false }                # so we can get the additional arguments
+{ 'command': 'netdev_add', 'data': 'Netdev', 'boxed': true }
 
 ##
 # @netdev_del:
diff --git a/include/net/net.h b/include/net/net.h
index e175ba9677..96e6eae817 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -203,7 +203,6 @@ void net_cleanup(void);
 void hmp_host_net_add(Monitor *mon, const QDict *qdict);
 void hmp_host_net_remove(Monitor *mon, const QDict *qdict);
 void netdev_add(QemuOpts *opts, Error **errp);
-void qmp_netdev_add(QDict *qdict, QObject **ret, Error **errp);
 
 int net_hub_id_for_client(NetClientState *nc, int *id);
 NetClientState *net_hub_port_find(int hub_id);
diff --git a/monitor/misc.c b/monitor/misc.c
index c3bc34c099..41a86e7012 100644
--- a/monitor/misc.c
+++ b/monitor/misc.c
@@ -247,8 +247,6 @@ static void monitor_init_qmp_commands(void)
                          qmp_query_qmp_schema, QCO_ALLOW_PRECONFIG);
     qmp_register_command(&qmp_commands, "device_add", qmp_device_add,
                          QCO_NO_OPTIONS);
-    qmp_register_command(&qmp_commands, "netdev_add", qmp_netdev_add,
-                         QCO_NO_OPTIONS);
     qmp_register_command(&qmp_commands, "object-add", qmp_object_add,
                          QCO_NO_OPTIONS);
 
diff --git a/net/net.c b/net/net.c
index 9e93c3f8a1..a2065aabed 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1170,7 +1170,7 @@ void netdev_add(QemuOpts *opts, Error **errp)
     net_client_init(opts, true, errp);
 }
 
-void qmp_netdev_add(QDict *qdict, QObject **ret, Error **errp)
+void qmp_netdev_add(Netdev *netdev, Error **errp)
 {
     Error *local_err = NULL;
     QemuOptsList *opts_list;
@@ -1181,12 +1181,12 @@ void qmp_netdev_add(QDict *qdict, QObject **ret, Error **errp)
         goto out;
     }
 
-    opts = qemu_opts_from_qdict(opts_list, qdict, &local_err);
+    opts = qemu_opts_create(opts_list, netdev->id, 1, &local_err);
     if (local_err) {
         goto out;
     }
 
-    netdev_add(opts, &local_err);
+    net_client_init1(netdev, true, &local_err);
     if (local_err) {
         qemu_opts_del(opts);
         goto out;
-- 
2.21.1



  parent reply	other threads:[~2020-03-17 21:11 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-17 21:00 [PULL 00/30] QAPI patches for 2020-03-17 Markus Armbruster
2020-03-17 21:00 ` [PULL 01/30] docs/devel/qapi-code-gen: Fix typo in grammar Markus Armbruster
2020-03-17 21:00 ` [PULL 02/30] qemu-doc: Belatedly document QMP command arg & result deprecation Markus Armbruster
2020-03-17 21:00 ` [PULL 03/30] qapi: Belatedly update doc comment for @wait deprecation Markus Armbruster
2020-03-17 21:00 ` [PULL 04/30] docs/devel/qapi-code-gen: Clarify allow-oob introspection Markus Armbruster
2020-03-17 21:00 ` [PULL 05/30] docs/devel/qapi-code-gen: Document 'features' introspection Markus Armbruster
2020-03-17 21:00 ` [PULL 06/30] tests/test-qmp-cmds: Factor out qmp_dispatch() test helpers Markus Armbruster
2020-03-17 21:00 ` [PULL 07/30] tests/test-qmp-cmds: Check responses more thoroughly Markus Armbruster
2020-03-17 21:00 ` [PULL 08/30] tests/test-qmp-cmds: Simplify test data setup Markus Armbruster
2020-03-17 21:00 ` [PULL 09/30] tests/test-qmp-event: " Markus Armbruster
2020-03-17 21:00 ` [PULL 10/30] tests/test-qmp-event: Use qobject_is_equal() Markus Armbruster
2020-03-17 21:00 ` [PULL 11/30] tests/test-qmp-event: Check event is actually emitted Markus Armbruster
2020-03-17 21:00 ` [PULL 12/30] qapi/schema: Clean up around QAPISchemaEntity.connect_doc() Markus Armbruster
2020-03-17 21:00 ` [PULL 13/30] qapi: Add feature flags to remaining definitions Markus Armbruster
2020-03-17 21:00 ` [PULL 14/30] qapi: Consistently put @features parameter right after @ifcond Markus Armbruster
2020-03-17 21:01 ` [PULL 15/30] qapi/introspect: Rename *qlit* to reduce confusion Markus Armbruster
2020-03-17 21:01 ` [PULL 16/30] qapi/introspect: Factor out _make_tree() Markus Armbruster
2020-03-17 21:01 ` [PULL 17/30] qapi/schema: Change _make_features() to a take feature list Markus Armbruster
2020-03-17 21:01 ` [PULL 18/30] qapi/schema: Reorder classes so related ones are together Markus Armbruster
2020-03-17 21:01 ` [PULL 19/30] qapi/schema: Rename QAPISchemaObjectType{Variant, Variants} Markus Armbruster
2020-03-17 21:01 ` [PULL 20/30] qapi/schema: Call QAPIDoc.connect_member() in just one place Markus Armbruster
2020-03-17 21:01 ` [PULL 21/30] qapi: Add feature flags to struct members Markus Armbruster
2020-03-17 21:01 ` [PULL 22/30] qapi: Inline do_qmp_dispatch() into qmp_dispatch() Markus Armbruster
2020-03-17 21:01 ` [PULL 23/30] qapi: Simplify how qmp_dispatch() deals with QCO_NO_SUCCESS_RESP Markus Armbruster
2020-03-17 21:01 ` [PULL 24/30] qapi: Simplify how qmp_dispatch() gets the request ID Markus Armbruster
2020-03-17 21:01 ` [PULL 25/30] qapi: Replace qmp_dispatch()'s TODO comment by an explanation Markus Armbruster
2020-03-17 21:01 ` [PULL 26/30] qapi: New special feature flag "deprecated" Markus Armbruster
2020-03-17 21:01 ` [PULL 27/30] qapi: Mark deprecated QMP parts with feature 'deprecated' Markus Armbruster
2020-03-17 21:01 ` [PULL 28/30] qmp: constify QmpCommand and list Markus Armbruster
2020-03-17 21:01 ` Markus Armbruster [this message]
2020-03-17 21:01 ` [PULL 30/30] net: Track netdevs in NetClientState rather than QemuOpt Markus Armbruster
2020-03-19 11:00 ` [PULL 00/30] QAPI patches for 2020-03-17 Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200317210115.8864-30-armbru@redhat.com \
    --to=armbru@redhat.com \
    --cc=lekiravi@yandex-team.ru \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).