File libvirt-blockjob-support-both-RHEL-and-upstream-qemu-drive-mirror.patch of Package libvirt

From c254b7d8cc2ded536dcc0eb07251e3a24c6eed3f Mon Sep 17 00:00:00 2001
Message-Id: <c254b7d8cc2ded536dcc0eb07251e3a24c6eed3f.1351526126.git.jdenemar@redhat.com>
From: Eric Blake <eblake@redhat.com>
Date: Mon, 29 Oct 2012 08:50:54 -0600
Subject: [PATCH] blockjob: support both RHEL and upstream qemu drive-mirror

https://bugzilla.redhat.com/show_bug.cgi?id=871055
RHEL-only

We took RHEL-only patches for support block copy, because we were
unwilling to wait for upstream to commit to the interface at that
time.  However, now that some time has passed, upstream has now
committed to things (commit 5a3501b), but with a slightly
different set of patches than what we used for RHEL.

This patch resolves things to match the upstream commits, to make
any future backports of bug fixes easier.  It also follows the lead
of block-commit support in allowing both upstream and RHEL interfaces
(rather than forcing the RHEL interface), so that someone can install
upstream qemu 1.3 and still get RHEL libvirt to control the feature.

This is based on the following upstream post (although that post will
never be applied to upstream):
https://www.redhat.com/archives/libvir-list/2012-October/msg01623.html

