Message ID | 20200224143008.13362-9-kwolf@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add qemu-storage-daemon | expand |
Hi Kevin, I tried to start vhost-user block device backend server with the following command, $ qemu-storage-daemon --blockdev driver=file,node-name=disk,filename=file.img,read-only=off \ --object vhost-user-blk-server,id=disk,unix-socket=/tmp/vu_blk.socket,node-name=disk,writable=off but the following error occurred, qemu-storage-daemon: Invalid parameter type for 'writable', expected: boolean I notice qmp_object_add is used. Should we use user_creatable_add_opts instead? diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c index dd128978cc..9d21aaaf54 100644 --- a/qemu-storage-daemon.c +++ b/qemu-storage-daemon.c @@ -277,8 +277,6 @@ static void process_options(int argc, char *argv[]) { QemuOpts *opts; const char *type; - QDict *args; - QObject *ret_data = NULL; /* FIXME The keyval parser rejects 'help' arguments, so we must * unconditionall try QemuOpts first. */ @@ -288,12 +286,11 @@ static void process_options(int argc, char *argv[]) if (type && user_creatable_print_help(type, opts)) { exit(EXIT_SUCCESS); } + + + user_creatable_add_opts(opts, &error_fatal); qemu_opts_del(opts); - args = keyval_parse(optarg, "qom-type", &error_fatal); - qmp_object_add(args, &ret_data, &error_fatal); - qobject_unref(args); - qobject_unref(ret_data); break; } default: On Mon, Feb 24, 2020 at 03:29:56PM +0100, Kevin Wolf wrote: >Add a command line option to create user-creatable QOM objects. > >Signed-off-by: Kevin Wolf <kwolf@redhat.com> >--- > qemu-storage-daemon.c | 47 +++++++++++++++++++++++++++++++++++++++++++ > Makefile.objs | 2 +- > qom/Makefile.objs | 1 + > 3 files changed, 49 insertions(+), 1 deletion(-) > >diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c >index c30caaf59e..0cd8144c81 100644 >--- a/qemu-storage-daemon.c >+++ b/qemu-storage-daemon.c >@@ -33,15 +33,19 @@ > #include "qapi/error.h" > #include "qapi/qapi-visit-block-core.h" > #include "qapi/qapi-commands-block-core.h" >+#include "qapi/qmp/qdict.h" > #include "qapi/qobject-input-visitor.h" > > #include "qemu-common.h" > #include "qemu-version.h" > #include "qemu/config-file.h" > #include "qemu/error-report.h" >+#include "qemu/help_option.h" > #include "qemu/log.h" > #include "qemu/main-loop.h" > #include "qemu/module.h" >+#include "qemu/option.h" >+#include "qom/object_interfaces.h" > > #include "trace/control.h" > >@@ -63,12 +67,31 @@ static void help(void) > " [,driver specific parameters...]\n" > " configure a block backend\n" > "\n" >+" --object help list object types that can be added\n" >+" --object <type>,help list properties for the given object type\n" >+" --object <type>[,<property>=<value>...]\n" >+" create a new object of type <type>, setting\n" >+" properties in the order they are specified. Note\n" >+" that the 'id' property must be set.\n" >+" See the qemu(1) man page for documentation of the\n" >+" objects that can be added.\n" >+"\n" > QEMU_HELP_BOTTOM "\n", > error_get_progname()); > } > > enum { > OPTION_BLOCKDEV = 256, >+ OPTION_OBJECT, >+}; >+ >+static QemuOptsList qemu_object_opts = { >+ .name = "object", >+ .implied_opt_name = "qom-type", >+ .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head), >+ .desc = { >+ { } >+ }, > }; > > static void process_options(int argc, char *argv[]) >@@ -78,6 +101,7 @@ static void process_options(int argc, char *argv[]) > static const struct option long_options[] = { > {"blockdev", required_argument, NULL, OPTION_BLOCKDEV}, > {"help", no_argument, NULL, 'h'}, >+ {"object", required_argument, NULL, OPTION_OBJECT}, > {"trace", required_argument, NULL, 'T'}, > {"version", no_argument, NULL, 'V'}, > {0, 0, 0, 0} >@@ -121,6 +145,29 @@ static void process_options(int argc, char *argv[]) > qapi_free_BlockdevOptions(options); > break; > } >+ case OPTION_OBJECT: >+ { >+ QemuOpts *opts; >+ const char *type; >+ QDict *args; >+ QObject *ret_data = NULL; >+ >+ /* FIXME The keyval parser rejects 'help' arguments, so we must >+ * unconditionall try QemuOpts first. */ >+ opts = qemu_opts_parse(&qemu_object_opts, >+ optarg, true, &error_fatal); >+ type = qemu_opt_get(opts, "qom-type"); >+ if (type && user_creatable_print_help(type, opts)) { >+ exit(EXIT_SUCCESS); >+ } >+ qemu_opts_del(opts); >+ >+ args = keyval_parse(optarg, "qom-type", &error_fatal); >+ qmp_object_add(args, &ret_data, &error_fatal); >+ qobject_unref(args); >+ qobject_unref(ret_data); >+ break; >+ } > default: > g_assert_not_reached(); > } >diff --git a/Makefile.objs b/Makefile.objs >index c7e1b36130..fa92b00427 100644 >--- a/Makefile.objs >+++ b/Makefile.objs >@@ -31,7 +31,7 @@ endif # CONFIG_SOFTMMU or CONFIG_TOOLS > # storage-daemon-obj-y is code used by qemu-storage-daemon (these objects are > # used for system emulation, too, but specified separately there) > >-storage-daemon-obj-y = block/ >+storage-daemon-obj-y = block/ qom/ > storage-daemon-obj-y += blockdev.o iothread.o > > ###################################################################### >diff --git a/qom/Makefile.objs b/qom/Makefile.objs >index f9d77350ac..1b45d104ba 100644 >--- a/qom/Makefile.objs >+++ b/qom/Makefile.objs >@@ -2,3 +2,4 @@ qom-obj-y = object.o container.o qom-qobject.o > qom-obj-y += object_interfaces.o > > common-obj-$(CONFIG_SOFTMMU) += qom-hmp-cmds.o qom-qmp-cmds.o >+storage-daemon-obj-y += qom-qmp-cmds.o >-- >2.20.1 >
On Mon, Feb 24, 2020 at 03:29:56PM +0100, Kevin Wolf wrote: >Add a command line option to create user-creatable QOM objects. > >Signed-off-by: Kevin Wolf <kwolf@redhat.com> >--- > qemu-storage-daemon.c | 47 +++++++++++++++++++++++++++++++++++++++++++ > Makefile.objs | 2 +- > qom/Makefile.objs | 1 + > 3 files changed, 49 insertions(+), 1 deletion(-) > >diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c >index c30caaf59e..0cd8144c81 100644 >--- a/qemu-storage-daemon.c >+++ b/qemu-storage-daemon.c >@@ -33,15 +33,19 @@ > #include "qapi/error.h" > #include "qapi/qapi-visit-block-core.h" > #include "qapi/qapi-commands-block-core.h" >+#include "qapi/qmp/qdict.h" > #include "qapi/qobject-input-visitor.h" > > #include "qemu-common.h" > #include "qemu-version.h" > #include "qemu/config-file.h" > #include "qemu/error-report.h" >+#include "qemu/help_option.h" > #include "qemu/log.h" > #include "qemu/main-loop.h" > #include "qemu/module.h" >+#include "qemu/option.h" >+#include "qom/object_interfaces.h" > > #include "trace/control.h" > >@@ -63,12 +67,31 @@ static void help(void) > " [,driver specific parameters...]\n" > " configure a block backend\n" > "\n" >+" --object help list object types that can be added\n" >+" --object <type>,help list properties for the given object type\n" >+" --object <type>[,<property>=<value>...]\n" >+" create a new object of type <type>, setting\n" >+" properties in the order they are specified. Note\n" >+" that the 'id' property must be set.\n" >+" See the qemu(1) man page for documentation of the\n" >+" objects that can be added.\n" >+"\n" > QEMU_HELP_BOTTOM "\n", > error_get_progname()); > } > > enum { > OPTION_BLOCKDEV = 256, >+ OPTION_OBJECT, >+}; >+ >+static QemuOptsList qemu_object_opts = { >+ .name = "object", >+ .implied_opt_name = "qom-type", >+ .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head), >+ .desc = { >+ { } >+ }, > }; > I'm not sure whether qemu-storage-daemon's QMP monitor is supposed to support `object-del` or not. If it's yes, we should add `qemu_add_opts(&qemu_object_opts);`, otherwise, qemu-storage-daemon will exit with the following error, Unexpected error in find_list() at util/qemu-config.c:24: The steps to reproduce this error, 1. start qemu-storage-daemon ./qemu-storage-daemon --object iothread,id=iothread0 --chardev socket,id=qmp,path=abc,server,nowait --monitor chardev=qmp 2. send object-del command echo '{ "execute": "qmp_capabilities" }'\ '{ 'object-del', 'arguments': {'id': 'iothread0'} }'\ '{ "execute": "quit" } ' | socat - UNIX-CONNECT:abc
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c index c30caaf59e..0cd8144c81 100644 --- a/qemu-storage-daemon.c +++ b/qemu-storage-daemon.c @@ -33,15 +33,19 @@ #include "qapi/error.h" #include "qapi/qapi-visit-block-core.h" #include "qapi/qapi-commands-block-core.h" +#include "qapi/qmp/qdict.h" #include "qapi/qobject-input-visitor.h" #include "qemu-common.h" #include "qemu-version.h" #include "qemu/config-file.h" #include "qemu/error-report.h" +#include "qemu/help_option.h" #include "qemu/log.h" #include "qemu/main-loop.h" #include "qemu/module.h" +#include "qemu/option.h" +#include "qom/object_interfaces.h" #include "trace/control.h" @@ -63,12 +67,31 @@ static void help(void) " [,driver specific parameters...]\n" " configure a block backend\n" "\n" +" --object help list object types that can be added\n" +" --object <type>,help list properties for the given object type\n" +" --object <type>[,<property>=<value>...]\n" +" create a new object of type <type>, setting\n" +" properties in the order they are specified. Note\n" +" that the 'id' property must be set.\n" +" See the qemu(1) man page for documentation of the\n" +" objects that can be added.\n" +"\n" QEMU_HELP_BOTTOM "\n", error_get_progname()); } enum { OPTION_BLOCKDEV = 256, + OPTION_OBJECT, +}; + +static QemuOptsList qemu_object_opts = { + .name = "object", + .implied_opt_name = "qom-type", + .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head), + .desc = { + { } + }, }; static void process_options(int argc, char *argv[]) @@ -78,6 +101,7 @@ static void process_options(int argc, char *argv[]) static const struct option long_options[] = { {"blockdev", required_argument, NULL, OPTION_BLOCKDEV}, {"help", no_argument, NULL, 'h'}, + {"object", required_argument, NULL, OPTION_OBJECT}, {"trace", required_argument, NULL, 'T'}, {"version", no_argument, NULL, 'V'}, {0, 0, 0, 0} @@ -121,6 +145,29 @@ static void process_options(int argc, char *argv[]) qapi_free_BlockdevOptions(options); break; } + case OPTION_OBJECT: + { + QemuOpts *opts; + const char *type; + QDict *args; + QObject *ret_data = NULL; + + /* FIXME The keyval parser rejects 'help' arguments, so we must + * unconditionall try QemuOpts first. */ + opts = qemu_opts_parse(&qemu_object_opts, + optarg, true, &error_fatal); + type = qemu_opt_get(opts, "qom-type"); + if (type && user_creatable_print_help(type, opts)) { + exit(EXIT_SUCCESS); + } + qemu_opts_del(opts); + + args = keyval_parse(optarg, "qom-type", &error_fatal); + qmp_object_add(args, &ret_data, &error_fatal); + qobject_unref(args); + qobject_unref(ret_data); + break; + } default: g_assert_not_reached(); } diff --git a/Makefile.objs b/Makefile.objs index c7e1b36130..fa92b00427 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -31,7 +31,7 @@ endif # CONFIG_SOFTMMU or CONFIG_TOOLS # storage-daemon-obj-y is code used by qemu-storage-daemon (these objects are # used for system emulation, too, but specified separately there) -storage-daemon-obj-y = block/ +storage-daemon-obj-y = block/ qom/ storage-daemon-obj-y += blockdev.o iothread.o ###################################################################### diff --git a/qom/Makefile.objs b/qom/Makefile.objs index f9d77350ac..1b45d104ba 100644 --- a/qom/Makefile.objs +++ b/qom/Makefile.objs @@ -2,3 +2,4 @@ qom-obj-y = object.o container.o qom-qobject.o qom-obj-y += object_interfaces.o common-obj-$(CONFIG_SOFTMMU) += qom-hmp-cmds.o qom-qmp-cmds.o +storage-daemon-obj-y += qom-qmp-cmds.o
Add a command line option to create user-creatable QOM objects. Signed-off-by: Kevin Wolf <kwolf@redhat.com> --- qemu-storage-daemon.c | 47 +++++++++++++++++++++++++++++++++++++++++++ Makefile.objs | 2 +- qom/Makefile.objs | 1 + 3 files changed, 49 insertions(+), 1 deletion(-)