aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2012-02-17 14:55:35 -0700
committerEric Blake <eblake@redhat.com>2012-02-29 13:44:20 -0700
commit68a1300556c4122767a9e77453c0e8e5d97c782f (patch)
treeb78b3901eaf6b85236a9873de06664b5db97a0e8
parentfix alphabetical order of virNetlink functions in symbol file (diff)
downloadlibvirt-68a1300556c4122767a9e77453c0e8e5d97c782f.tar.gz
libvirt-68a1300556c4122767a9e77453c0e8e5d97c782f.tar.bz2
libvirt-68a1300556c4122767a9e77453c0e8e5d97c782f.zip
qemu: require json for block jobs
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.
-rw-r--r--src/qemu/qemu_monitor.c9
-rw-r--r--src/qemu/qemu_monitor_text.c175
-rw-r--r--src/qemu/qemu_monitor_text.h8
3 files changed, 7 insertions, 185 deletions
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index de4571c9d..489691906 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
@@ -2716,15 +2716,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 f051a863a..d6f7dacfa 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 050c30e41..719fc8265 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);