982648
From 8bac3f7591f7df980a631deeb67a2f20eab6fc62 Mon Sep 17 00:00:00 2001
982648
Message-Id: <8bac3f7591f7df980a631deeb67a2f20eab6fc62@dist-git>
6d3351
From: Jiri Denemark <jdenemar@redhat.com>
6d3351
Date: Tue, 5 Apr 2016 09:14:09 +0200
6d3351
Subject: [PATCH] RHEL: Support virtio disk hotplug in JSON mode
6d3351
6d3351
RHEL only, no upstream
6d3351
6d3351
For bug
6d3351
  https://bugzilla.redhat.com/show_bug.cgi?id=1026966
6d3351
  https://bugzilla.redhat.com/show_bug.cgi?id=573946
6d3351
6d3351
The existing drive_add command can hotplug SCSI and VirtIO
6d3351
disks, but this isn't ported to JSON mode. RHEL6 introduces
6d3351
a custom __com.redhat_drive_add that only supports VirtIO
6d3351
disks. Switch the VirtIO hotplug to this command, but leave
6d3351
the SCSI hotplug using old command so SCSI gets an explicit
6d3351
error about being unsupported.
6d3351
6d3351
* src/libvirt_private.syms: Export virJSONValueObjectRemoveKey
6d3351
* src/util/json.c, src/util/json.h: Add virJSONValueObjectRemoveKey
6d3351
  to allow a key to be deleted from an object
6d3351
* src/qemu/qemu_monitor_json.c: Try __com.redhat_drive_add first and use
6d3351
  drive_add only if the redhat command is not known to qemu.
6d3351
6d3351
Also includes the following fix:
6d3351
6d3351
https://bugzilla.redhat.com/show_bug.cgi?id=696596
6d3351
6d3351
Upstream added drive_del as a way to ensure that disks are fully
6d3351
removed before returning control to libvirt.  But RHEL backported
6d3351
it as __com.redhat_drive_del, prior to upstream adoption of a
6d3351
QMP counterpart.  Because we weren't trying the RHEL-specific
6d3351
spelling, we were falling back to the unsafe approach of just
6d3351
removing the device and hoping for the best, which was racy and
6d3351
could occasionally result in a rapid hot-plug cycle trying to
6d3351
plug in a new disk that collides with the old disk not yet gone.
6d3351
6d3351
* src/qemu/qemu_monitor_json.c (qemuMonitorJSONDriveDel): Try
6d3351
rhel-specific drive_del monitor command first.
6d3351
6d3351
(cherry picked from commit d1c200dfead14a590a4ddebe20a20ffe441d2b24 in
6d3351
rhel-6.5 branch)
6d3351
6d3351
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
6d3351
6d3351
Conflicts:
6d3351
	src/libvirt_private.syms - the change is already upstream
6d3351
        src/util/virjson.[ch] - the change is already upstream
6d3351
	src/qemu/qemu_monitor_json.c - context; upstream doesn't try to
6d3351
	    call nonexistent drive_{add,del} QMP commands any more
6d3351
---
982648
 src/qemu/qemu_monitor.c      |  12 ++--
982648
 src/qemu/qemu_monitor_json.c | 107 +++++++++++++++++++++++++++++++++++
982648
 src/qemu/qemu_monitor_json.h |   6 ++
982648
 tests/qemuhotplugtest.c      |  93 +++++++++++++++++++++++++++++-
982648
 4 files changed, 212 insertions(+), 6 deletions(-)
6d3351
6d3351
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
982648
index 6fc038a8d9..5e0e95cc51 100644
6d3351
--- a/src/qemu/qemu_monitor.c
6d3351
+++ b/src/qemu/qemu_monitor.c
982648
@@ -2947,8 +2947,10 @@ qemuMonitorDriveDel(qemuMonitorPtr mon,
6d3351
 
6d3351
     QEMU_CHECK_MONITOR(mon);
6d3351
 
6d3351
-    /* there won't be a direct replacement for drive_del in QMP */
6d3351
-    return qemuMonitorTextDriveDel(mon, drivestr);
6d3351
+    if (mon->json)
6d3351
+        return qemuMonitorJSONDriveDel(mon, drivestr);
6d3351
+    else
6d3351
+        return qemuMonitorTextDriveDel(mon, drivestr);
6d3351
 }
