With this, it is possible to update the path to a disk backing image on either the save or restore action, without having to binary edit the XML embedded in the state file. * src/qemu/qemu_driver.c (qemuDomainSaveInternal) (qemuDomainSaveImageOpen): Add parameter. (qemuDomainSaveFlags, qemuDomainManagedSave) (qemuDomainRestoreFlags, qemuDomainObjRestore): Update callers. --- v2: new patch Tested via: virsh start dom virsh dumpxml dom > dom.xml ln /path/to/disk /path/to/disk2 ln /path/to/disk /path/to/disk3 edit dom.xml to change /path/to/disk to /path/to/disk2 virsh save dom dom.save --xml dom.xml check that xml embedded in binary dom.save did change cp dom.xml dom.xml2 edit dom.xml to change /path/to/disk2 to /path/to/disk3 edit dom.xml2 to break abi, such as removing entire cdrom <disk> element virsh restore dom.save --xml dom.xml2 => properly failed virsh restore dom.save --xml dom.xml virsh dumpxml dom - validate that /path/to/disk3 is in use Which means it is now possible to do: virsh dumpxml dom > dom.xml virsh save dom dom.save use qemu-img to create new qcow2 files with backing file of the original images alter dom.xml to reflect the new file names virsh restore dom.save --xml dom.xml to externally manage disk snapshots causing changed file names. Not quite where I wanted to be with snapshot support, but certainly a step in the right direction! src/qemu/qemu_driver.c | 56 +++++++++++++++++++++++++++++++++-------------- 1 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 73d2938..d1fa06f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2113,7 +2113,7 @@ qemuCompressProgramName(int compress) static int qemuDomainSaveInternal(struct qemud_driver *driver, virDomainPtr dom, virDomainObjPtr vm, const char *path, - int compressed, bool bypass_cache) + int compressed, bool bypass_cache, const char *xmlin) { char *xml = NULL; struct qemud_save_header header; @@ -2160,7 +2160,22 @@ qemuDomainSaveInternal(struct qemud_driver *driver, virDomainPtr dom, } /* Get XML for the domain */ - xml = virDomainDefFormat(vm->def, VIR_DOMAIN_XML_SECURE); + if (xmlin) { + virDomainDefPtr def = NULL; + + if (!(def = virDomainDefParseString(driver->caps, xmlin, + QEMU_EXPECTED_VIRT_TYPES, + VIR_DOMAIN_XML_INACTIVE))) { + goto endjob; + } + if (!virDomainDefCheckABIStability(vm->def, def)) { + virDomainDefFree(def); + goto endjob; + } + xml = virDomainDefFormat(def, VIR_DOMAIN_XML_SECURE); + } else { + xml = virDomainDefFormat(vm->def, VIR_DOMAIN_XML_SECURE); + } if (!xml) { qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", _("failed to get domain xml")); @@ -2381,11 +2396,6 @@ qemuDomainSaveFlags(virDomainPtr dom, const char *path, const char *dxml, virDomainObjPtr vm = NULL; virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE, -1); - if (dxml) { - qemuReportError(VIR_ERR_INVALID_ARG, "%s", - _("xml modification unsupported")); - return -1; - } qemuDriverLock(driver); @@ -2423,7 +2433,8 @@ qemuDomainSaveFlags(virDomainPtr dom, const char *path, const char *dxml, } ret = qemuDomainSaveInternal(driver, dom, vm, path, compressed, - (flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0); + (flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0, + dxml); vm = NULL; cleanup: @@ -2487,7 +2498,8 @@ qemuDomainManagedSave(virDomainPtr dom, unsigned int flags) compressed = QEMUD_SAVE_FORMAT_RAW; ret = qemuDomainSaveInternal(driver, dom, vm, name, compressed, - (flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0); + (flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0, + NULL); vm = NULL; cleanup: @@ -3616,7 +3628,8 @@ qemuDomainSaveImageOpen(struct qemud_driver *driver, const char *path, virDomainDefPtr *ret_def, struct qemud_save_header *ret_header, - bool bypass_cache, virFileDirectFdPtr *directFd) + bool bypass_cache, virFileDirectFdPtr *directFd, + const char *xmlin) { int fd; struct qemud_save_header header; @@ -3700,6 +3713,20 @@ qemuDomainSaveImageOpen(struct qemud_driver *driver, QEMU_EXPECTED_VIRT_TYPES, VIR_DOMAIN_XML_INACTIVE))) goto error; + if (xmlin) { + virDomainDefPtr def2 = NULL; + + if (!(def2 = virDomainDefParseString(driver->caps, xmlin, + QEMU_EXPECTED_VIRT_TYPES, + VIR_DOMAIN_XML_INACTIVE))) + goto error; + if (!virDomainDefCheckABIStability(def, def2)) { + virDomainDefFree(def2); + goto error; + } + virDomainDefFree(def); + def = def2; + } VIR_FREE(xml); @@ -3834,17 +3861,12 @@ qemuDomainRestoreFlags(virConnectPtr conn, virFileDirectFdPtr directFd = NULL; virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE, -1); - if (dxml) { - qemuReportError(VIR_ERR_INVALID_ARG, "%s", - _("xml modification unsupported")); - return -1; - } qemuDriverLock(driver); fd = qemuDomainSaveImageOpen(driver, path, &def, &header, (flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0, - &directFd); + &directFd, dxml); if (fd < 0) goto cleanup; @@ -3904,7 +3926,7 @@ qemuDomainObjRestore(virConnectPtr conn, virFileDirectFdPtr directFd = NULL; fd = qemuDomainSaveImageOpen(driver, path, &def, &header, - bypass_cache, &directFd); + bypass_cache, &directFd, NULL); if (fd < 0) goto cleanup; -- 1.7.4.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list