[libvirt] [PATCH 1/3] qemu: require json for block jobs

Eric Blake eblake at redhat.com
Sat Feb 18 17:44:34 UTC 2012


Block job commands are not part of upstream qemu until 1.1; and
proper support of job completion and cancellation depends on being
able to receive QMP events, which implies the JSON monitor.
Additionally, some early versions of block job commands were
backported to RHEL qemu, but these versions lacked asynchronous
job cancellation and partial block pull, so there are several
patches that will still be needed in this area of libvirt code
to support both flavors of block job commands.

Due to earlier patches in libvirt, we are guaranteed that all versions
of qemu that support block job commands already require libvirt to
use the JSON monitor.  That means that the text version of block jobs
will not be used, and having to refactor two copies of the block job
handlers makes no sense.  So instead, we delete the text handlers.

* src/qemu/qemu_monitor.c (qemuMonitorBlockJob): Drop text monitor
support.
* src/qemu/qemu_monitor_text.h (qemuMonitorTextBlockJob): Delete.
* src/qemu/qemu_monitor_text.c (qemuMonitorTextParseBlockJobOne)
(qemuMonitorTextParseBlockJob, qemuMonitorTextBlockJob):
Likewise.
---
 src/qemu/qemu_monitor.c      |    9 +-
 src/qemu/qemu_monitor_text.c |  175 +-----------------------------------------
 src/qemu/qemu_monitor_text.h |    8 +--
 3 files changed, 7 insertions(+), 185 deletions(-)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 93f3505..903463d 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1,7 +1,7 @@
 /*
  * qemu_monitor.c: interaction with QEMU monitor console
  *
- * Copyright (C) 2006-2011 Red Hat, Inc.
+ * Copyright (C) 2006-2012 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -2657,15 +2657,16 @@ int qemuMonitorBlockJob(qemuMonitorPtr mon,
                         virDomainBlockJobInfoPtr info,
                         int mode)
 {
-    int ret;
+    int ret = -1;

-    VIR_DEBUG("mon=%p, device=%p, bandwidth=%lu, info=%p, mode=%o",
+    VIR_DEBUG("mon=%p, device=%s, bandwidth=%lu, info=%p, mode=%o",
               mon, device, bandwidth, info, mode);

     if (mon->json)
         ret = qemuMonitorJSONBlockJob(mon, device, bandwidth, info, mode);
     else
-        ret = qemuMonitorTextBlockJob(mon, device, bandwidth, info, mode);
+        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
+                        _("block jobs require JSON monitor"));
     return ret;
 }

diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index f051a86..d6f7dac 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -1,7 +1,7 @@
 /*
  * qemu_monitor_text.c: interaction with QEMU monitor console
  *
- * Copyright (C) 2006-2011 Red Hat, Inc.
+ * Copyright (C) 2006-2012 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -3280,179 +3280,6 @@ cleanup:
     return ret;
 }

-static int qemuMonitorTextParseBlockJobOne(const char *text,
-                                           const char *device,
-                                           virDomainBlockJobInfoPtr info,
-                                           const char **next)
-{
-    virDomainBlockJobInfo tmp;
-    char *p;
-    unsigned long long speed_bytes;
-    int mismatch = 0;
-
-    if (next == NULL)
-        return -1;
-    *next = NULL;
-
-    /*
-     * Each active stream will appear on its own line in the following format:
-     * Streaming device <device>: Completed <cur> of <end> bytes
-     */
-    if ((text = STRSKIP(text, "Streaming device ")) == NULL)
-        return -EINVAL;
-
-    if (!STREQLEN(text, device, strlen(device)))
-        mismatch = 1;
-
-    if ((text = strstr(text, ": Completed ")) == NULL)
-        return -EINVAL;
-    text += 11;
-
-    if (virStrToLong_ull (text, &p, 10, &tmp.cur))
-        return -EINVAL;
-    text = p;
-
-    if (!STRPREFIX(text, " of "))
-        return -EINVAL;
-    text += 4;
-
-    if (virStrToLong_ull (text, &p, 10, &tmp.end))
-        return -EINVAL;
-    text = p;
-
-    if (!STRPREFIX(text, " bytes, speed limit "))
-        return -EINVAL;
-    text += 20;
-
-    if (virStrToLong_ull (text, &p, 10, &speed_bytes))
-        return -EINVAL;
-    text = p;
-
-    if (!STRPREFIX(text, " bytes/s"))
-        return -EINVAL;
-
-    if (mismatch) {
-        *next = STRSKIP(text, "\n");
-        return -EAGAIN;
-    }
-
-    if (info) {
-        info->cur = tmp.cur;
-        info->end = tmp.end;
-        info->bandwidth = speed_bytes / 1024ULL / 1024ULL;
-        info->type = VIR_DOMAIN_BLOCK_JOB_TYPE_PULL;
-    }
-    return 1;
-}
-
-static int qemuMonitorTextParseBlockJob(const char *text,
-                                        const char *device,
-                                        virDomainBlockJobInfoPtr info)
-{
-    const char *next = NULL;
-    int ret = 0;
-
-    /* Check error: Device not found */
-    if (strstr(text, "Device '") && strstr(text, "' not found")) {
-        qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Device not found"));
-        return -1;
-    }
-
-    /* Check error: Job already active on this device */
-    if (strstr(text, "Device '") && strstr(text, "' is in use")) {
-        qemuReportError(VIR_ERR_OPERATION_FAILED, _("Device %s in use"),
-            device);
-        return -1;
-    }
-
-    /* Check error: Stop non-existent job */
-    if (strstr(text, "has not been activated")) {
-        qemuReportError(VIR_ERR_OPERATION_INVALID,\
-            _("No active operation on device: %s"), device);
-        return -1;
-    }
-
-    /* This is not an error condition, there are just no results to report. */
-    if (strstr(text, "No active jobs")) {
-        return 0;
-    }
-
-    /* Check for unsupported operation */
-    if (strstr(text, "Operation is not supported")) {
-        qemuReportError(VIR_ERR_OPERATION_INVALID,
-            _("Operation is not supported for device: %s"), device);
-        return -1;
-    }
-
-    /* No output indicates success for Pull, JobAbort, and JobSetSpeed */
-    if (STREQ(text, ""))
-        return 0;
-
-    /* Now try to parse BlockJobInfo */
-    do {
-        ret = qemuMonitorTextParseBlockJobOne(text, device, info, &next);
-        text = next;
-    } while (text && ret == -EAGAIN);
-
-    if (ret < 0)
-        return -1;
-    return ret;
-}
-
-int qemuMonitorTextBlockJob(qemuMonitorPtr mon,
-                             const char *device,
-                             unsigned long bandwidth,
-                             virDomainBlockJobInfoPtr info,
-                             int mode)
-{
-    char *cmd = NULL;
-    char *reply = NULL;
-    int ret;
-    const char *cmd_name = NULL;
-
-    if (mode == BLOCK_JOB_ABORT) {
-        cmd_name = "block_job_cancel";
-        ret = virAsprintf(&cmd, "%s %s", cmd_name, device);
-    } else if (mode == BLOCK_JOB_INFO) {
-        cmd_name = "info block-jobs";
-        ret = virAsprintf(&cmd, "%s", cmd_name);
-    } else if (mode == BLOCK_JOB_SPEED) {
-        cmd_name = "block_job_set_speed";
-        ret = virAsprintf(&cmd, "%s %s %luM", cmd_name, device, bandwidth);
-    } else if (mode == BLOCK_JOB_PULL) {
-        cmd_name = "block_stream";
-        ret = virAsprintf(&cmd, "%s %s", cmd_name, device);
-    } else {
-        return -1;
-    }
-
-    if (ret < 0) {
-        virReportOOMError();
-        return -1;
-    }
-
-    if (qemuMonitorHMPCommand(mon, cmd, &reply) < 0) {
-        qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                        "%s", _("cannot run monitor command"));
-        ret = -1;
-        goto cleanup;
-    }
-
-    if (qemuMonitorTextCommandNotFound(cmd_name, reply)) {
-        qemuReportError(VIR_ERR_OPERATION_INVALID,
-                        _("Command '%s' is not found"), cmd_name);
-        ret = -1;
-        goto cleanup;
-    }
-
-    ret = qemuMonitorTextParseBlockJob(reply, device, info);
-
-cleanup:
-    VIR_FREE(cmd);
-    VIR_FREE(reply);
-    return ret;
-}
-

 int qemuMonitorTextOpenGraphics(qemuMonitorPtr mon,
                                 const char *protocol,
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index 050c30e..719fc82 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -1,7 +1,7 @@
 /*
  * qemu_monitor_text.h: interaction with QEMU monitor console
  *
- * Copyright (C) 2006-2009, 2011 Red Hat, Inc.
+ * Copyright (C) 2006-2009, 2011-2012 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -233,12 +233,6 @@ int qemuMonitorTextSendKey(qemuMonitorPtr mon,

 int qemuMonitorTextScreendump(qemuMonitorPtr mon, const char *file);

-int qemuMonitorTextBlockJob(qemuMonitorPtr mon,
-                            const char *device,
-                            unsigned long bandwidth,
-                            virDomainBlockJobInfoPtr info,
-                            int mode);
-
 int qemuMonitorTextSetLink(qemuMonitorPtr mon,
                            const char *name,
                            enum virDomainNetInterfaceLinkState state);
-- 
1.7.7.6




More information about the libvir-list mailing list