]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
blockjob: split out block info monitor handling
authorEric Blake <eblake@redhat.com>
Wed, 27 Aug 2014 19:29:14 +0000 (13:29 -0600)
committerEric Blake <eblake@redhat.com>
Fri, 5 Sep 2014 16:37:08 +0000 (10:37 -0600)
Another layer of overly-multiplexed code that deserves to be
split into obviously separate paths for query vs. modify.
This continues the cleanup started in commit cefe0ba.

In the process, make some tweaks to simplify the logic when
parsing the JSON reply.  There should be no user-visible
semantic changes.

* src/qemu/qemu_monitor.h (qemuMonitorBlockJob): Drop parameter.
(qemuMonitorBlockJobInfo): New prototype.
(BLOCK_JOB_INFO): Drop enum.
* src/qemu/qemu_monitor_json.h (qemuMonitorJSONBlockJob)
(qemuMonitorJSONBlockJobInfo): Likewise.
* src/qemu/qemu_monitor.c (qemuMonitorBlockJob): Split...
(qemuMonitorBlockJobInfo): ...into second function.
* src/qemu/qemu_monitor_json.c (qemuMonitorJSONBlockJob): Move
block info portions...
(qemuMonitorJSONGetBlockJobInfo): ...here, and rename...
(qemuMonitorJSONBlockJobInfo): ...and export.
(qemuMonitorJSONGetBlockJobInfoOne): Alter return semantics.
* src/qemu/qemu_driver.c (qemuDomainBlockPivot)
(qemuDomainBlockJobImpl, qemuDomainGetBlockJobInfo): Adjust
callers.
* src/qemu/qemu_migration.c (qemuMigrationDriveMirror)
(qemuMigrationCancelDriveMirror): Likewise.

Signed-off-by: Eric Blake <eblake@redhat.com>
src/qemu/qemu_driver.c
src/qemu/qemu_migration.c
src/qemu/qemu_monitor.c
src/qemu/qemu_monitor.h
src/qemu/qemu_monitor_json.c
src/qemu/qemu_monitor_json.h

