
On Thu, Jun 09, 2011 at 12:10:10PM -0500, Adam Litke wrote:
The virDomainBlockPull* family of commands are enabled by the 'block_stream' and 'info block_stream' qemu monitor commands.
* src/qemu/qemu_driver.c src/qemu/qemu_monitor_text.[ch]: implement disk streaming by using the stream and info stream text monitor commands * src/qemu/qemu_monitor_json.[ch]: implement commands using the qmp monitor
Signed-off-by: Adam Litke <agl@us.ibm.com> --- src/qemu/qemu_driver.c | 108 +++++++++++++++++++++++++++++ src/qemu/qemu_monitor.c | 16 ++++ src/qemu/qemu_monitor.h | 13 ++++ src/qemu/qemu_monitor_json.c | 131 +++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 4 + src/qemu/qemu_monitor_text.c | 156 ++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_text.h | 5 ++ 7 files changed, 433 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 80de79a..1cbb151 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7971,6 +7971,110 @@ cleanup: return ret; }
+static const char * +qemuDiskPathToAlias(virDomainObjPtr vm, const char *path) { + int i; + char *ret = NULL; + + for (i = 0 ; i < vm->def->ndisks ; i++) { + virDomainDiskDefPtr disk = vm->def->disks[i]; + + if (disk->src != NULL && STREQ(disk->src, path)) {
You also rather want to check that disk->type is one of VIR_DOMAIN_DISK_TYPE_BLOCK VIR_DOMAIN_DISK_TYPE_FILE before looking at disk->src
+ if (virAsprintf(&ret, "drive-%s", disk->info.alias) < 0) { + virReportOOMError(); + return NULL; + } + break; + } + } + + if (!ret) { + qemuReportError(VIR_ERR_INVALID_ARG, + "%s", _("No device found for specified path")); + } + return ret; +} + +static int +qemuDomainBlockPullImpl(virDomainPtr dom, const char *path, + virDomainBlockPullInfoPtr info, + int mode) +{ + struct qemud_driver *driver = dom->conn->privateData; + virDomainObjPtr vm = NULL; + qemuDomainObjPrivatePtr priv; + char uuidstr[VIR_UUID_STRING_BUFLEN]; + const char *device = NULL; + int ret = -1; + + qemuDriverLock(driver); + virUUIDFormat(dom->uuid, uuidstr); + vm = virDomainFindByUUID(&driver->domains, dom->uuid); + if (!vm) { + qemuReportError(VIR_ERR_NO_DOMAIN, + _("no domain with matching uuid '%s'"), uuidstr); + goto cleanup; + } + + if (!virDomainObjIsActive(vm)) { + qemuReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("domain is not running")); + goto cleanup; + } + + device = qemuDiskPathToAlias(vm, path); + if (!device) { + goto cleanup; + } + + if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0) + goto cleanup; + qemuDomainObjEnterMonitorWithDriver(driver, vm); + priv = vm->privateData; + ret = qemuMonitorBlockPull(priv->mon, device, info, mode); + qemuDomainObjExitMonitorWithDriver(driver, vm); + if (qemuDomainObjEndJob(vm) == 0) { + vm = NULL; + goto cleanup; + } + +cleanup: + VIR_FREE(device); + if (vm) + virDomainObjUnlock(vm); + qemuDriverUnlock(driver); + return ret; +} + +static int +qemuDomainBlockPull(virDomainPtr dom, const char *path, + virDomainBlockPullInfoPtr info, unsigned int flags) +{ + virCheckFlags(0, -1); + return qemuDomainBlockPullImpl(dom, path, info, BLOCK_PULL_MODE_ONE); +} + +static int +qemuDomainBlockPullAll(virDomainPtr dom, const char *path, unsigned int flags) +{ + virCheckFlags(0, -1); + return qemuDomainBlockPullImpl(dom, path, NULL, BLOCK_PULL_MODE_ALL); +} + +static int +qemuDomainBlockPullAbort(virDomainPtr dom, const char *path, unsigned int flags) +{ + virCheckFlags(0, -1); + return qemuDomainBlockPullImpl(dom, path, NULL, BLOCK_PULL_MODE_ABORT); +} + +static int +qemuDomainGetBlockPullInfo(virDomainPtr dom, const char *path, + virDomainBlockPullInfoPtr info, unsigned int flags) +{ + virCheckFlags(0, -1); + return qemuDomainBlockPullImpl(dom, path, info, BLOCK_PULL_MODE_INFO); +}
static virDriver qemuDriver = { .no = VIR_DRV_QEMU, @@ -8090,6 +8194,10 @@ static virDriver qemuDriver = { .domainMigratePerform3 = qemuDomainMigratePerform3, /* 0.9.2 */ .domainMigrateFinish3 = qemuDomainMigrateFinish3, /* 0.9.2 */ .domainMigrateConfirm3 = qemuDomainMigrateConfirm3, /* 0.9.2 */ + .domainBlockPull = qemuDomainBlockPull, /* 0.9.2 */ + .domainBlockPullAll = qemuDomainBlockPullAll, /* 0.9.2 */ + .domainBlockPullAbort = qemuDomainBlockPullAbort, /* 0.9.2 */ + .domainGetBlockPullInfo = qemuDomainGetBlockPullInfo, /* 0.9.2 */ };
These want to be 0.9.3 ACK to the rest of the patch Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|