From 10ec36e2e7bac65dfee0ab04b992524f8a97c216 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Sat, 18 Feb 2012 09:20:01 -0700 Subject: [PATCH] qemu: pass block pull backing file to monitor This actually wires up the new optional parameter to block_stream: http://wiki.qemu.org/Features/LiveBlockMigration/ImageStreamingAPI The error checking is still sparse, since libvirt must not use qemu-img or header probing on a qcow2 file in use by qemu to check if the backing file name is valid; so for now, libvirt is relying on qemu to diagnose an incorrect backing name. Fixing this will require libvirt to track the entire backing file chain at the time qemu is started and keeps it updated with snapshot and pull operations. * src/qemu/qemu_monitor_json.c (qemuMonitorJSONBlockJob): Add parameter, and update callers. * src/qemu/qemu_monitor_json.h (qemuMonitorJSONBlockJob): Update signature. * src/qemu/qemu_monitor.h (qemuMonitorBlockJob): Likewise. * src/qemu/qemu_driver.c (qemuDomainBlockJobImpl): Update caller. * src/qemu/qemu_monitor.c (qemuMonitorBlockJob): Likewise. --- src/qemu/qemu_driver.c | 15 ++++++--------- src/qemu/qemu_monitor.c | 7 ++++--- src/qemu/qemu_monitor.h | 6 ++++-- src/qemu/qemu_monitor_json.c | 26 +++++++++++++++++++------- src/qemu/qemu_monitor_json.h | 3 ++- 5 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index a3ba5337a..c6bdd299f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -11379,14 +11379,6 @@ qemuDomainBlockJobImpl(virDomainPtr dom, const char *path, const char *base, if (!device) { goto cleanup; } - /* XXX - add a qemu capability check; if qemu 1.1 or newer, then - * validate and convert non-NULL base into something that can - * be passed as optional base argument. */ - if (base) { - qemuReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", - _("partial block pull is not supported with this QEMU binary")); - goto cleanup; - } if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0) goto cleanup; @@ -11399,7 +11391,12 @@ qemuDomainBlockJobImpl(virDomainPtr dom, const char *path, const char *base, qemuDomainObjEnterMonitorWithDriver(driver, vm); priv = vm->privateData; - ret = qemuMonitorBlockJob(priv->mon, device, bandwidth, info, mode); + /* XXX - add a qemu capability check, since only qemu 1.1 or newer + * supports the base argument. + * XXX - libvirt should really be tracking the backing file chain + * itself, and validating that base is on the chain, rather than + * relying on qemu to do this. */ + ret = qemuMonitorBlockJob(priv->mon, device, base, bandwidth, info, mode); qemuDomainObjExitMonitorWithDriver(driver, vm); endjob: diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 489691906..1da73f69d 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -2712,17 +2712,18 @@ int qemuMonitorScreendump(qemuMonitorPtr mon, int qemuMonitorBlockJob(qemuMonitorPtr mon, const char *device, + const char *base, unsigned long bandwidth, virDomainBlockJobInfoPtr info, int mode) { int ret = -1; - VIR_DEBUG("mon=%p, device=%s, bandwidth=%lu, info=%p, mode=%o", - mon, device, bandwidth, info, mode); + VIR_DEBUG("mon=%p, device=%s, base=%s, bandwidth=%lu, info=%p, mode=%o", + mon, device, NULLSTR(base), bandwidth, info, mode); if (mon->json) - ret = qemuMonitorJSONBlockJob(mon, device, bandwidth, info, mode); + ret = qemuMonitorJSONBlockJob(mon, device, base, bandwidth, info, mode); else qemuReportError(VIR_ERR_INVALID_ARG, "%s", _("block jobs require JSON monitor")); diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 9c5a5d3c7..b1c956c26 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -1,7 +1,7 @@ /* * qemu_monitor.h: 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 @@ -519,9 +519,11 @@ typedef enum { int qemuMonitorBlockJob(qemuMonitorPtr mon, const char *device, + const char *back, unsigned long bandwidth, virDomainBlockJobInfoPtr info, - int mode); + int mode) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5); int qemuMonitorOpenGraphics(qemuMonitorPtr mon, const char *protocol, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index e6e9a8547..c0f148bff 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -3229,17 +3229,25 @@ static int qemuMonitorJSONGetBlockJobInfo(virJSONValuePtr reply, } -int qemuMonitorJSONBlockJob(qemuMonitorPtr mon, - const char *device, - unsigned long bandwidth, - virDomainBlockJobInfoPtr info, - int mode) +int +qemuMonitorJSONBlockJob(qemuMonitorPtr mon, + const char *device, + const char *base, + unsigned long bandwidth, + virDomainBlockJobInfoPtr info, + int mode) { int ret = -1; virJSONValuePtr cmd = NULL; virJSONValuePtr reply = NULL; const char *cmd_name = NULL; + if (base && mode != BLOCK_JOB_PULL) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("only block pull supports base: %s"), base); + return -1; + } + if (mode == BLOCK_JOB_ABORT) { cmd_name = "block_job_cancel"; cmd = qemuMonitorJSONMakeCommand(cmd_name, "s:device", device, NULL); @@ -3254,8 +3262,12 @@ int qemuMonitorJSONBlockJob(qemuMonitorPtr mon, NULL); } else if (mode == BLOCK_JOB_PULL) { cmd_name = "block_stream"; - cmd = qemuMonitorJSONMakeCommand(cmd_name, "s:device", - device, NULL); + if (base) + cmd = qemuMonitorJSONMakeCommand(cmd_name, "s:device", + device, "s:base", base, NULL); + else + cmd = qemuMonitorJSONMakeCommand(cmd_name, "s:device", + device, NULL); } if (!cmd) diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 9c423a084..0932a2c0e 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -1,7 +1,7 @@ /* * qemu_monitor_json.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 @@ -246,6 +246,7 @@ int qemuMonitorJSONScreendump(qemuMonitorPtr mon, int qemuMonitorJSONBlockJob(qemuMonitorPtr mon, const char *device, + const char *base, unsigned long bandwidth, virDomainBlockJobInfoPtr info, int mode); -- 2.39.5