Patchwork [16/19] Add a query-netdev command to QMP

login
register
mail settings
Submitter Daniel P. Berrange
Date June 7, 2010, 2:42 p.m.
Message ID <1275921752-29420-17-git-send-email-berrange@redhat.com>
Download mbox | patch
Permalink /patch/54865/
State New
Headers show

Comments

Daniel P. Berrange - June 7, 2010, 2:42 p.m.
This adds a new QMP command called query-netdev to provide information
about the available netdev backends in the QEMU binary. There is no
existing '-netdev ?' support, but if there was, this would obsolete it

The data format looks like

    [
        {
            "name": "user",
            "props": [
                {
                    "name": "type",
                    "help": "net client type (nic, tap etc.)",
                    "type": "string"
                },
                {
                    "name": "name",
                    "help": "identifier for monitor commands",
                    "type": "string"
                },
                {
                    "name": "hostname",
                    "help": "client hostname reported by the builtin DHCP server",
                    "type": "string"
                },
                ...
            ]
        }
        {
            "name": "tap",
            "props": [
                {
                    "name": "type",
                    "help": "net client type (nic, tap etc.)",
                    "type": "string"
                },
                {
                    "name": "ifname",
                    "help": "interface name",
                    "type": "string"
                },
                ...
            ]
        }
        ...
    ]

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 monitor.c     |    8 ++++++++
 net.c         |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 net.h         |    2 ++
 qemu-option.c |    4 ++++
 qemu-option.h |    4 ++++
 5 files changed, 67 insertions(+), 0 deletions(-)
