Blame SOURCES/kvm-QMP-Forward-port-__com-redhat_drive_add-from-RHEL-6.patch

d81766
From 146a96db46f86b405c0eb346d3525c56192f00e7 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
d81766
index e6a1ffb..74cc578 100644
d81766
--- a/device-hotplug.c
d81766
+++ b/device-hotplug.c
d81766
@@ -79,3 +79,78 @@ err:
d81766
         drive_del(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
+    }
d81766
+    qemu_opt_set(opts, "if", "none");
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
d81766
index 23a5d10..9240adc 100644
d81766
--- a/include/sysemu/blockdev.h
d81766
+++ b/include/sysemu/blockdev.h
d81766
@@ -65,4 +65,6 @@ void qmp_change_blockdev(const char *device, const char *filename,
d81766
                          const char *format, Error **errp);
d81766
 void do_commit(Monitor *mon, const QDict *qdict);
d81766
 int do_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
d81766
index 68ffc94..b6080d5 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",