* src/qemu/qemu_capabilities.c (qemuCapsProbeQMPCommands): No need
to check for drive-reopen any more.
* src/qemu/qemu_monitor_json.c (qemuMonitorJSONDriveMirror)
(qemuMonitorJSONDrivePivot): Handle both RHEL and upstream.
* src/qemu/qemu_monitor.c (qemuMonitorDriveMirror)
(qemuMonitorDrivePivot): Drop bool reopen argument.
* src/qemu/qemu_monitor_json.h: Likewise.
* src/qemu/qemu_monitor.h: Likewise.
* src/qemu/qemu_driver.c (qemuDomainBlockPivot)
(qemuDomainBlockCopy): Update callers.
---
 src/qemu/qemu_capabilities.c |  2 --
 src/qemu/qemu_driver.c       |  8 ++---
 src/qemu/qemu_monitor.c      | 16 +++++-----
 src/qemu/qemu_monitor.h      |  4 +--
 src/qemu/qemu_monitor_json.c | 75 +++++++++++++++++++++++++++-----------------
 src/qemu/qemu_monitor_json.h |  4 +--
 6 files changed, 59 insertions(+), 50 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index aca21a6..1094351 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1891,8 +1891,6 @@ qemuCapsProbeQMPCommands(qemuCapsPtr caps,
         else if (STREQ(name, "drive-mirror") ||
                  STREQ(name, "__com.redhat_drive-mirror"))
             qemuCapsSet(caps, QEMU_CAPS_DRIVE_MIRROR);
-        else if (STREQ(name, "__com.redhat_drive-reopen"))
-            qemuCapsSet(caps, QEMU_CAPS_DRIVE_REOPEN);
         VIR_FREE(name);
     }
     VIR_FREE(commands);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1a2bb4f..5250969 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -12555,7 +12555,6 @@ qemuDomainBlockPivot(virConnectPtr conn,
     int ret = -1;
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virDomainBlockJobInfo info;
-    bool reopen = qemuCapsGet(priv->caps, QEMU_CAPS_DRIVE_REOPEN);
     const char *format = virStorageFileFormatTypeToString(disk->mirrorFormat);
     bool resume = false;
     virCgroupPtr cgroup = NULL;
@@ -12651,8 +12650,7 @@ qemuDomainBlockPivot(virConnectPtr conn,
 
     /* Attempt the pivot.  */
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
-    ret = qemuMonitorDrivePivot(priv->mon, device, disk->mirror, format,
-                                reopen);
+    ret = qemuMonitorDrivePivot(priv->mon, device, disk->mirror, format);
     qemuDomainObjExitMonitorWithDriver(driver, vm);
 
     /* Note that RHEL 6.3 'drive-reopen' has the remote risk of a
@@ -12911,7 +12909,6 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path,
     virDomainDiskDefPtr disk;
     int ret = -1;
     int idx;
-    bool reopen;
     struct stat st;
     bool need_unlink = false;
     char *mirror = NULL;
@@ -12950,7 +12947,6 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path,
         goto cleanup;
     }
 
-    reopen = qemuCapsGet(priv->caps, QEMU_CAPS_DRIVE_REOPEN);
     if (!(qemuCapsGet(priv->caps, QEMU_CAPS_DRIVE_MIRROR) &&
           qemuCapsGet(priv->caps, QEMU_CAPS_BLOCKJOB_ASYNC))) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
@@ -13049,7 +13045,7 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path,
     /* Actually start the mirroring */
     qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorDriveMirror(priv->mon, device, dest, format, bandwidth,
-                                 reopen, flags);
+                                 flags);
     virDomainAuditDisk(vm, NULL, dest, "mirror", ret >= 0);
     qemuDomainObjExitMonitor(driver, vm);
     if (ret < 0) {
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index c54d84f..3bda4b5 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -2817,14 +2817,14 @@ int
 qemuMonitorDriveMirror(qemuMonitorPtr mon,
                        const char *device, const char *file,
                        const char *format, unsigned long bandwidth,
-                       bool reopen, unsigned int flags)
+                       unsigned int flags)
 {
     int ret = -1;
     unsigned long long speed;
 
     VIR_DEBUG("mon=%p, device=%s, file=%s, format=%s, bandwidth=%ld, "
-              "reopen=%d, flags=%x",
-              mon, device, file, NULLSTR(format), bandwidth, reopen, flags);
+              "flags=%x",
+              mon, device, file, NULLSTR(format), bandwidth, flags);
 
     /* Convert bandwidth MiB to bytes */
     speed = bandwidth;
@@ -2838,7 +2838,7 @@ qemuMonitorDriveMirror(qemuMonitorPtr mon,
 
     if (mon->json)
         ret = qemuMonitorJSONDriveMirror(mon, device, file, format, speed,
-                                         reopen, flags);
+                                         flags);
     else
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                        _("drive-mirror requires JSON monitor"));
@@ -2895,15 +2895,15 @@ qemuMonitorBlockCommit(qemuMonitorPtr mon, const char *device,
  * a block copy job.  */
 int
 qemuMonitorDrivePivot(qemuMonitorPtr mon, const char *device,
-                      const char *file, const char *format, bool reopen)
+                      const char *file, const char *format)
 {
     int ret = -1;
 
-    VIR_DEBUG("mon=%p, device=%s, file=%s, format=%s, reopen=%d",
-              mon, device, file, NULLSTR(format), reopen);
+    VIR_DEBUG("mon=%p, device=%s, file=%s, format=%s",
+              mon, device, file, NULLSTR(format));
 
     if (mon->json)
-        ret = qemuMonitorJSONDrivePivot(mon, device, file, format, reopen);
+        ret = qemuMonitorJSONDrivePivot(mon, device, file, format);
     else
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                        _("drive pivot requires JSON monitor"));
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 0bbeb6c..e4f0be9 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -533,14 +533,12 @@ int qemuMonitorDriveMirror(qemuMonitorPtr mon,
                            const char *file,
                            const char *format,
                            unsigned long bandwidth,
-                           bool reopen,
                            unsigned int flags)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
 int qemuMonitorDrivePivot(qemuMonitorPtr mon,
                           const char *device,
                           const char *file,
-                          const char *format,
-                          bool reopen)
+                          const char *format)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
 
 int qemuMonitorBlockCommit(qemuMonitorPtr mon,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 2df9781..40aacde 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -3399,7 +3399,7 @@ int
 qemuMonitorJSONDriveMirror(qemuMonitorPtr mon,
                            const char *device, const char *file,
                            const char *format, unsigned long long speed,
-                           bool reopen, unsigned int flags)
+                           unsigned int flags)
 {
     int ret = -1;
     virJSONValuePtr cmd;
@@ -3407,7 +3407,26 @@ qemuMonitorJSONDriveMirror(qemuMonitorPtr mon,
     bool shallow = (flags & VIR_DOMAIN_BLOCK_REBASE_SHALLOW) != 0;
     bool reuse = (flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT) != 0;
 
-    if (reopen)
+    cmd = qemuMonitorJSONMakeCommand("drive-mirror",
+                                     "s:device", device,
+                                     "s:target", file,
+                                     "U:speed", speed,
+                                     "s:sync", shallow ? "top" : "full",
+                                     "s:mode",
+                                     reuse ? "existing" : "absolute-paths",
+                                     format ? "s:format" : NULL, format,
+                                     NULL);
+    if (!cmd)
+        return -1;
+
+    if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
+        goto cleanup;
+    if (qemuMonitorJSONHasError(reply, "CommandNotFound")) {
+        VIR_DEBUG("block-job-complete command not found, trying RHEL version");
+        virJSONValueFree(cmd);
+        virJSONValueFree(reply);
+        reply = NULL;
+        ret = -1;
         cmd = qemuMonitorJSONMakeCommand("__com.redhat_drive-mirror",
                                          "s:device", device,
                                          "s:target", file,
@@ -3417,21 +3436,11 @@ qemuMonitorJSONDriveMirror(qemuMonitorPtr mon,
                                          reuse ? "existing" : "absolute-paths",
                                          format ? "s:format" : NULL, format,
                                          NULL);
-    else
-        cmd = qemuMonitorJSONMakeCommand("drive-mirror",
-                                         "s:device", device,
-                                         "s:target", file,
-                                         "U:speed", speed,
-                                         "s:sync", shallow ? "top" : "full",
-                                         "s:mode",
-                                         reuse ? "existing" : "absolute-paths",
-                                         format ? "s:format" : NULL, format,
-                                         NULL);
-    if (!cmd)
-        return -1;
-
-    if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
-        goto cleanup;
+        if (!cmd)
+            goto cleanup;
+        if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
+            goto cleanup;
+    }
     ret = qemuMonitorJSONCheckError(cmd, reply);
 
 cleanup:
@@ -3494,6 +3503,7 @@ qemuMonitorJSONBlockCommit(qemuMonitorPtr mon, const char *device,
         virJSONValueFree(cmd);
         virJSONValueFree(reply);
         reply = NULL;
+        ret = -1;
         cmd = qemuMonitorJSONMakeCommand("__com.redhat_block-commit",
                                          "s:device", device,
                                          "U:speed", speed,
@@ -3515,27 +3525,36 @@ cleanup:
 
 int
 qemuMonitorJSONDrivePivot(qemuMonitorPtr mon, const char *device,
-                          const char *file, const char *format, bool reopen)
+                          const char *file, const char *format)
 {
     int ret;
     virJSONValuePtr cmd;
     virJSONValuePtr reply = NULL;
 
-    if (reopen)
-        cmd = qemuMonitorJSONMakeCommand("__com.redhat_drive-reopen",
-                                         "s:device", device,
-                                         "s:new-image-file", file,
-                                         format ? "s:format" : NULL, format,
-                                         NULL);
-    else
-        cmd = qemuMonitorJSONMakeCommand("block-job-complete",
-                                         "s:device", device,
-                                         NULL);
+    cmd = qemuMonitorJSONMakeCommand("block-job-complete",
+                                     "s:device", device,
+                                     NULL);
     if (!cmd)
         return -1;
 
     if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
         goto cleanup;
+    if (qemuMonitorJSONHasError(reply, "CommandNotFound")) {
+        VIR_DEBUG("block-job-complete command not found, trying RHEL version");
+        virJSONValueFree(cmd);
+        virJSONValueFree(reply);
+        reply = NULL;
+        ret = -1;
+        cmd = qemuMonitorJSONMakeCommand("__com.redhat_drive-reopen",
+                                         "s:device", device,
+                                         "s:new-image-file", file,
+                                         format ? "s:format" : NULL, format,
+                                         NULL);
+        if (!cmd)
+            goto cleanup;
+        if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
+            goto cleanup;
+    }
     ret = qemuMonitorJSONCheckError(cmd, reply);
 
 cleanup:
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 8d8dc43..0966a76 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -247,14 +247,12 @@ int qemuMonitorJSONDriveMirror(qemuMonitorPtr mon,
                                const char *file,
                                const char *format,
                                unsigned long long speed,
-                               bool reopen,
                                unsigned int flags)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
 int qemuMonitorJSONDrivePivot(qemuMonitorPtr mon,
                               const char *device,
                               const char *file,
-                              const char *format,
-                              bool reopen)
+                              const char *format)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
 
 int qemuMonitorJSONBlockCommit(qemuMonitorPtr mon,
-- 
1.7.12.4

openSUSE Build Service is sponsored by