index 3c046784f320df1b75e11b51ef97d3c54464c245..b893e38d59bca37415495de010e8ff93b0b48cf2 100644 (file)
@@ -14857,8 +14857,7 @@ qemuDomainBlockPivot(virConnectPtr conn,
     /* Probe the status, if needed.  */
     if (!disk->mirrorState) {
         qemuDomainObjEnterMonitor(driver, vm);
-        rc = qemuMonitorBlockJob(priv->mon, device, NULL, NULL, 0, &info,
-                                  BLOCK_JOB_INFO, true);
+        rc = qemuMonitorBlockJobInfo(priv->mon, device, &info);
         qemuDomainObjExitMonitor(driver, vm);
         if (rc < 0)
             goto cleanup;
@@ -15125,7 +15124,7 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
 
     qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorBlockJob(priv->mon, device, basePath, backingPath,
-                              bandwidth, NULL, mode, async);
+                              bandwidth, mode, async);
     qemuDomainObjExitMonitor(driver, vm);
     if (ret < 0) {
         if (mode == BLOCK_JOB_ABORT && disk->mirror)
@@ -15169,8 +15168,7 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
                 virDomainBlockJobInfo dummy;
 
                 qemuDomainObjEnterMonitor(driver, vm);
-                ret = qemuMonitorBlockJob(priv->mon, device, NULL, NULL, 0,
-                                          &dummy, BLOCK_JOB_INFO, async);
+                ret = qemuMonitorBlockJobInfo(priv->mon, device, &dummy);
                 qemuDomainObjExitMonitor(driver, vm);
 
                 if (ret <= 0)
@@ -15277,8 +15275,7 @@ qemuDomainGetBlockJobInfo(virDomainPtr dom, const char *path,
     disk = vm->def->disks[idx];
 
     qemuDomainObjEnterMonitor(driver, vm);
-    ret = qemuMonitorBlockJob(priv->mon, device, NULL, NULL, 0,
-                              info, BLOCK_JOB_INFO, true);
+    ret = qemuMonitorBlockJobInfo(priv->mon, device, info);
     qemuDomainObjExitMonitor(driver, vm);
     if (ret < 0)
         goto endjob;
index 9cfb77eb31379f8c9fe817feedb8cff126960b0c..9885a166eebbf990a17154b166339229eaf67c0d 100644 (file)
@@ -1307,8 +1307,7 @@ qemuMigrationDriveMirror(virQEMUDriverPtr driver,
                                _("canceled by client"));
                 goto error;
             }
-            mon_ret = qemuMonitorBlockJob(priv->mon, diskAlias, NULL, NULL, 0,
-                                          &info, BLOCK_JOB_INFO, true);
+            mon_ret = qemuMonitorBlockJobInfo(priv->mon, diskAlias, &info);
             qemuDomainObjExitMonitor(driver, vm);
 
             if (mon_ret < 0)
@@ -1361,7 +1360,7 @@ qemuMigrationDriveMirror(virQEMUDriverPtr driver,
         if (qemuDomainObjEnterMonitorAsync(driver, vm,
                                            QEMU_ASYNC_JOB_MIGRATION_OUT) == 0) {
             if (qemuMonitorBlockJob(priv->mon, diskAlias, NULL, NULL, 0,
-                                    NULL, BLOCK_JOB_ABORT, true) < 0) {
+                                    BLOCK_JOB_ABORT, true) < 0) {
                 VIR_WARN("Unable to cancel block-job on '%s'", diskAlias);
             }
             qemuDomainObjExitMonitor(driver, vm);
@@ -1428,7 +1427,7 @@ qemuMigrationCancelDriveMirror(qemuMigrationCookiePtr mig,
             goto cleanup;
 
         if (qemuMonitorBlockJob(priv->mon, diskAlias, NULL, NULL, 0,
-                                NULL, BLOCK_JOB_ABORT, true) < 0)
+                                BLOCK_JOB_ABORT, true) < 0)
             VIR_WARN("Unable to stop block job on %s", diskAlias);
         qemuDomainObjExitMonitor(driver, vm);
     }
index 5b2952aa442785c766e25f817acb11bf55911bd8..44930512c766428fd51d2fa62b3adc70fa811cb8 100644 (file)
@@ -3360,22 +3360,22 @@ int qemuMonitorScreendump(qemuMonitorPtr mon,
 }
 
 /* bandwidth is in MiB/sec */
-int qemuMonitorBlockJob(qemuMonitorPtr mon,
-                        const char *device,
-                        const char *base,
-                        const char *backingName,
-                        unsigned long bandwidth,
-                        virDomainBlockJobInfoPtr info,
-                        qemuMonitorBlockJobCmd mode,
-                        bool modern)
+int
+qemuMonitorBlockJob(qemuMonitorPtr mon,
+                    const char *device,
+                    const char *base,
+                    const char *backingName,
+                    unsigned long bandwidth,
+                    qemuMonitorBlockJobCmd mode,
+                    bool modern)
 {
     int ret = -1;
     unsigned long long speed;
 
     VIR_DEBUG("mon=%p, device=%s, base=%s, backingName=%s, bandwidth=%luM, "
-              "info=%p, mode=%o, modern=%d",
+              "mode=%o, modern=%d",
               mon, device, NULLSTR(base), NULLSTR(backingName),
-              bandwidth, info, mode, modern);
+              bandwidth, mode, modern);
 
     /* Convert bandwidth MiB to bytes - unfortunately the JSON QMP protocol is
      * limited to LLONG_MAX also for unsigned values */
@@ -3390,13 +3390,32 @@ int qemuMonitorBlockJob(qemuMonitorPtr mon,
 
     if (mon->json)
         ret = qemuMonitorJSONBlockJob(mon, device, base, backingName,
-                                      speed, info, mode, modern);
+                                      speed, mode, modern);
     else
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
                        _("block jobs require JSON monitor"));
     return ret;
 }
 
