This patch is mainly to solve the migration problem: After the media is ejected inside guest, and one removes the source of the media outside, migration will fail early, as we start the qemu daemon on dest host with the source of the removable block still existing, this causes failure when trying to do cgroup setting on the media source then. All the migration functions try to get the domain XML before doing preparation on dest host. Except one specify the domain XML externally (e.g. option "--xml" of "virsh migrate"). So this patch changes the function "qemuDomainFormatXML" to check the media status of removable block using the new introduced monitor functions, and clear the source path if the media ejected, so that it won't start the qemu daemon on dest host along with the media path. Public migration APIs invokes "driver->domainGetXMLDesc"; "driver->domainMigratePeer2Peer" uses "qemuDomainFormatXML" for v2 migration protocol and "qemuDomainBegin" for v3 migration protocol, to get the domain XML before preparation on dest host. All of these 3 functions are based on "qemuDomainFormatXML", that's why making changes on it. The changes affect the running domain config, (e.g. for a running domain, "virsh dumpxml" won't display the source path of the media anymore once it's ejected inside guest. But think it's reasonable to do like so. But the migration will still fail even with this patch when one specified the domain XML externally. However, think this is not what we should care about. It's fault of user? --- src/qemu/qemu_domain.c | 37 +++++++++++++++++++++++++++++++++++++ 1 files changed, 37 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 675c6df..968af69 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1063,12 +1063,49 @@ char *qemuDomainFormatXML(struct qemud_driver *driver, unsigned int flags) { virDomainDefPtr def; + unsigned int ejected = 0; + int err, i; + qemuDomainObjPrivatePtr priv = NULL; + if ((flags & VIR_DOMAIN_XML_INACTIVE) && vm->newDef) def = vm->newDef; else def = vm->def; + /* Check if the media of removable block is ejected, and clear the + * source path if it's ejected. + */ + if (virDomainObjIsActive(vm)) { + priv = vm->privateData; + + if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_QUERY) < 0) + return NULL; + + for (i = 0; i < vm->def->ndisks; i++) { + if (vm->def->disks[i]->src && + (vm->def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM || + vm->def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)) { + qemuDomainObjEnterMonitorWithDriver(driver, vm); + err = qemuMonitorGetRemovableBlockMediaStatus(priv->mon, + vm->def->disks[i]->info.alias, + &ejected); + qemuDomainObjExitMonitorWithDriver(driver, vm); + + if (err == -1) + return NULL; + + if (ejected == 1) + VIR_FREE(vm->def->disks[i]->src); + } + } + + if (qemuDomainObjEndJob(driver, vm) == 0) { + vm = NULL; + return NULL; + } + } + return qemuDomainDefFormatXML(driver, def, flags); } -- 1.7.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list