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(a)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 :|