|
|
8be556 |
From c466d0a410e2618c6a69ec4d7179ea5be97121a5 Mon Sep 17 00:00:00 2001
|
|
|
d81766 |
From: Markus Armbruster <armbru@redhat.com>
|
|
|
d81766 |
Date: Tue, 17 Dec 2013 06:46:36 +0100
|
|
|
d81766 |
Subject: QMP: Forward-port __com.redhat_drive_add from RHEL-6
|
|
|
d81766 |
|
|
|
d81766 |
RH-Author: Markus Armbruster <armbru@redhat.com>
|
|
|
d81766 |
Message-id: <1387262799-10350-4-git-send-email-armbru@redhat.com>
|
|
|
d81766 |
Patchwork-id: 56294
|
|
|
d81766 |
O-Subject: [PATCH v2 3/6] QMP: Forward-port __com.redhat_drive_add from RHEL-6
|
|
|
d81766 |
Bugzilla: 889051
|
|
|
d81766 |
RH-Acked-by: Fam Zheng <famz@redhat.com>
|
|
|
d81766 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
d81766 |
RH-Acked-by: Luiz Capitulino <lcapitulino@redhat.com>
|
|
|
d81766 |
|
|
|
d81766 |
From: Markus Armbruster <armbru@redhat.com>
|
|
|
d81766 |
|
|
|
d81766 |
Code taken from RHEL-6 as of qemu-kvm-0.12.1.2-2.418.el6, backported
|
|
|
d81766 |
and fixed up as follows:
|
|
|
d81766 |
|
|
|
d81766 |
* Update simple_drive_add() for commit 4e89978 "qemu-option:
|
|
|
d81766 |
qemu_opts_from_qdict(): use error_set()".
|
|
|
d81766 |
|
|
|
d81766 |
* Update simple_drive_add() for commit 2d0d283 "Support default block
|
|
|
d81766 |
interfaces per QEMUMachine".
|
|
|
d81766 |
|
|
|
d81766 |
* Add comment explaining drive_init() error reporting hacks to
|
|
|
d81766 |
simple_drive_add().
|
|
|
d81766 |
|
|
|
d81766 |
* qemu-monitor.hx has been split into qmp-commands.hx and
|
|
|
d81766 |
hmp-commands.hx. Copy the QMP parts to qmp-commands.hx. Clean up
|
|
|
d81766 |
second example slightly.
|
|
|
d81766 |
|
|
|
d81766 |
* Trailing whitespace cleaned up.
|
|
|
d81766 |
|
|
|
d81766 |
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
|
|
d81766 |
|
|
|
d81766 |
diff --git a/device-hotplug.c b/device-hotplug.c
|
|
|
8be556 |
index 68b9496..7d4dc92 100644
|
|
|
d81766 |
--- a/device-hotplug.c
|
|
|
d81766 |
+++ b/device-hotplug.c
|
|
|
d81766 |
@@ -79,3 +79,78 @@ err:
|
|
|
8be556 |
blk_unref(blk_by_legacy_dinfo(dinfo));
|
|
|
d81766 |
}
|
|
|
d81766 |
}
|
|
|
d81766 |
+
|
|
|
d81766 |
+static void check_parm(const char *key, QObject *obj, void *opaque)
|
|
|
d81766 |
+{
|
|
|
d81766 |
+ static const char *valid_keys[] = {
|
|
|
d81766 |
+ "id", "cyls", "heads", "secs", "trans", "media", "snapshot",
|
|
|
d81766 |
+ "file", "cache", "aio", "format", "serial", "rerror", "werror",
|
|
|
d81766 |
+ "readonly", "copy-on-read",
|
|
|
d81766 |
+#ifdef CONFIG_BLOCK_IO_THROTTLING
|
|
|
d81766 |
+ "bps", "bps_rd", "bps_wr", "iops", "iops_rd", "iops_wr",
|
|
|
d81766 |
+#endif
|
|
|
d81766 |
+ NULL
|
|
|
d81766 |
+
|
|
|
d81766 |
+ };
|
|
|
d81766 |
+ int *stopped = opaque;
|
|
|
d81766 |
+ const char **p;
|
|
|
d81766 |
+
|
|
|
d81766 |
+ if (*stopped) {
|
|
|
d81766 |
+ return;
|
|
|
d81766 |
+ }
|
|
|
d81766 |
+
|
|
|
d81766 |
+ for (p = valid_keys; *p; p++) {
|
|
|
d81766 |
+ if (!strcmp(key, *p)) {
|
|
|
d81766 |
+ return;
|
|
|
d81766 |
+ }
|
|
|
d81766 |
+ }
|
|
|
d81766 |
+
|
|
|
d81766 |
+ qerror_report(QERR_INVALID_PARAMETER, key);
|
|
|
d81766 |
+ *stopped = 1;
|
|
|
d81766 |
+}
|
|
|
d81766 |
+
|
|
|
d81766 |
+int simple_drive_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
|
|
|
d81766 |
+{
|
|
|
d81766 |
+ int stopped;
|
|
|
d81766 |
+ Error *local_err = NULL;
|
|
|
d81766 |
+ QemuOpts *opts;
|
|
|
d81766 |
+ DriveInfo *dinfo;
|
|
|
d81766 |
+ MachineClass *mc;
|
|
|
d81766 |
+
|
|
|
d81766 |
+ if (!qdict_haskey(qdict, "id")) {
|
|
|
d81766 |
+ qerror_report(QERR_MISSING_PARAMETER, "id");
|
|
|
d81766 |
+ return -1;
|
|
|
d81766 |
+ }
|
|
|
d81766 |
+
|
|
|
d81766 |
+ stopped = 0;
|
|
|
d81766 |
+ qdict_iter(qdict, check_parm, &stopped);
|
|
|
d81766 |
+ if (stopped) {
|
|
|
d81766 |
+ return -1;
|
|
|
d81766 |
+ }
|
|
|
d81766 |
+
|
|
|
d81766 |
+ opts = qemu_opts_from_qdict(&qemu_drive_opts, qdict, &local_err);
|
|
|
d81766 |
+ if (!opts) {
|
|
|
d81766 |
+ qerror_report_err(local_err);
|
|
|
d81766 |
+ error_free(local_err);
|
|
|
d81766 |
+ return -1;
|
|
|
d81766 |
+ }
|
|
|
8be556 |
+ qemu_opt_set(opts, "if", "none", &error_abort);
|
|
|
d81766 |
+ mc = MACHINE_GET_CLASS(current_machine);
|
|
|
d81766 |
+ dinfo = drive_new(opts, mc->block_default_type);
|
|
|
d81766 |
+ if (!dinfo) {
|
|
|
d81766 |
+ /*
|
|
|
d81766 |
+ * drive_new() reports some errors with qerror_report_err(),
|
|
|
d81766 |
+ * and some with error_report(). The latter vanish without
|
|
|
d81766 |
+ * trace in monitor_vprintf(). See also the rather optimistic
|
|
|
d81766 |
+ * upstream commit 74ee59a. Emit a generic error here. If a
|
|
|
d81766 |
+ * prior error from qerror_report_err() is pending, it'll get
|
|
|
d81766 |
+ * ignored.
|
|
|
d81766 |
+ */
|
|
|
d81766 |
+ qerror_report(QERR_DEVICE_INIT_FAILED,
|
|
|
d81766 |
+ qemu_opts_id(opts));
|
|
|
d81766 |
+ qemu_opts_del(opts);
|
|
|
d81766 |
+ return -1;
|
|
|
d81766 |
+ }
|
|
|
d81766 |
+
|
|
|
d81766 |
+ return 0;
|
|
|
d81766 |
+}
|
|
|
d81766 |
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
|
|
|
8be556 |
index 7ca59b5..4478fc8 100644
|
|
|
d81766 |
--- a/include/sysemu/blockdev.h
|
|
|
d81766 |
+++ b/include/sysemu/blockdev.h
|
|
|
8be556 |
@@ -67,4 +67,6 @@ void qmp_change_blockdev(const char *device, const char *filename,
|
|
|
d81766 |
const char *format, Error **errp);
|
|
|
8be556 |
void hmp_commit(Monitor *mon, const QDict *qdict);
|
|
|
8be556 |
int hmp_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
|
|
|
d81766 |
+
|
|
|
d81766 |
+int simple_drive_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
|
|
|
d81766 |
#endif
|
|
|
d81766 |
diff --git a/qmp-commands.hx b/qmp-commands.hx
|
|
|
8be556 |
index 514ef73..6d47a99 100644
|
|
|
d81766 |
--- a/qmp-commands.hx
|
|
|
d81766 |
+++ b/qmp-commands.hx
|
|
|
d81766 |
@@ -106,6 +106,52 @@ Example:
|
|
|
d81766 |
Note: The "force" argument defaults to false.
|
|
|
d81766 |
|
|
|
d81766 |
EQMP
|
|
|
d81766 |
+ {
|
|
|
d81766 |
+ .name = RFQDN_REDHAT "drive_add",
|
|
|
d81766 |
+ .args_type = "simple-drive:O",
|
|
|
d81766 |
+ .params = "id=name,[file=file][,format=f][,media=d]...",
|
|
|
d81766 |
+ .help = "Create a drive similar to -device if=none.",
|
|
|
d81766 |
+ .user_print = monitor_user_noop,
|
|
|
d81766 |
+ .mhandler.cmd_new = simple_drive_add,
|
|
|
d81766 |
+ },
|
|
|
d81766 |
+
|
|
|
d81766 |
+SQMP
|
|
|
d81766 |
+__com.redhat_drive_add
|
|
|
d81766 |
+----------------------
|
|
|
d81766 |
+
|
|
|
d81766 |
+Create a drive similar to -device if=none.
|
|
|
d81766 |
+
|
|
|
d81766 |
+Arguments:
|
|
|
d81766 |
+
|
|
|
d81766 |
+- "id": Drive ID, must be unique (json-string)
|
|
|
d81766 |
+- "file": Disk image (json-string, optional)
|
|
|
d81766 |
+- "format": Disk format (json-string, optional)
|
|
|
d81766 |
+- "aio": How to perform asynchronous disk I/O (json-string, optional)
|
|
|
d81766 |
+- "cache": Host cache use policy (json-string, optional)
|
|
|
d81766 |
+- "cyls", "heads", "secs": Disk geometry (json-int, optional)
|
|
|
d81766 |
+- "trans": BIOS translation mode (json-string, optional)
|
|
|
d81766 |
+- "media": Media type (json-string, optional)
|
|
|
d81766 |
+- "readonly": Open image read-only (json-bool, optional)
|
|
|
d81766 |
+- "rerror": What to do on read error (json-string, optional)
|
|
|
d81766 |
+- "werror": What to do on write error (json-string, optional)
|
|
|
d81766 |
+- "serial": Drive serial number (json-string, optional)
|
|
|
d81766 |
+- "snapshot": Enable snapshot mode (json-bool, optional)
|
|
|
d81766 |
+- "copy-on-read": Enable copy-on-read mode (json-bool, optional)
|
|
|
d81766 |
+
|
|
|
d81766 |
+Example:
|
|
|
d81766 |
+
|
|
|
d81766 |
+1. Add a drive without medium:
|
|
|
d81766 |
+
|
|
|
d81766 |
+-> { "execute": "__com.redhat_drive_add", "arguments": { "id": "foo" } }
|
|
|
d81766 |
+<- {"return": {}}
|
|
|
d81766 |
+
|
|
|
d81766 |
+2. Add a drive with medium:
|
|
|
d81766 |
+
|
|
|
d81766 |
+-> { "execute": "__com.redhat_drive_add",
|
|
|
d81766 |
+ "arguments": { "id": "bar", "file": "tmp.qcow2", "format": "qcow2" } }
|
|
|
d81766 |
+<- {"return": {}}
|
|
|
d81766 |
+
|
|
|
d81766 |
+EQMP
|
|
|
d81766 |
|
|
|
d81766 |
{
|
|
|
d81766 |
.name = RFQDN_REDHAT "drive_del",
|