+
+int
+qemuMonitorBlockJobInfo(qemuMonitorPtr mon,
+                        const char *device,
+                        virDomainBlockJobInfoPtr info)
+{
+    int ret = -1;
+
+    VIR_DEBUG("mon=%p, device=%s, info=%p", mon, device, info);
+
+    if (mon->json)
+        ret = qemuMonitorJSONBlockJobInfo(mon, device, info);
+    else
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                       _("block jobs require JSON monitor"));
+    return ret;
+}
+
+
 int qemuMonitorSetBlockIoThrottle(qemuMonitorPtr mon,
                                   const char *device,
                                   virDomainBlockIoTuneInfoPtr info)
index 4fd6f01701bc830d8c7e2d2c29c7a6ceb98a55a6..c66b77e7fe638f3379ddac1607729c6eb46de5cd 100644 (file)
@@ -685,7 +685,6 @@ int qemuMonitorSendKey(qemuMonitorPtr mon,
 
 typedef enum {
     BLOCK_JOB_ABORT,
-    BLOCK_JOB_INFO,
     BLOCK_JOB_SPEED,
     BLOCK_JOB_PULL,
 } qemuMonitorBlockJobCmd;
@@ -695,11 +694,15 @@ int qemuMonitorBlockJob(qemuMonitorPtr mon,
                         const char *base,
                         const char *backingName,
                         unsigned long bandwidth,
-                        virDomainBlockJobInfoPtr info,
                         qemuMonitorBlockJobCmd mode,
                         bool modern)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
+int qemuMonitorBlockJobInfo(qemuMonitorPtr mon,
+                            const char *device,
+                            virDomainBlockJobInfoPtr info)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+
 int qemuMonitorOpenGraphics(qemuMonitorPtr mon,
                             const char *protocol,
                             int fd,
index 62e7d5d01656d6ba24cf2ec9f980c2419c4dcb19..2b58c7827ee5d7773886eeedca4a31c06a4cfa0c 100644 (file)
@@ -3684,9 +3684,11 @@ int qemuMonitorJSONScreendump(qemuMonitorPtr mon,
     return ret;
 }
 
-static int qemuMonitorJSONGetBlockJobInfoOne(virJSONValuePtr entry,
-                                              const char *device,
-                                              virDomainBlockJobInfoPtr info)
+/* Returns -1 on error, 0 if not the right device, 1 if info was populated.  */
+static int
+qemuMonitorJSONGetBlockJobInfoOne(virJSONValuePtr entry,
+                                  const char *device,
+                                  virDomainBlockJobInfoPtr info)
 {
     const char *this_dev;
     const char *type;
@@ -3698,7 +3700,7 @@ static int qemuMonitorJSONGetBlockJobInfoOne(virJSONValuePtr entry,
         return -1;
     }
     if (!STREQ(this_dev, device))
-        return -1;
+        return 0;
 
     type = virJSONValueObjectGetString(entry, "type");
     if (!type) {
@@ -3733,54 +3735,65 @@ static int qemuMonitorJSONGetBlockJobInfoOne(virJSONValuePtr entry,
                        _("entry was missing 'len'"));
         return -1;
     }
-    return 0;
+    return 1;
 }
 
-/** qemuMonitorJSONGetBlockJobInfo:
- * Parse Block Job information.
- * The reply is a JSON array of objects, one per active job.
+/**
+ * qemuMonitorJSONBlockJobInfo:
+ * Parse Block Job information, and populate info for the named device.
+ * Return 1 if info available, 0 if device has no block job, and -1 on error.
  */
-static int qemuMonitorJSONGetBlockJobInfo(virJSONValuePtr reply,
-                                           const char *device,
-                                           virDomainBlockJobInfoPtr info)
+int
+qemuMonitorJSONBlockJobInfo(qemuMonitorPtr mon,
+                            const char *device,
+                            virDomainBlockJobInfoPtr info)
 {
+    virJSONValuePtr cmd = NULL;
+    virJSONValuePtr reply = NULL;
     virJSONValuePtr data;
     int nr_results;
     size_t i;
+    int ret = -1;
 
-    if (!info)
+    cmd = qemuMonitorJSONMakeCommand("query-block-jobs", NULL);
+    if (!cmd)
         return -1;
+    if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+        goto cleanup;
 
     if ((data = virJSONValueObjectGet(reply, "return")) == NULL) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("reply was missing return data"));
-        return -1;
+        goto cleanup;
     }
 
     if (data->type != VIR_JSON_TYPE_ARRAY) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("unrecognized format of block job information"));
