All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, armbru@redhat.com, stefanha@redhat.com,
	lcapitulino@redhat.com
Subject: [Qemu-devel] [PATCH 18/18] blockdev: 'blockdev-add' QMP command
Date: Tue, 23 Jul 2013 15:03:26 +0200	[thread overview]
Message-ID: <1374584606-5615-19-git-send-email-kwolf@redhat.com> (raw)
In-Reply-To: <1374584606-5615-1-git-send-email-kwolf@redhat.com>

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 blockdev.c       |  45 +++++++++
 qapi-schema.json | 293 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qmp-commands.hx  |  26 +++++
 3 files changed, 364 insertions(+)

diff --git a/blockdev.c b/blockdev.c
index ef55b1a..214173b 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -38,6 +38,8 @@
 #include "qemu/option.h"
 #include "qemu/config-file.h"
 #include "qapi/qmp/types.h"
+#include "qapi-visit.h"
+#include "qapi/qmp-output-visitor.h"
 #include "sysemu/sysemu.h"
 #include "block/block_int.h"
 #include "qmp-commands.h"
@@ -1805,6 +1807,49 @@ void qmp_block_job_complete(const char *device, Error **errp)
     block_job_complete(job, errp);
 }
 
+void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
+{
+    QmpOutputVisitor *ov = qmp_output_visitor_new();
+    QObject *obj;
+    QDict *qdict;
+
+    if (!options->has_id) {
+        error_setg(errp, "Block device needs an ID");
+        return;
+    }
+
+    /* TODO Sort it out in raw-posix and drive_init: Reject aio=native with
+     * cache.direct=off instead of silently switching to aio=threads, except if
+     * called from drive_init.
+     *
+     * For now, simply forbidding the combination for all drivers will do. */
+    if (options->has_aio && options->aio == BLOCKDEV_A_I_O_OPTIONS_NATIVE) {
+        if (!options->has_cache || !options->cache->direct) {
+            error_setg(errp, "aio=native requires cache.direct=true");
+            return;
+        }
+    }
+
+    visit_type_BlockdevOptions(qmp_output_get_visitor(ov),
+                               &options, NULL, errp);
+    obj = qmp_output_get_qobject(ov);
+    qdict = qobject_to_qdict(obj);
+
+    qdict_flatten(qdict);
+
+    Error *local_err = NULL;
+    QemuOpts *opts = qemu_opts_from_qdict(&qemu_drive_opts, qdict, &local_err);
+    if (error_is_set(&local_err)) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+    } else {
+        blockdev_init(opts, IF_NONE);
+    }
+
+    qobject_decref(obj);
+    qmp_output_visitor_cleanup(ov);
+}
+
 static void do_qmp_query_block_jobs_one(void *opaque, BlockDriverState *bs)
 {
     BlockJobInfoList **prev = opaque;
diff --git a/qapi-schema.json b/qapi-schema.json
index 592bb9c..bfe6d32 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3761,3 +3761,296 @@
 ##
 { 'command': 'query-rx-filter', 'data': { '*name': 'str' },
   'returns': ['RxFilterInfo'] }
+
+
+##
+# @BlockdevDiscardOptions
+#
+# Determines how to handle discard requests.
+#
+# @ignore:      Ignore the request
+# @unmap:       Forward as an unmap request
+#
+# Since: 1.6
+##
+{ 'enum': 'BlockdevDiscardOptions',
+  'data': [ 'ignore', 'unmap' ] }
+
+##
+# @BlockdevDiscardOptions
+#
+# Selects the AIO backend to handle I/O requests
+#
+# @threads:     Use qemu's thread pool
+# @native:      Use native AIO backend (only Linux and Windows)
+#
+# Since: 1.6
+##
+{ 'enum': 'BlockdevAIOOptions',
+  'data': [ 'threads', 'native' ] }
+
+##
+# @BlockdevCacheOptions
+#
+# Includes cache-related options for block devices
+#
+# @writeback:   enables writeback mode for any caches (default: true)
+# @direct:      enables use of O_DIRECT (bypass the host page cache;
+#               default: false)
+# @no-flush:    ignore any flush requests for the device (default: false)
+#
+# Since: 1.6
+##
+{ 'type': 'BlockdevCacheOptions',
+  'data': { '*writeback': 'bool',
+            '*direct': 'bool',
+            '*no-flush': 'bool' } }
+
+##
+# @BlockdevThrottlingOptions
+#
+# Includes block device options related to I/O throttling. Leaving an option out
+# means the same as assigning 0 and applies no throttling.
+#
+# @bps-total:   limit total bytes per second
+# @bps-read:    limit read bytes per second
+# @bps-write:   limit written bytes per second
+# @iops-total:  limit total I/O operations per second
+# @iops-read:   limit read operations per second
+# @iops-write:  limit write operations per second
+#
+# Since: 1.6
+##
+{ 'type': 'BlockdevThrottlingOptions',
+  'data': { '*bps-total': 'int',
+            '*bps-read': 'int',
+            '*bps-write': 'int',
+            '*iops-total': 'int',
+            '*iops-read': 'int',
+            '*iops-write': 'int' } }
+
+##
+# @BlockdevOptionsBase
+#
+# Options that are available for all block devices, independent of the block
+# driver.
+#
+# @driver:      block driver name
+# @id:          id by which the new block device can be referred to
+# @discard:     discard-related options
+# @cache:       cache-related options
+# @aio:         AIO backend (default: threads)
+# @rerror:      how to handle read errors on the device (default: report)
+# @werror:      how to handle write errors on the device (default: enospc)
+# @throttling:  I/O throttling related options
+# @read-only:   whether the block device should be read-only (default: false)
+# @copy-on-read: whether to enable copy on read for the device (default: false)
+#
+# Since: 1.6
+##
+{ 'type': 'BlockdevOptionsBase',
+  'data': { 'driver': 'str',
+            '*id': 'str',
+            '*discard': 'BlockdevDiscardOptions',
+            '*cache': 'BlockdevCacheOptions',
+            '*aio':  'BlockdevAIOOptions',
+            '*rerror': 'BlockdevOnError',
+            '*werror': 'BlockdevOnError',
+            '*throttling': 'BlockdevThrottlingOptions',
+            '*read-only': 'bool',
+            '*copy-on-read': 'bool' } }
+
+##
+# @BlockdevOptionsFile
+#
+# Driver specific block device options for the file backend and similar
+# protocols.
+#
+# @filename:    path to the image file
+#
+# Since: 1.6
+##
+{ 'type': 'BlockdevOptionsFile',
+  'data': { 'filename': 'str' } }
+
+##
+# @BlockdevOptionsFile
+#
+# Driver specific block device options for the NBD protocol. Either path or host
+# must be specified.
+#
+# @path:        path to a unix domain socket
+# @host:        host name for a TCP connection
+# @port:        port number for a TCP connection (default: 10809)
+# @export:      NBD export name
+#
+# Since: 1.6
+##
+{ 'type': 'BlockdevOptionsNBD',
+  'data': { '*path': 'str', '*host': 'str', '*port': 'int', '*export': 'str' } }
+
+##
+# @BlockdevOptionsSSH
+#
+# Driver specific block device options for the SSH protocol.
+#
+# @host:        host name for a TCP connection
+# @port:        port number for a TCP connection (default: 22)
+# @path:        path to the image on the remote host
+# @user:        SSH user name
+#
+# @host-key-check:
+# TODO Should this be split into multiple fields for QMP?
+# TODO Driver takes host_key_check with underscores currently
+#
+# Since: 1.6
+##
+{ 'type': 'BlockdevOptionsSSH',
+  'data': { 'host': 'str', '*port': 'int', 'path': 'str', '*user': 'str',
+            '*host-key-check': 'str' } }
+
+##
+# @BlockdevOptionsVVFAT
+#
+# Driver specific block device options for the vvfat protocol.
+#
+# @dir:         directory to be exported as FAT image
+# @fat-type:    FAT type: 12, 16 or 32
+# @floppy:      whether to export a floppy imae (true) or partitioned hard disk
+#               (false; default)
+# @rw:          whether to allow write operations (default: false)
+#
+# Since: 1.6
+##
+{ 'type': 'BlockdevOptionsVVFAT',
+  'data': { 'dir': 'str', '*fat-type': 'int', '*floppy': 'bool',
+            '*rw': 'bool' } }
+
+##
+# @BlockdevOptionsGenericFormat
+#
+# Driver specific block device options for image format that have no option
+# besides their data source.
+#
+# @file:        reference to or definition of the data source block device
+#
+# Since: 1.6
+##
+{ 'type': 'BlockdevOptionsGenericFormat',
+  'data': { 'file': 'BlockdevRef' } }
+
+##
+# @BlockdevOptionsGenericCOWFormat
+#
+# Driver specific block device options for image format that have no option
+# besides their data source and an optional backing file.
+#
+# @file:        reference to or definition of the data source block device
+# @backing:     reference to or definition of the backing file block device
+#               (if missing, taken from the image file content)
+#
+# Since: 1.6
+##
+# TODO Add inheritance and base on BlockdevOptionsGenericFormat
+{ 'type': 'BlockdevOptionsGenericCOWFormat',
+  'data': { 'file': 'BlockdevRef', '*backing': 'BlockdevRef' } }
+
+##
+# @BlockdevOptionsGenericCOWFormat
+#
+# Driver specific block device options for qcow2.
+#
+# @file:        reference to or definition of the data source block device
+#
+# @backing:     reference to or definition of the backing file block device
+#               (if missing, taken from the image file content)
+#
+# @lazy-refcounts: whether to enable the lazy refcounts feature (default is
+#                  taken from the image file)
+#
+# @pass-discard-request: whether discard requests to the qcow2 device should
+#                        be forwarded to the data source
+#
+# @pass-discard-snapshot: whether discard requests for the data source should
+#                         be issued when a snapshot operation (e.g. deleting
+#                         a snapshot) frees clusters in the qcow2 file
+#
+# @pass-discard-other: whether discard requests for the data source should be
+#                      issued on other occasions where a cluster gets freed
+#
+# Since: 1.6
+##
+# TODO Add inheritance and base on BlockdevOptionsGenericCOWFormat
+{ 'type': 'BlockdevOptionsQcow2',
+  'data': { 'file': 'BlockdevRef',
+            '*backing': 'BlockdevRef',
+            '*lazy-refcounts': 'bool',
+            '*pass-discard-request': 'bool',
+            '*pass-discard-snapshot': 'bool',
+            '*pass-discard-other': 'bool' } }
+
+##
+# @BlockdevOptions
+#
+# Options for creating a block device.
+#
+# Since: 1.6
+##
+{ 'union': 'BlockdevOptions',
+  'base': 'BlockdevOptionsBase',
+  'discriminator': 'driver',
+  'data': {
+      'file':       'BlockdevOptionsFile',
+      'http':       'BlockdevOptionsFile',
+      'https':      'BlockdevOptionsFile',
+      'ftp':        'BlockdevOptionsFile',
+      'ftps':       'BlockdevOptionsFile',
+      'tftp':       'BlockdevOptionsFile',
+# TODO gluster: Wait for structured options
+# TODO iscsi: Wait for structured options
+# TODO nbd: Should take InetSocketAddress for 'host'?
+# TODO rbd: Wait for structured options
+# TODO sheepdog: Wait for structured options
+# TODO ssh: Should take InetSocketAddress for 'host'?
+      'vvfat':      'BlockdevOptionsVVFAT',
+
+      'bochs':      'BlockdevOptionsGenericFormat',
+      'cloop':      'BlockdevOptionsGenericFormat',
+      'cow':        'BlockdevOptionsGenericCOWFormat',
+      'dmg':        'BlockdevOptionsGenericFormat',
+      'parallels':  'BlockdevOptionsGenericFormat',
+      'qcow':       'BlockdevOptionsGenericCOWFormat',
+      'qcow2':      'BlockdevOptionsQcow2',
+      'qed':        'BlockdevOptionsGenericCOWFormat',
+      'raw':        'BlockdevOptionsGenericFormat',
+      'vdi':        'BlockdevOptionsGenericFormat',
+      'vhdx':       'BlockdevOptionsGenericFormat',
+      'vmdk':       'BlockdevOptionsGenericCOWFormat',
+      'vpc':        'BlockdevOptionsGenericFormat'
+  } }
+
+##
+# @BlockdevRef
+#
+# Reference to a block device.
+#
+# @definition:      defines a new block device inline
+# @reference:       references the ID of an existing block device
+#
+# Since: 1.6
+##
+{ 'union': 'BlockdevRef',
+  'discriminator': {},
+  'data': { 'definition': 'BlockdevOptions'
+            'reference': 'str' } }
+
+##
+# @blockdev-add:
+#
+# Creates a new block device.
+#
+# @options: block device options for the new device
+#
+# Since: 1.6
+##
+{ 'command': 'blockdev-add', 'data': { 'options': 'BlockdevOptions' } }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 65a9e26..96b0956 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3113,3 +3113,29 @@ Example:
    }
 
 EQMP
