From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=33655 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OLeom-0005ur-6z for qemu-devel@nongnu.org; Mon, 07 Jun 2010 12:04:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OLeok-0003mM-KN for qemu-devel@nongnu.org; Mon, 07 Jun 2010 12:04:51 -0400 Received: from mail-iw0-f173.google.com ([209.85.214.173]:33765) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OLeok-0003mD-B3 for qemu-devel@nongnu.org; Mon, 07 Jun 2010 12:04:50 -0400 Received: by iwn41 with SMTP id 41so3655331iwn.4 for ; Mon, 07 Jun 2010 09:04:49 -0700 (PDT) Message-ID: <4C0D189C.8050805@codemonkey.ws> Date: Mon, 07 Jun 2010 11:04:44 -0500 From: Anthony Liguori MIME-Version: 1.0 Subject: Re: [Qemu-devel] [PATCH 19/19] Add a -capabilities argument to allow easy query for static QEMU info References: <1275921752-29420-1-git-send-email-berrange@redhat.com> <1275921752-29420-20-git-send-email-berrange@redhat.com> In-Reply-To: <1275921752-29420-20-git-send-email-berrange@redhat.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Daniel P. Berrange" Cc: qemu-devel@nongnu.org On 06/07/2010 09:42 AM, Daniel P. Berrange wrote: > The QMP monitor provides a number of commands for querying info about > the QEMU binary capabilities. Given that these commands don't take > any options and just return static data, requiring the use of QMP is > unnecessarily onerous. This adds a new '-capabilities' command line > argument as a syntactic sugar for accessing the QMP commands that > just return static QEMU binary capabilities. > > Setting the '-capabilities' argument causes QEMU to output the requested > data on stdout, pretty printed in JSON format. The argument expects an > associated value to identify the data to be printed. This can be one of > the strings version|machines|devices|cputypes|target|commands|argv|netdev > > To query all possible data at once, the shorthand 'all' is allowed. > > The output is a QDict where the key is the type of data requested, and > the value is the JSON data from the associated monitor command. For > example: > I think the idea is good but I think we should use a different name as QMP capabilities has a different meaning. Maybe features? Regards, Anthony Liguori > $ qemu -capabilities all > { > "machines": [ > { > "name": "pc-0.13", > "description": "Standard PC", > "default": 0 > }, > { > "name": "pc", > .... > } > .... > } > "version": { > "qemu": { > "micro": 50, > "minor": 12, > "major": 0 > }, > "package": "" > }, > "target": { > "arch": "i386", > "wordsize": 32, > ... > } > > Signed-off-by: Daniel P. Berrange > --- > monitor.c | 4 +- > monitor.h | 2 + > qemu-options.hx | 9 +++++ > vl.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 113 insertions(+), 2 deletions(-) > > diff --git a/monitor.c b/monitor.c > index 6203f75..401a27a 100644 > --- a/monitor.c > +++ b/monitor.c > @@ -711,7 +711,7 @@ static void do_info_version_print(Monitor *mon, const QObject *data) > * > * { qemu: { "major": 0, "minor": 11, "micro": 5 }, "package": "" } > */ > -static void do_info_version(Monitor *mon, QObject **ret_data) > +void do_info_version(Monitor *mon, QObject **ret_data) > { > const char *version = QEMU_VERSION; > int major = 0, minor = 0, micro = 0; > @@ -760,7 +760,7 @@ static QObject *get_cmd_dict(const char *name) > return qobject_from_jsonf("{ 'name': %s }", p); > } > > -static void do_info_commands(Monitor *mon, QObject **ret_data) > +void do_info_commands(Monitor *mon, QObject **ret_data) > { > QList *cmd_list; > const mon_cmd_t *cmd; > diff --git a/monitor.h b/monitor.h > index 733485f..dc376af 100644 > --- a/monitor.h > +++ b/monitor.h > @@ -57,5 +57,7 @@ typedef void (MonitorCompletion)(void *opaque, QObject *ret_data); > void monitor_set_error(Monitor *mon, QError *qerror); > > void do_info_argv(Monitor *mon, QObject **data); > +void do_info_version(Monitor *mon, QObject **ret_data); > +void do_info_commands(Monitor *mon, QObject **ret_data); > > #endif /* !MONITOR_H */ > diff --git a/qemu-options.hx b/qemu-options.hx > index a6928b7..5f82347 100644 > --- a/qemu-options.hx > +++ b/qemu-options.hx > @@ -27,6 +27,15 @@ STEXI > Display version information and exit > ETEXI > > +DEF("capabilities", HAS_ARG, QEMU_OPTION_capabilities, > + "-capabilities all|version|machines|devices|cputypes|target|commands|argv|netdev\n" > + " display capabilities of the QEMU binary and exit\n", QEMU_ARCH_ALL) > +STEXI > +@item -capabilities all|version|machines|devices|cputypes|target|commands|argv|netdev > +@findex -capabilities > +Display capabilities of the QEMU binary and exit > +ETEXI > + > DEF("M", HAS_ARG, QEMU_OPTION_M, > "-M machine select emulated machine (-M ? for list)\n", QEMU_ARCH_ALL) > STEXI > diff --git a/vl.c b/vl.c > index de010cc..1f165a1 100644 > --- a/vl.c > +++ b/vl.c > @@ -1988,6 +1988,97 @@ static void version(void) > } > > > +enum { > + QEMU_CAPS_VERSION, > + QEMU_CAPS_MACHINES, > + QEMU_CAPS_DEVICES, > + QEMU_CAPS_CPUTYPES, > + QEMU_CAPS_TARGET, > + QEMU_CAPS_COMMANDS, > + QEMU_CAPS_ARGV, > + QEMU_CAPS_NETDEV, > + QEMU_CAPS_CONFIG, > + > + QEMU_CAPS_LAST > +}; > + > +QEMU_ENUM_DECL(qemu_caps_flag); > +QEMU_ENUM_IMPL(qemu_caps_flag, QEMU_CAPS_LAST, > + "version", > + "machines", > + "devices", > + "cputypes", > + "target", > + "commands", > + "argv", > + "netdev", > + "config"); > + > +static int qemu_caps_flags_from_string(const char *flagsstr) > +{ > + if (strcmp(flagsstr, "all") == 0) > + return ~0; > + else { > + int i = qemu_caps_flag_from_string(flagsstr); > + if (i< 0) > + return 0; > + return (1<< i); > + } > + > + return 0; > +} > +typedef void (*qemu_caps_handler)(Monitor *mon, QObject **); > + > +/* Binding capabilities to a subset of monitor commands. > + * The commands must only use static binary state, no > + * VM runtime state and must accept mon=NULL > + */ > +static const qemu_caps_handler qemu_caps_handlers[] = { > + do_info_version, > + do_info_machines, > + do_info_devices, > + do_info_cpu_types, > + do_info_target, > + do_info_commands, > + do_info_argv, > + do_info_netdev, > + do_info_config, > +}; > +verify(ARRAY_SIZE(qemu_caps_handlers) == QEMU_CAPS_LAST); > + > +static void qemu_show_caps(const char *flagsstr) > +{ > + QDict *data = qdict_new(); > + QString *json; > + int i; > + int flags; > + > + flags = qemu_caps_flags_from_string(flagsstr); > + if (flags == 0) { > + fprintf(stderr, "Unknown capabilities '%s'\n", flagsstr); > + exit(1); > + } > + > + for (i = 0 ; i< QEMU_CAPS_LAST ; i++) { > + if (flags& (1<< i)) { > + QObject *val; > + qemu_caps_handler handler = qemu_caps_handlers[i]; > + const char *name = qemu_caps_flag_to_string(i); > + (*handler)(NULL,&val); > + qdict_put_obj(data, name, val); > + } > + } > + json = qobject_to_json_pretty(QOBJECT(data)); > + assert(json != NULL); > + > + qstring_append_chr(json, '\n'); > + fprintf(stdout, qstring_get_str(json)); > + > + QDECREF(json); > + > +} > + > + > /** > * do_info_argv(): > * > @@ -2647,6 +2738,7 @@ int main(int argc, char **argv, char **envp) > #endif > int show_vnc_port = 0; > int defconfig = 1; > + const char *showcaps = NULL; > > error_set_progname(argv[0]); > > @@ -3020,6 +3112,9 @@ int main(int argc, char **argv, char **envp) > version(); > exit(0); > break; > + case QEMU_OPTION_capabilities: > + showcaps = optarg; > + break; > case QEMU_OPTION_m: { > uint64_t value; > char *ptr; > @@ -3785,6 +3880,11 @@ int main(int argc, char **argv, char **envp) > if (qemu_opts_foreach(&qemu_device_opts, device_help_func, NULL, 0) != 0) > exit(0); > > + if (showcaps) { > + qemu_show_caps(showcaps); > + exit(0); > + } > + > if (watchdog) { > i = select_watchdog(watchdog); > if (i> 0) >