Anthony Liguori - June 7, 2010, 3:15 p.m.
On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
> This adds a new QMP command called query-netdev to provide information
> about the available netdev backends in the QEMU binary. There is no
> existing '-netdev ?' support, but if there was, this would obsolete it
>
> The data format looks like
>
>      [
>          {
>              "name": "user",
>              "props": [
>                  {
>                      "name": "type",
>                      "help": "net client type (nic, tap etc.)",
>                      "type": "string"
>                  },
>    

I'm not sure it's a good idea to expose the help text.  That bakes it 
into the ABI which seems bad.

Regards,

Anthony Liguori

>                  {
>                      "name": "name",
>                      "help": "identifier for monitor commands",
>                      "type": "string"
>                  },
>                  {
>                      "name": "hostname",
>                      "help": "client hostname reported by the builtin DHCP server",
>                      "type": "string"
>                  },
>                  ...
>              ]
>          }
>          {
>              "name": "tap",
>              "props": [
>                  {
>                      "name": "type",
>                      "help": "net client type (nic, tap etc.)",
>                      "type": "string"
>                  },
>                  {
>                      "name": "ifname",
>                      "help": "interface name",
>                      "type": "string"
>                  },
>                  ...
>              ]
>          }
>          ...
>      ]
>
> Signed-off-by: Daniel P. Berrange<berrange@redhat.com>
> ---
>   monitor.c     |    8 ++++++++
>   net.c         |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
>   net.h         |    2 ++
>   qemu-option.c |    4 ++++
>   qemu-option.h |    4 ++++
>   5 files changed, 67 insertions(+), 0 deletions(-)
>
> diff --git a/monitor.c b/monitor.c
> index 1c5157d..19f42f3 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -2552,6 +2552,14 @@ static const mon_cmd_t info_cmds[] = {
>           .mhandler.info_new = do_info_argv,
>       },
>       {
> +        .name       = "netdev",
> +        .args_type  = "",
> +        .params     = "",
> +        .help       = "list valid netdev backend types",
> +        .user_print = monitor_user_noop,
> +        .mhandler.info_new = do_info_netdev,
> +    },
> +    {
>           .name       = "network",
>           .args_type  = "",
>           .params     = "",
> diff --git a/net.c b/net.c
> index 5349001..90929d4 100644
> --- a/net.c
> +++ b/net.c
> @@ -36,6 +36,8 @@
>   #include "qemu-common.h"
>   #include "qemu_socket.h"
>   #include "hw/qdev.h"
> +#include "qjson.h"
> +#include "qlist.h"
>
>   static QTAILQ_HEAD(, VLANState) vlans;
>   static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
> @@ -1080,6 +1082,53 @@ static const struct {
>   };
>   verify(ARRAY_SIZE(net_client_types) == NET_CLIENT_LAST);
>
> +
> +void do_info_netdev(Monitor *mon, QObject **data)
> +{
> +    QList *backends = qlist_new();
> +    int i, j;
> +
> +    for (i = 0; i<  ARRAY_SIZE(net_client_types) ; i++) {
> +	QObject *backend;
> +	QList *props = qlist_new();
> +
> +	if (i == NET_CLIENT_NIC ||
> +	    i == NET_CLIENT_DUMP||
> +	    i == NET_CLIENT_NONE)
> +	    continue;
> +
> +	for (j = 0 ; net_client_types[i].desc[j].name != NULL ; j++) {
> +	    const QemuOptDesc *desc = net_client_types[i].desc + j;
> +	    QObject *prop;
> +
> +	    if (strcmp(desc->name, "vlan") == 0)
> +		continue;
> +
> +	    if (desc->help) {
> +		prop = qobject_from_jsonf("{ 'name': %s, 'type': %s, 'help': %s }",
> +					  desc->name,
> +					  qemu_opt_type_to_string(desc->type),
> +					  desc->help);
> +	    } else {
> +		prop = qobject_from_jsonf("{ 'name': %s, 'type': %s }",
> +					  desc->name,
> +					  qemu_opt_type_to_string(desc->type));
> +	    }
> +
> +	    qlist_append_obj(props, prop);
> +	}
> +
> +	backend = qobject_from_jsonf("{ 'name': %s, 'props': %p }",
> +				     qemu_net_type_to_string(i),
> +				     props);
> +
> +	qlist_append_obj(backends, backend);
> +    }
> +
> +    *data = qobject_from_jsonf("{ 'backends': %p }", backends);
> +}
> +
> +
>   int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
>   {
>       const char *name;
> diff --git a/net.h b/net.h
> index b83f615..9c0e385 100644
> --- a/net.h
> +++ b/net.h
> @@ -167,6 +167,8 @@ void net_host_device_remove(Monitor *mon, const QDict *qdict);
>   int do_netdev_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
>   int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
>
> +void do_info_netdev(Monitor *mon, QObject **data);
> +
>   #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
>   #define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
>   #ifdef __sun__
> diff --git a/qemu-option.c b/qemu-option.c
> index bb9cc43..f132a9b 100644
> --- a/qemu-option.c
> +++ b/qemu-option.c
> @@ -32,6 +32,10 @@
>   #include "qemu-option.h"
>   #include "qerror.h"
>
> +QEMU_ENUM_IMPL(qemu_opt_type, QEMU_OPT_LAST,
> +	       "string", "bool", "number",
> +	       "size", "enum");
> +
>   /*
>    * Extracts the name of an option from the parameter string (p points at the
>    * first byte of the option name)
> diff --git a/qemu-option.h b/qemu-option.h
> index 3540a9b..9382cc3 100644
> --- a/qemu-option.h
> +++ b/qemu-option.h
> @@ -28,6 +28,7 @@
>
>   #include<stdint.h>
>   #include "qemu-queue.h"
> +#include "qemu-enum.h"
>   #include "qdict.h"
>
>   enum QEMUOptionParType {
> @@ -90,7 +91,10 @@ enum QemuOptType {
>       QEMU_OPT_NUMBER,      /* simple number                                        */
>       QEMU_OPT_SIZE,        /* size, accepts (K)ilo, (M)ega, (G)iga, (T)era postfix */
>       QEMU_OPT_ENUM,        /* int, from user string validated against an enum      */
> +
> +    QEMU_OPT_LAST,
>   };
> +QEMU_ENUM_DECL(qemu_opt_type);
>
>   typedef struct QemuOptDesc {
>       const char *name;
>
Miguel Di Ciurcio Filho - June 7, 2010, 7:13 p.m.
On Mon, Jun 7, 2010 at 11:42 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
> This adds a new QMP command called query-netdev to provide information
> about the available netdev backends in the QEMU binary. There is no
> existing '-netdev ?' support, but if there was, this would obsolete it
>

Hi Daniel,

Could we work on a different name? Just a few hours ago on another
thread query-netdev, instead of the originaly proposed
query-netdevices, was proposed, with similar functionality. I see that
your patch shows the supported backends. I'm working on another patch
that actually shows the current used backend network devices.

Regards,

Miguel
Daniel P. Berrange - June 8, 2010, 8:38 a.m.
On Mon, Jun 07, 2010 at 04:13:48PM -0300, Miguel Di Ciurcio Filho wrote:
> On Mon, Jun 7, 2010 at 11:42 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
> > This adds a new QMP command called query-netdev to provide information
> > about the available netdev backends in the QEMU binary. There is no
> > existing '-netdev ?' support, but if there was, this would obsolete it
> >
> 
> Hi Daniel,
> 
> Could we work on a different name? Just a few hours ago on another
> thread query-netdev, instead of the originaly proposed
> query-netdevices, was proposed, with similar functionality. I see that
> your patch shows the supported backends. I'm working on another patch
> that actually shows the current used backend network devices.

Yeah perhaps I should rename mine to 'query-netdev-types' so show that it
is static info about the types of netdev available, rather than about the
configured instances


Daniel
Markus Armbruster - June 26, 2010, 7:32 a.m.
Anthony Liguori <anthony@codemonkey.ws> writes:

> On 06/07/2010 09:42 AM, Daniel P. Berrange wrote:
>> This adds a new QMP command called query-netdev to provide information
>> about the available netdev backends in the QEMU binary. There is no
>> existing '-netdev ?' support, but if there was, this would obsolete it
>>
>> The data format looks like
>>
>>      [
>>          {
>>              "name": "user",
>>              "props": [
>>                  {
>>                      "name": "type",
>>                      "help": "net client type (nic, tap etc.)",
>>                      "type": "string"
>>                  },
>>    
>
> I'm not sure it's a good idea to expose the help text.  That bakes it
> into the ABI which seems bad.

Bah.  Tell clients "this part is informative and not ABI, and you'll die
a horrible death if you parse it", then change it a couple of times to
drive the point home.

Patch

diff --git a/monitor.c b/monitor.c
index 1c5157d..19f42f3 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2552,6 +2552,14 @@  static const mon_cmd_t info_cmds[] = {
         .mhandler.info_new = do_info_argv,
     },
     {
+        .name       = "netdev",
+        .args_type  = "",
+        .params     = "",
+        .help       = "list valid netdev backend types",
+        .user_print = monitor_user_noop,
+        .mhandler.info_new = do_info_netdev,
+    },
+    {
         .name       = "network",
         .args_type  = "",
         .params     = "",
diff --git a/net.c b/net.c
index 5349001..90929d4 100644
--- a/net.c
+++ b/net.c
@@ -36,6 +36,8 @@ 
 #include "qemu-common.h"
 #include "qemu_socket.h"
 #include "hw/qdev.h"
+#include "qjson.h"
+#include "qlist.h"
 
 static QTAILQ_HEAD(, VLANState) vlans;
 static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
@@ -1080,6 +1082,53 @@  static const struct {
 };
 verify(ARRAY_SIZE(net_client_types) == NET_CLIENT_LAST);
 
+
+void do_info_netdev(Monitor *mon, QObject **data)
+{
+    QList *backends = qlist_new();
+    int i, j;
+
+    for (i = 0; i < ARRAY_SIZE(net_client_types) ; i++) {
+	QObject *backend;
+	QList *props = qlist_new();
+
+	if (i == NET_CLIENT_NIC ||
+	    i == NET_CLIENT_DUMP||
+	    i == NET_CLIENT_NONE)
+	    continue;
+
+	for (j = 0 ; net_client_types[i].desc[j].name != NULL ; j++) {
+	    const QemuOptDesc *desc = net_client_types[i].desc + j;
+	    QObject *prop;
+
+	    if (strcmp(desc->name, "vlan") == 0)
+		continue;
+
+	    if (desc->help) {
+		prop = qobject_from_jsonf("{ 'name': %s, 'type': %s, 'help': %s }",
+					  desc->name,
+					  qemu_opt_type_to_string(desc->type),
+					  desc->help);
+	    } else {
+		prop = qobject_from_jsonf("{ 'name': %s, 'type': %s }",
+					  desc->name,
+					  qemu_opt_type_to_string(desc->type));
+	    }
+
+	    qlist_append_obj(props, prop);
+	}
+
+	backend = qobject_from_jsonf("{ 'name': %s, 'props': %p }",
+				     qemu_net_type_to_string(i),
+				     props);
+
+	qlist_append_obj(backends, backend);
+    }
+
+    *data = qobject_from_jsonf("{ 'backends': %p }", backends);
+}
+
+
 int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
 {
     const char *name;
diff --git a/net.h b/net.h
index b83f615..9c0e385 100644
--- a/net.h
+++ b/net.h
@@ -167,6 +167,8 @@  void net_host_device_remove(Monitor *mon, const QDict *qdict);
 int do_netdev_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
 int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
 
+void do_info_netdev(Monitor *mon, QObject **data);
+
 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
 #define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
 #ifdef __sun__
diff --git a/qemu-option.c b/qemu-option.c
index bb9cc43..f132a9b 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -32,6 +32,10 @@ 
 #include "qemu-option.h"
 #include "qerror.h"
 
+QEMU_ENUM_IMPL(qemu_opt_type, QEMU_OPT_LAST,
+	       "string", "bool", "number",
+	       "size", "enum");
+
 /*
  * Extracts the name of an option from the parameter string (p points at the
  * first byte of the option name)
diff --git a/qemu-option.h b/qemu-option.h
index 3540a9b..9382cc3 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -28,6 +28,7 @@ 
 
 #include <stdint.h>
 #include "qemu-queue.h"
+#include "qemu-enum.h"
 #include "qdict.h"
 
 enum QEMUOptionParType {
@@ -90,7 +91,10 @@  enum QemuOptType {
     QEMU_OPT_NUMBER,      /* simple number                                        */
     QEMU_OPT_SIZE,        /* size, accepts (K)ilo, (M)ega, (G)iga, (T)era postfix */
     QEMU_OPT_ENUM,        /* int, from user string validated against an enum      */
+
+    QEMU_OPT_LAST,
 };
+QEMU_ENUM_DECL(qemu_opt_type);
 
 typedef struct QemuOptDesc {
     const char *name;