6d3351
 
6d3351
 
982648
@@ -3137,8 +3139,10 @@ qemuMonitorAddDrive(qemuMonitorPtr mon,
6d3351
 
6d3351
     QEMU_CHECK_MONITOR(mon);
6d3351
 
6d3351
-    /* there won't ever be a direct QMP replacement for this function */
6d3351
-    return qemuMonitorTextAddDrive(mon, drivestr);
6d3351
+    if (mon->json)
6d3351
+        return qemuMonitorJSONAddDrive(mon, drivestr);
6d3351
+    else
6d3351
+        return qemuMonitorTextAddDrive(mon, drivestr);
6d3351
 }
6d3351
 
6d3351
 
6d3351
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
982648
index af754e870e..ec8469476e 100644
6d3351
--- a/src/qemu/qemu_monitor_json.c
6d3351
+++ b/src/qemu/qemu_monitor_json.c
982648
@@ -4055,6 +4055,113 @@ int qemuMonitorJSONDelObject(qemuMonitorPtr mon,
6d3351
 }
6d3351
 
6d3351
 
6d3351
+int qemuMonitorJSONAddDrive(qemuMonitorPtr mon,
6d3351
+                            const char *drivestr)
6d3351
+{
6d3351
+    int ret = -1;
6d3351
+    virJSONValuePtr cmd;
6d3351
+    virJSONValuePtr reply = NULL;
6d3351
+    virJSONValuePtr args;
6d3351
+
6d3351
+    cmd = qemuMonitorJSONMakeCommand("__com.redhat_drive_add",
6d3351
+                                     NULL);
6d3351
+    if (!cmd)
6d3351
+        return -1;
6d3351
+
6d3351
+    args = qemuMonitorJSONKeywordStringToJSON(drivestr, "type");
6d3351
+    if (!args)
6d3351
+        goto cleanup;
6d3351
+
6d3351
+    /* __com.redhat_drive_add rejects the 'if' key */
6d3351
+    virJSONValueObjectRemoveKey(args, "if", NULL);
6d3351
+
6d3351
+    if (virJSONValueObjectAppend(cmd, "arguments", args) < 0) {
6d3351
+        virReportOOMError();
6d3351
+        goto cleanup;
6d3351
+    }
6d3351
+    args = NULL; /* cmd owns reference to args now */
6d3351
+
6d3351
+    if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
6d3351
+        goto cleanup;
6d3351
+
6d3351
+    if (qemuMonitorJSONHasError(reply, "CommandNotFound")) {
6d3351
+        virJSONValueFree(cmd);
6d3351
+        virJSONValueFree(reply);
6d3351
+        cmd = reply = NULL;
6d3351
+
6d3351
+        VIR_DEBUG("__com.redhat_drive_add command not found,"
6d3351
+                  " trying upstream way");
6d3351
+    } else {
6d3351
+        ret = qemuMonitorJSONCheckError(cmd, reply);
6d3351
+        goto cleanup;
6d3351
+    }
6d3351
+
6d3351
+    /* Upstream approach */
6d3351
+    /* there won't be a direct replacement for drive_add in QMP */
6d3351
+    ret = qemuMonitorTextAddDrive(mon, drivestr);
6d3351
+
6d3351
+ cleanup:
6d3351
+    virJSONValueFree(args);
6d3351
+    virJSONValueFree(cmd);
6d3351
+    virJSONValueFree(reply);
6d3351
+    return ret;
6d3351
+}
6d3351
+
6d3351
+
6d3351
+int qemuMonitorJSONDriveDel(qemuMonitorPtr mon,
6d3351
+                            const char *drivestr)
6d3351
+{
6d3351
+    int ret;
6d3351
+    virJSONValuePtr cmd;
6d3351
+    virJSONValuePtr reply = NULL;
6d3351
+
6d3351
+    VIR_DEBUG("drivestr=%s", drivestr);
6d3351
+    cmd = qemuMonitorJSONMakeCommand("__com.redhat_drive_del",
6d3351
+                                     "s:id", drivestr,
6d3351
+                                     NULL);
6d3351
+    if (!cmd)
6d3351
+        return -1;
6d3351
+
6d3351
+    if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
6d3351
+        goto cleanup;
6d3351
+
6d3351
+    if (qemuMonitorJSONHasError(reply, "CommandNotFound")) {
6d3351
+        virJSONValueFree(cmd);
6d3351
+        virJSONValueFree(reply);
6d3351
+        cmd = reply = NULL;
6d3351
+
6d3351
+        VIR_DEBUG("__com.redhat_drive_del command not found,"
6d3351
+                  " trying upstream way");
6d3351
+    } else if (qemuMonitorJSONHasError(reply, "DeviceNotFound")) {
6d3351
+        /* NB: device not found errors mean the drive was
6d3351
+         * auto-deleted and we ignore the error */
6d3351
+        ret = 0;
6d3351
+        goto cleanup;
6d3351
+    } else {
6d3351
+        ret = qemuMonitorJSONCheckError(cmd, reply);
6d3351
+        goto cleanup;
6d3351
+    }
6d3351
+
6d3351
+    /* Upstream approach */
6d3351
+    /* there won't be a direct replacement for drive_del in QMP */
6d3351
+    if ((ret = qemuMonitorTextDriveDel(mon, drivestr)) < 0) {
6d3351
+        virErrorPtr err = virGetLastError();
6d3351
+        if (err && err->code == VIR_ERR_OPERATION_UNSUPPORTED) {
6d3351
+            VIR_ERROR("%s",
6d3351
+                      _("deleting disk is not supported.  "
6d3351
+                        "This may leak data if disk is reassigned"));
6d3351
+            ret = 1;
6d3351
+            virResetLastError();
6d3351
+        }
6d3351
+    }
6d3351
+
6d3351
+ cleanup:
6d3351
+    virJSONValueFree(cmd);
6d3351
+    virJSONValueFree(reply);
6d3351
+    return ret;
6d3351
+}
6d3351
+
982648
+
982648
 int
