diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index a3ba5337ac..c6bdd299f7 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 4896919064..1da73f69d1 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 9c5a5d3c7d..b1c956c26d 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 e6e9a85478..c0f148bfff 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 9c423a0843..0932a2c0e6 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);