-        return -1;
+        goto cleanup;
     }
 
     if ((nr_results = virJSONValueArraySize(data)) < 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("unable to determine array size"));
-        return -1;
+        goto cleanup;
     }
 
-    for (i = 0; i < nr_results; i++) {
+    for (i = ret = 0; i < nr_results && ret == 0; i++) {
         virJSONValuePtr entry = virJSONValueArrayGet(data, i);
         if (!entry) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("missing array element"));
-            return -1;
+            ret = -1;
+            goto cleanup;
         }
-        if (qemuMonitorJSONGetBlockJobInfoOne(entry, device, info) == 0)
-            return 1;
+        ret = qemuMonitorJSONGetBlockJobInfoOne(entry, device, info);
     }
 
-    return 0;
+ cleanup:
+    virJSONValueFree(cmd);
+    virJSONValueFree(reply);
+    return ret;
 }
 
 
@@ -3791,7 +3804,6 @@ qemuMonitorJSONBlockJob(qemuMonitorPtr mon,
                         const char *base,
                         const char *backingName,
                         unsigned long long speed,
-                        virDomainBlockJobInfoPtr info,
                         qemuMonitorBlockJobCmd mode,
                         bool modern)
 {
@@ -3833,11 +3845,6 @@ qemuMonitorJSONBlockJob(qemuMonitorPtr mon,
                                          NULL);
         break;
 
-    case BLOCK_JOB_INFO:
-        cmd_name = "query-block-jobs";
-        cmd = qemuMonitorJSONMakeCommand(cmd_name, NULL);
-        break;
-
     case BLOCK_JOB_SPEED:
         cmd_name = modern ? "block-job-set-speed" : "block_job_set_speed";
         cmd = qemuMonitorJSONMakeCommand(cmd_name,
@@ -3888,9 +3895,6 @@ qemuMonitorJSONBlockJob(qemuMonitorPtr mon,
         }
     }
 
-    if (ret == 0 && mode == BLOCK_JOB_INFO)
-        ret = qemuMonitorJSONGetBlockJobInfo(reply, device, info);
-
     virJSONValueFree(cmd);
     virJSONValueFree(reply);
     return ret;
index d8c9308c5d29aaef4030324f941c69c2341be329..ebcf8ae64561dfa8e05ed061c09bae69ab2d987c 100644 (file)
@@ -285,11 +285,15 @@ int qemuMonitorJSONBlockJob(qemuMonitorPtr mon,
                             const char *base,
                             const char *backingName,
                             unsigned long long speed,
-                            virDomainBlockJobInfoPtr info,
                             qemuMonitorBlockJobCmd mode,
                             bool modern)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
+int qemuMonitorJSONBlockJobInfo(qemuMonitorPtr mon,
+                                const char *device,
+                                virDomainBlockJobInfoPtr info)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+
 int qemuMonitorJSONSetLink(qemuMonitorPtr mon,
                            const char *name,
                            virDomainNetInterfaceLinkState state);