982648
 qemuMonitorJSONDiskSnapshot(qemuMonitorPtr mon, virJSONValuePtr actions,
982648
                             const char *device, const char *file,
6d3351
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
982648
index b92fc3762b..9c8fab7cc0 100644
6d3351
--- a/src/qemu/qemu_monitor_json.h
6d3351
+++ b/src/qemu/qemu_monitor_json.h
982648
@@ -238,6 +238,12 @@ int qemuMonitorJSONAddObject(qemuMonitorPtr mon,
6d3351
 int qemuMonitorJSONDelObject(qemuMonitorPtr mon,
6d3351
                              const char *objalias);
6d3351
 
6d3351
+int qemuMonitorJSONAddDrive(qemuMonitorPtr mon,
6d3351
+                            const char *drivestr);
6d3351
+
6d3351
+int qemuMonitorJSONDriveDel(qemuMonitorPtr mon,
6d3351
+                            const char *drivestr);
6d3351
+
982648
 int qemuMonitorJSONDiskSnapshot(qemuMonitorPtr mon,
982648
                                 virJSONValuePtr actions,
982648
                                 const char *device,
6d3351
diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c
982648
index 663e33ed00..cddedf768e 100644
6d3351
--- a/tests/qemuhotplugtest.c
6d3351
+++ b/tests/qemuhotplugtest.c
982648
@@ -665,6 +665,14 @@ mymain(void)
982648
     "    }" \
6d3351
     "}\r\n"
6d3351
 
6d3351
+#define QMP_NOT_FOUND \
6d3351
+    "{" \
6d3351
+    "    \"error\": {" \
6d3351
+    "        \"class\": \"CommandNotFound\"," \
6d3351
+    "        \"desc\": \"The command has not been found\"" \
6d3351
+    "    }" \
6d3351
+    "}"
6d3351
+
6d3351
     DO_TEST_UPDATE("graphics-spice", "graphics-spice-nochange", false, false, NULL);
6d3351
     DO_TEST_UPDATE("graphics-spice-timeout", "graphics-spice-timeout-nochange", false, false,
6d3351
                    "set_password", QMP_OK, "expire_password", QMP_OK);
982648
@@ -685,67 +693,135 @@ mymain(void)
6d3351
                    "chardev-remove", QMP_OK);
6d3351
 
6d3351
     DO_TEST_ATTACH("base-live", "disk-virtio", false, true,
6d3351
+                   "__com.redhat_drive_add", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP("OK\\r\\n"),
6d3351
                    "device_add", QMP_OK);
6d3351
     DO_TEST_DETACH("base-live", "disk-virtio", false, false,
6d3351
                    "device_del", QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP(""));
6d3351
 
6d3351
+    DO_TEST_ATTACH("base-live", "disk-virtio", false, true,
6d3351
+                   "__com.redhat_drive_add", QMP_OK,
6d3351
+                   "device_add", QMP_OK);
6d3351
+    DO_TEST_DETACH("base-live", "disk-virtio", false, false,
6d3351
+                   "device_del", QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_OK);
6d3351
+
6d3351
     DO_TEST_ATTACH_EVENT("base-live", "disk-virtio", false, true,
6d3351
+                         "__com.redhat_drive_add", QMP_NOT_FOUND,
6d3351
                          "human-monitor-command", HMP("OK\\r\\n"),
6d3351
                          "device_add", QMP_OK);
6d3351
     DO_TEST_DETACH("base-live", "disk-virtio", true, true,
6d3351
                    "device_del", QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP(""));
6d3351
     DO_TEST_DETACH("base-live", "disk-virtio", false, false,
6d3351
                    "device_del", QMP_DEVICE_DELETED("virtio-disk4") QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP(""));
6d3351
 
6d3351
+    DO_TEST_ATTACH_EVENT("base-live", "disk-virtio", false, true,
6d3351
+                         "__com.redhat_drive_add", QMP_OK,
6d3351
+                         "device_add", QMP_OK);
6d3351
+    DO_TEST_DETACH("base-live", "disk-virtio", true, true,
6d3351
+                   "device_del", QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_OK);
6d3351
+    DO_TEST_DETACH("base-live", "disk-virtio", false, false,
6d3351
+                   "device_del", QMP_DEVICE_DELETED("virtio-disk4") QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_OK);
6d3351
+
6d3351
     DO_TEST_ATTACH("base-live", "disk-usb", false, true,
6d3351
+                   "__com.redhat_drive_add", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP("OK\\r\\n"),
6d3351
                    "device_add", QMP_OK);
6d3351
     DO_TEST_DETACH("base-live", "disk-usb", false, false,
6d3351
                    "device_del", QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP(""));
6d3351
 
6d3351
+    DO_TEST_ATTACH("base-live", "disk-usb", false, true,
6d3351
+                   "__com.redhat_drive_add", QMP_OK,
6d3351
+                   "device_add", QMP_OK);
6d3351
+    DO_TEST_DETACH("base-live", "disk-usb", false, false,
6d3351
+                   "device_del", QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_OK);
6d3351
+
6d3351
     DO_TEST_ATTACH_EVENT("base-live", "disk-usb", false, true,
6d3351
+                         "__com.redhat_drive_add", QMP_NOT_FOUND,
6d3351
                          "human-monitor-command", HMP("OK\\r\\n"),
6d3351
                          "device_add", QMP_OK);
6d3351
     DO_TEST_DETACH("base-live", "disk-usb", true, true,
6d3351
                    "device_del", QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP(""));
6d3351
     DO_TEST_DETACH("base-live", "disk-usb", false, false,
6d3351
                    "device_del", QMP_DEVICE_DELETED("usb-disk16") QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP(""));
6d3351
 
6d3351
+    DO_TEST_ATTACH_EVENT("base-live", "disk-usb", false, true,
6d3351
+                         "__com.redhat_drive_add", QMP_OK,
6d3351
+                         "device_add", QMP_OK);
6d3351
+    DO_TEST_DETACH("base-live", "disk-usb", true, true,
6d3351
+                   "device_del", QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_OK);
6d3351
+    DO_TEST_DETACH("base-live", "disk-usb", false, false,
6d3351
+                   "device_del", QMP_DEVICE_DELETED("usb-disk16") QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_OK);
6d3351
+
6d3351
     DO_TEST_ATTACH("base-live", "disk-scsi", false, true,
6d3351
+                   "__com.redhat_drive_add", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP("OK\\r\\n"),
6d3351
                    "device_add", QMP_OK);
6d3351
     DO_TEST_DETACH("base-live", "disk-scsi", false, false,
6d3351
                    "device_del", QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP(""));
6d3351
 
6d3351
+    DO_TEST_ATTACH("base-live", "disk-scsi", false, true,
6d3351
+                   "__com.redhat_drive_add", QMP_OK,
6d3351
+                   "device_add", QMP_OK);
6d3351
+    DO_TEST_DETACH("base-live", "disk-scsi", false, false,
6d3351
+                   "device_del", QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_OK);
6d3351
+
6d3351
     DO_TEST_ATTACH_EVENT("base-live", "disk-scsi", false, true,
6d3351
+                         "__com.redhat_drive_add", QMP_NOT_FOUND,
6d3351
                          "human-monitor-command", HMP("OK\\r\\n"),
6d3351
                          "device_add", QMP_OK);
6d3351
     DO_TEST_DETACH("base-live", "disk-scsi", true, true,
6d3351
                    "device_del", QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP(""));
6d3351
     DO_TEST_DETACH("base-live", "disk-scsi", false, false,
6d3351
                    "device_del", QMP_DEVICE_DELETED("scsi0-0-0-5") QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP(""));
6d3351
 
6d3351
+    DO_TEST_ATTACH_EVENT("base-live", "disk-scsi", false, true,
6d3351
+                         "__com.redhat_drive_add", QMP_OK,
6d3351
+                         "device_add", QMP_OK);
6d3351
+    DO_TEST_DETACH("base-live", "disk-scsi", true, true,
6d3351
+                   "device_del", QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_OK);
6d3351
+    DO_TEST_DETACH("base-live", "disk-scsi", false, false,
6d3351
+                   "device_del", QMP_DEVICE_DELETED("scsi0-0-0-5") QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_OK);
6d3351
+
6d3351
     DO_TEST_ATTACH("base-without-scsi-controller-live", "disk-scsi-2", false, true,
6d3351
                    /* Four controllers added */
6d3351
                    "device_add", QMP_OK,
6d3351
                    "device_add", QMP_OK,
6d3351
                    "device_add", QMP_OK,
6d3351
                    "device_add", QMP_OK,
6d3351
-                   "human-monitor-command", HMP("OK\\r\\n"),
6d3351
                    /* Disk added */
6d3351
+                   "__com.redhat_drive_add", QMP_NOT_FOUND,
6d3351
+                   "human-monitor-command", HMP("OK\\r\\n"),
6d3351
                    "device_add", QMP_OK);
6d3351
     DO_TEST_DETACH("base-with-scsi-controller-live", "disk-scsi-2", false, false,
6d3351
                    "device_del", QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP(""));
6d3351
 
6d3351
     DO_TEST_ATTACH_EVENT("base-without-scsi-controller-live", "disk-scsi-2", false, true,
982648
@@ -754,14 +830,17 @@ mymain(void)
6d3351
                          "device_add", QMP_OK,
6d3351
                          "device_add", QMP_OK,
6d3351
                          "device_add", QMP_OK,
6d3351
-                         "human-monitor-command", HMP("OK\\r\\n"),
6d3351
                          /* Disk added */
6d3351
+                         "__com.redhat_drive_add", QMP_NOT_FOUND,
6d3351
+                         "human-monitor-command", HMP("OK\\r\\n"),
6d3351
                          "device_add", QMP_OK);
6d3351
     DO_TEST_DETACH("base-with-scsi-controller-live", "disk-scsi-2", true, true,
6d3351
                    "device_del", QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP(""));
6d3351
     DO_TEST_DETACH("base-with-scsi-controller-live", "disk-scsi-2", false, false,
6d3351
                    "device_del", QMP_DEVICE_DELETED("scsi3-0-5-7") QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP(""));
6d3351
 
6d3351
     DO_TEST_ATTACH("base-live", "qemu-agent", false, true,
982648
@@ -772,38 +851,47 @@ mymain(void)
6d3351
                    "chardev-remove", QMP_OK);
6d3351
 
6d3351
     DO_TEST_ATTACH("base-ccw-live", "ccw-virtio", false, true,
6d3351
+                   "__com.redhat_drive_add", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP("OK\\r\\n"),
6d3351
                    "device_add", QMP_OK);
6d3351
     DO_TEST_DETACH("base-ccw-live", "ccw-virtio", false, false,
6d3351
                    "device_del", QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP(""));
6d3351
 
6d3351
     DO_TEST_ATTACH("base-ccw-live-with-ccw-virtio", "ccw-virtio-2", false, true,
6d3351
+                   "__com.redhat_drive_add", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP("OK\\r\\n"),
6d3351
                    "device_add", QMP_OK);
6d3351
 
6d3351
     DO_TEST_DETACH("base-ccw-live-with-ccw-virtio", "ccw-virtio-2", false, false,
6d3351
                    "device_del", QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP(""));
6d3351
 
6d3351
     DO_TEST_ATTACH("base-ccw-live-with-ccw-virtio", "ccw-virtio-2-explicit", false, true,
6d3351
+                   "__com.redhat_drive_add", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP("OK\\r\\n"),
6d3351
                    "device_add", QMP_OK);
6d3351
 
6d3351
     DO_TEST_DETACH("base-ccw-live-with-ccw-virtio", "ccw-virtio-2-explicit", false, false,
6d3351
                    "device_del", QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP(""));
6d3351
 
6d3351
     /* Attach a second device, then detach the first one. Then attach the first one again. */
6d3351
     DO_TEST_ATTACH("base-ccw-live-with-ccw-virtio", "ccw-virtio-2-explicit", false, true,
6d3351
+                   "__com.redhat_drive_add", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP("OK\\r\\n"),
6d3351
                    "device_add", QMP_OK);
6d3351
 
6d3351
     DO_TEST_DETACH("base-ccw-live-with-2-ccw-virtio", "ccw-virtio-1-explicit", false, true,
6d3351
                    "device_del", QMP_OK,
6d3351
+                   "__com.redhat_drive_del", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP(""));
6d3351
 
6d3351
     DO_TEST_ATTACH("base-ccw-live-with-2-ccw-virtio", "ccw-virtio-1-reverse", false, false,
6d3351
+                   "__com.redhat_drive_add", QMP_NOT_FOUND,
6d3351
                    "human-monitor-command", HMP("OK\\r\\n"),
6d3351
                    "device_add", QMP_OK);
6d3351
 
982648
@@ -821,6 +909,7 @@ mymain(void)
c1c534
                    "object-del", QMP_OK);
c1c534
     DO_TEST_ATTACH("base-live+disk-scsi-wwn",
c1c534
                    "disk-scsi-duplicate-wwn", false, false,
c1c534
+                   "__com.redhat_drive_add", QMP_NOT_FOUND,
c1c534
                    "human-monitor-command", HMP("OK\\r\\n"),
c1c534
                    "device_add", QMP_OK);
c1c534
 
6d3351
-- 
982648
2.18.0
6d3351