+
+    {
+        .name       = "blockdev-add",
+        .args_type  = "options:q",
+        .mhandler.cmd_new = qmp_marshal_input_blockdev_add,
+    },
+
+SQMP
+blockdev-add
+------------
+
+Add a block device.
+
+Arguments:
+
+- "options": block driver options
+
+Example:
+
+-> { "execute": "blockdev-add",
+    "arguments": { "options" : { "driver": "qcow2",
+                                 "file": { "driver": "file",
+                                           "filename": "test.qcow2" } } } }
+<- { "return": {} }
+
+EQMP
-- 
1.8.1.4

  parent reply	other threads:[~2013-07-23 13:04 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-23 13:03 [Qemu-devel] [PATCH 00/18] 'blockdev-add' QMP command Kevin Wolf
2013-07-23 13:03 ` [Qemu-devel] [PATCH 01/18] qapi-types.py: Split off generate_struct_fields() Kevin Wolf
2013-07-25 23:06   ` Eric Blake
2013-07-23 13:03 ` [Qemu-devel] [PATCH 02/18] qapi-types.py: Implement 'base' for unions Kevin Wolf
2013-07-25 23:12   ` Eric Blake
2013-08-21  3:38   ` Amos Kong
2013-08-27 15:58     ` Kevin Wolf
2013-08-29 13:52       ` Luiz Capitulino
2013-08-29 16:06         ` Kevin Wolf
2013-08-29 16:33           ` Luiz Capitulino
2013-08-29 16:50             ` Kevin Wolf
2013-08-29 17:02             ` Eric Blake
2013-08-29 18:36               ` Luiz Capitulino
2013-08-30  7:30                 ` Wenchao Xia
2013-07-23 13:03 ` [Qemu-devel] [PATCH 03/18] qapi-visit.py: Split off generate_visit_struct_fields() Kevin Wolf
2013-07-25 23:15   ` Eric Blake
2013-07-23 13:03 ` [Qemu-devel] [PATCH 04/18] qapi-visit.py: Implement 'base' for unions Kevin Wolf
2013-07-25 23:19   ` Eric Blake
2013-07-23 13:03 ` [Qemu-devel] [PATCH 05/18] docs: Document QAPI union types Kevin Wolf
2013-07-26 13:06   ` Eric Blake
2013-07-23 13:03 ` [Qemu-devel] [PATCH 06/18] qapi: Add visitor for implicit structs Kevin Wolf
2013-07-26 13:12   ` Eric Blake
2013-07-23 13:03 ` [Qemu-devel] [PATCH 07/18] qapi: Flat unions with arbitrary discriminator Kevin Wolf
2013-07-26 13:40   ` Eric Blake
2013-07-26 15:01     ` Kevin Wolf
2013-07-26 15:13       ` Eric Blake
2013-07-26 19:16   ` [Qemu-devel] [PATCH v2 07/17] " Kevin Wolf
2013-07-26 19:36     ` Eric Blake
2013-07-23 13:03 ` [Qemu-devel] [PATCH 08/18] qapi: Add consume argument to qmp_input_get_object() Kevin Wolf
2013-07-26 15:13   ` Eric Blake
2013-07-23 13:03 ` [Qemu-devel] [PATCH 09/18] qapi.py: Maintain a list of union types Kevin Wolf
2013-07-26 15:26   ` Eric Blake
2013-07-23 13:03 ` [Qemu-devel] [PATCH 10/18] qapi: Anonymous unions Kevin Wolf
2013-07-26 15:42   ` Eric Blake
2013-07-23 13:03 ` [Qemu-devel] [PATCH 11/18] block: Allow "driver" option on the top level Kevin Wolf
2013-07-26 16:00   ` Eric Blake
2013-07-23 13:03 ` [Qemu-devel] [PATCH 12/18] QemuOpts: Add qemu_opt_unset() Kevin Wolf
2013-07-26 16:04   ` Eric Blake
2013-07-23 13:03 ` [Qemu-devel] [PATCH 13/18] blockdev: Rename I/O throttling options for QMP Kevin Wolf
2013-07-26 16:10   ` Eric Blake
2013-07-26 16:26     ` Kevin Wolf
2013-07-26 16:44       ` Eric Blake
2013-07-26 16:54         ` Kevin Wolf
2013-07-26 17:01           ` Eric Blake
2013-07-26 19:35     ` Benoît Canet
2013-07-26 19:54       ` Eric Blake
2013-07-23 13:03 ` [Qemu-devel] [PATCH 14/18] qcow2: Use dashes instead of underscores in options Kevin Wolf
2013-07-26 16:17   ` Eric Blake
2013-07-23 13:03 ` [Qemu-devel] [PATCH 15/18] blockdev: Rename 'readonly' option to 'read-only' Kevin Wolf
2013-07-26 16:20   ` Eric Blake
2013-07-23 13:03 ` [Qemu-devel] [PATCH 16/18] blockdev: Split up 'cache' option Kevin Wolf
2013-07-26 16:30   ` Eric Blake
2013-07-23 13:03 ` [Qemu-devel] [PATCH 17/18] Implement qdict_flatten() Kevin Wolf
2013-07-26 16:40   ` Eric Blake
2013-07-26 17:03     ` Kevin Wolf
2013-07-23 13:03 ` Kevin Wolf [this message]
2013-07-26 17:45   ` [Qemu-devel] [PATCH 18/18] blockdev: 'blockdev-add' QMP command Eric Blake
2013-07-26 18:14     ` Kevin Wolf
2013-07-30 17:44       ` Luiz Capitulino
2013-07-31  8:09         ` Kevin Wolf
2013-08-30  7:41   ` Wenchao Xia

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=1374584606-5615-19-git-send-email-kwolf@redhat.com \
    --to=kwolf@redhat.com \
    --cc=armbru@redhat.com \
    --cc=lcapitulino@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.