From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44685) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1boXp7-0006VC-Rb for qemu-devel@nongnu.org; Mon, 26 Sep 2016 11:28:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1boXp6-0004El-Jy for qemu-devel@nongnu.org; Mon, 26 Sep 2016 11:28:05 -0400 From: Kevin Wolf Date: Mon, 26 Sep 2016 17:27:54 +0200 Message-Id: <1474903676-5680-2-git-send-email-kwolf@redhat.com> In-Reply-To: <1474903676-5680-1-git-send-email-kwolf@redhat.com> References: <1474903676-5680-1-git-send-email-kwolf@redhat.com> Subject: [Qemu-devel] [PATCH v3 1/3] block: Add '-blockdev' command line option List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-block@nongnu.org Cc: kwolf@redhat.com, mreitz@redhat.com, eblake@redhat.com, qemu-devel@nongnu.org This is an option that is directly mapped to the blockdev-add QMP command. It works more or less like -drive, except that it doesn't create a BlockBackend and doesn't support legacy options. This patch adds minimal documentation, the next patches will improve it. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake Reviewed-by: Max Reitz --- blockdev.c | 12 +++++++++++ include/sysemu/sysemu.h | 1 + qemu-options.hx | 12 +++++++++++ vl.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+) diff --git a/blockdev.c b/blockdev.c index d11a74f..b9af9fd 100644 --- a/blockdev.c +++ b/blockdev.c @@ -4075,3 +4075,15 @@ QemuOptsList qemu_drive_opts = { { /* end of list */ } }, }; + +QemuOptsList qemu_blockdev_opts = { + .name = "blockdev", + .head = QTAILQ_HEAD_INITIALIZER(qemu_blockdev_opts.head), + .desc = { + /* + * no elements => accept any params + * validation will happen later + */ + { /* end of list */ } + }, +}; diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index ef2c50b..264cd80 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -235,6 +235,7 @@ bool defaults_enabled(void); extern QemuOptsList qemu_legacy_drive_opts; extern QemuOptsList qemu_common_drive_opts; extern QemuOptsList qemu_drive_opts; +extern QemuOptsList qemu_blockdev_opts; extern QemuOptsList qemu_chardev_opts; extern QemuOptsList qemu_device_opts; extern QemuOptsList qemu_netdev_opts; diff --git a/qemu-options.hx b/qemu-options.hx index 0b621bb..5d13898 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -513,6 +513,18 @@ Use @var{file} as CD-ROM image (you cannot use @option{-hdc} and using @file{/dev/cdrom} as filename (@pxref{host_drives}). ETEXI +DEF("blockdev", HAS_ARG, QEMU_OPTION_blockdev, + "-blockdev driver=driver,node-name=n[,read-only=on|off]\n" + " [,cache.direct=on|off][,cache.no-flush=on|off]\n" + " [,discard=ignore|unmap][,detect-zeroes=on|off|unmap]\n" + " [,...driver specific...]\n", QEMU_ARCH_ALL) +STEXI +@item -blockdev @var{option}[,@var{option}[,@var{option}[,...]]] +@findex -blockdev + +Define a new block driver node. +ETEXI + DEF("drive", HAS_ARG, QEMU_OPTION_drive, "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n" " [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n" diff --git a/vl.c b/vl.c index 215a6f9..6f9369a 100644 --- a/vl.c +++ b/vl.c @@ -123,6 +123,9 @@ int main(int argc, char **argv) #include "sysemu/replay.h" #include "qapi/qmp/qerror.h" #include "sysemu/iothread.h" +#include "qapi-visit.h" +#include "qapi/qobject-input-visitor.h" +#include "qapi/dealloc-visitor.h" #define MAX_VIRTIO_CONSOLES 1 #define MAX_SCLP_CONSOLES 1 @@ -1170,6 +1173,42 @@ static int cleanup_add_fd(void *opaque, QemuOpts *opts, Error **errp) #define MTD_OPTS "" #define SD_OPTS "" +static int blockdev_init_func(void *opaque, QemuOpts *opts, Error **errp) +{ + BlockdevOptions *options = NULL; + Visitor *v = NULL; + Error *local_err = NULL; + + QDict *opts_dict = qemu_opts_to_qdict(opts, NULL); + QObject *crumpled = qdict_crumple(opts_dict, true, &local_err); + if (local_err) { + goto fail; + } + + v = qobject_string_input_visitor_new(crumpled); + visit_type_BlockdevOptions(v, NULL, &options, &local_err); + if (local_err) { + goto fail; + } + visit_complete(v, opts); + + qmp_blockdev_add(options, &local_err); + if (local_err) { + goto fail; + } + +fail: + qapi_free_BlockdevOptions(options); + visit_free(v); + QDECREF(opts_dict); + qobject_decref(crumpled); + + if (local_err) { + error_propagate(errp, local_err); + } + return !!local_err; +} + static int drive_init_func(void *opaque, QemuOpts *opts, Error **errp) { BlockInterfaceType *block_default_type = opaque; @@ -3028,6 +3067,7 @@ int main(int argc, char **argv, char **envp) module_call_init(MODULE_INIT_QAPI); qemu_add_opts(&qemu_drive_opts); + qemu_add_opts(&qemu_blockdev_opts); qemu_add_drive_opts(&qemu_legacy_drive_opts); qemu_add_drive_opts(&qemu_common_drive_opts); qemu_add_drive_opts(&qemu_drive_opts); @@ -3163,6 +3203,13 @@ int main(int argc, char **argv, char **envp) exit(1); } break; + case QEMU_OPTION_blockdev: + opts = qemu_opts_parse_noisily(qemu_find_opts("blockdev"), + optarg, false); + if (opts == NULL) { + exit(1); + } + break; case QEMU_OPTION_set: if (qemu_set_option(optarg) != 0) exit(1); @@ -4450,6 +4497,12 @@ int main(int argc, char **argv, char **envp) } /* open the virtual block devices */ + if (qemu_opts_foreach(qemu_find_opts("blockdev"), blockdev_init_func, + NULL, &err)) { + error_report_err(err); + exit(1); + } + if (snapshot || replay_mode != REPLAY_MODE_NONE) { qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot, NULL, NULL); -- 1.8.3.1