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>
/* 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;
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)
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)
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;
_("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)
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);
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);
}
}
/* 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 */
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)
typedef enum {
BLOCK_JOB_ABORT,
- BLOCK_JOB_INFO,
BLOCK_JOB_SPEED,
BLOCK_JOB_PULL,
} qemuMonitorBlockJobCmd;
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,
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;
return -1;
}
if (!STREQ(this_dev, device))
- return -1;
+ return 0;
type = virJSONValueObjectGetString(entry, "type");
if (!type) {
_("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;
}
const char *base,
const char *backingName,
unsigned long long speed,
- virDomainBlockJobInfoPtr info,
qemuMonitorBlockJobCmd mode,
bool modern)
{
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,
}
}
- if (ret == 0 && mode == BLOCK_JOB_INFO)
- ret = qemuMonitorJSONGetBlockJobInfo(reply, device, info);
-
virJSONValueFree(cmd);
virJSONValueFree(reply);
return ret;
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);