qemuDomainDefFormatBuf(struct qemud_driver *driver,
virDomainDefPtr def,
unsigned int flags,
+ bool compatible,
virBuffer *buf)
{
int ret = -1;
virCPUDefPtr cpu = NULL;
virCPUDefPtr def_cpu = def->cpu;
+ virDomainControllerDefPtr *controllers = NULL;
+ int ncontrollers = 0;
/* Update guest CPU requirements according to host CPU */
if ((flags & VIR_DOMAIN_XML_UPDATE_CPU) &&
def->cpu = cpu;
}
+ if (compatible) {
+ int i;
+ virDomainControllerDefPtr usb = NULL;
+
+ /* If only the default USB controller is present, we can remove it
+ * and make the XML compatible with older versions of libvirt which
+ * didn't support USB controllers in the XML but always added the
+ * default one to qemu anyway.
+ */
+ for (i = 0; i < def->ncontrollers; i++) {
+ if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) {
+ if (usb) {
+ usb = NULL;
+ break;
+ }
+ usb = def->controllers[i];
+ }
+ }
+ if (usb && usb->idx == 0 && usb->model == -1) {
+ VIR_DEBUG("Removing default USB controller from domain '%s'"
+ " for migration compatibility", def->name);
+ controllers = def->controllers;
+ ncontrollers = def->ncontrollers;
+ if (VIR_ALLOC_N(def->controllers, ncontrollers - 1) < 0) {
+ controllers = NULL;
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ def->ncontrollers = 0;
+ for (i = 0; i < ncontrollers; i++) {
+ if (controllers[i] != usb)
+ def->controllers[def->ncontrollers++] = controllers[i];
+ }
+ }
+ }
+
ret = virDomainDefFormatInternal(def, flags, buf);
cleanup:
def->cpu = def_cpu;
virCPUDefFree(cpu);
+ if (controllers) {
+ VIR_FREE(def->controllers);
+ def->controllers = controllers;
+ def->ncontrollers = ncontrollers;
+ }
return ret;
}
char *qemuDomainDefFormatXML(struct qemud_driver *driver,
virDomainDefPtr def,
- unsigned int flags)
+ unsigned int flags,
+ bool compatible)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
- if (qemuDomainDefFormatBuf(driver, def, flags, &buf) < 0) {
+ if (qemuDomainDefFormatBuf(driver, def, flags, compatible, &buf) < 0) {
virBufferFreeAndReset(&buf);
return NULL;
}
char *qemuDomainFormatXML(struct qemud_driver *driver,
virDomainObjPtr vm,
- unsigned int flags)
+ unsigned int flags,
+ bool compatible)
{
virDomainDefPtr def;
else
def = vm->def;
- return qemuDomainDefFormatXML(driver, def, flags);
+ return qemuDomainDefFormatXML(driver, def, flags, compatible);
}
char *
qemuDomainDefFormatLive(struct qemud_driver *driver,
virDomainDefPtr def,
- bool inactive)
+ bool inactive,
+ bool compatible)
{
unsigned int flags = QEMU_DOMAIN_FORMAT_LIVE_FLAGS;
if (inactive)
flags |= VIR_DOMAIN_XML_INACTIVE;
- return qemuDomainDefFormatXML(driver, def, flags);
+ return qemuDomainDefFormatXML(driver, def, flags, compatible);
}
int qemuDomainDefFormatBuf(struct qemud_driver *driver,
virDomainDefPtr vm,
unsigned int flags,
+ bool compatible,
virBuffer *buf);
char *qemuDomainDefFormatXML(struct qemud_driver *driver,
virDomainDefPtr vm,
- unsigned int flags);
+ unsigned int flags,
+ bool compatible);
char *qemuDomainFormatXML(struct qemud_driver *driver,
virDomainObjPtr vm,
- unsigned int flags);
+ unsigned int flags,
+ bool compatible);
char *qemuDomainDefFormatLive(struct qemud_driver *driver,
virDomainDefPtr def,
- bool inactive);
+ bool inactive,
+ bool compatible);
void qemuDomainObjTaint(struct qemud_driver *driver,
virDomainObjPtr obj,
virDomainDefFree(def);
goto endjob;
}
- xml = qemuDomainDefFormatLive(driver, def, true);
+ xml = qemuDomainDefFormatLive(driver, def, true, true);
} else {
- xml = qemuDomainDefFormatLive(driver, vm->def, true);
+ xml = qemuDomainDefFormatLive(driver, vm->def, true, true);
}
if (!xml) {
qemuReportError(VIR_ERR_OPERATION_FAILED,
if (fd < 0)
goto cleanup;
- ret = qemuDomainDefFormatXML(driver, def, flags);
+ ret = qemuDomainDefFormatXML(driver, def, flags, false);
cleanup:
virDomainDefFree(def);
goto cleanup;
}
- xml = qemuDomainDefFormatXML(driver, def, (VIR_DOMAIN_XML_INACTIVE |
- VIR_DOMAIN_XML_SECURE));
+ xml = qemuDomainDefFormatXML(driver, def,
+ VIR_DOMAIN_XML_INACTIVE |
+ VIR_DOMAIN_XML_SECURE,
+ true);
if (!xml)
goto cleanup;
len = strlen(xml) + 1;
}
}
- ret = qemuDomainFormatXML(driver, vm, flags);
+ ret = qemuDomainFormatXML(driver, vm, flags, false);
cleanup:
if (vm)
goto cleanup;
}
- xml = qemuDomainDefFormatXML(driver, def, VIR_DOMAIN_XML_INACTIVE);
+ xml = qemuDomainDefFormatXML(driver, def, VIR_DOMAIN_XML_INACTIVE, false);
cleanup:
virDomainDefFree(def);
} else {
/* Easiest way to clone inactive portion of vm->def is via
* conversion in and back out of xml. */
- if (!(xml = qemuDomainDefFormatLive(driver, vm->def, true)) ||
+ if (!(xml = qemuDomainDefFormatLive(driver, vm->def, true, false)) ||
!(def->dom = virDomainDefParseString(driver->caps, xml,
QEMU_EXPECTED_VIRT_TYPES,
VIR_DOMAIN_XML_INACTIVE)))
if (!(xml = qemuDomainDefFormatXML(driver,
snap->def->dom,
VIR_DOMAIN_XML_INACTIVE |
- VIR_DOMAIN_XML_SECURE)))
+ VIR_DOMAIN_XML_SECURE,
+ false)))
goto cleanup;
config = virDomainDefParseString(driver->caps, xml,
QEMU_EXPECTED_VIRT_TYPES,
mig->persistent,
VIR_DOMAIN_XML_INACTIVE |
VIR_DOMAIN_XML_SECURE,
+ true,
buf) < 0)
return -1;
virBufferAdjustIndent(buf, -2);
if (!virDomainDefCheckABIStability(vm->def, def))
goto cleanup;
- rv = qemuDomainDefFormatLive(driver, def, false);
+ rv = qemuDomainDefFormatLive(driver, def, false, true);
} else {
- rv = qemuDomainDefFormatLive(driver, vm->def, false);
+ rv = qemuDomainDefFormatLive(driver, vm->def, false, true);
}
cleanup:
int hookret;
if (!(xml = qemuDomainDefFormatXML(driver, def,
- VIR_DOMAIN_XML_SECURE)))
+ VIR_DOMAIN_XML_SECURE, false)))
goto cleanup;
hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, def->name,
*/
if (!(dom_xml = qemuDomainFormatXML(driver, vm,
VIR_DOMAIN_XML_SECURE |
- VIR_DOMAIN_XML_UPDATE_CPU)))
+ VIR_DOMAIN_XML_UPDATE_CPU,
+ true)))
return -1;
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED)
/* Run an early hook to set-up missing devices */
if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
- char *xml = qemuDomainDefFormatXML(driver, vm->def, 0);
+ char *xml = qemuDomainDefFormatXML(driver, vm->def, 0, false);
int hookret;
hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, vm->def->name,
/* now that we know it is about to start call the hook if present */
if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
- char *xml = qemuDomainDefFormatXML(driver, vm->def, 0);
+ char *xml = qemuDomainDefFormatXML(driver, vm->def, 0, false);
int hookret;
hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, vm->def->name,
/* now that we know it's stopped call the hook if present */
if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
- char *xml = qemuDomainDefFormatXML(driver, vm->def, 0);
+ char *xml = qemuDomainDefFormatXML(driver, vm->def, 0, false);
/* we can't stop the operation even if the script raised an error */
virHookCall(VIR_HOOK_DRIVER_QEMU, vm->def->name,
/* The "release" hook cleans up additional resources */
if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
- char *xml = qemuDomainDefFormatXML(driver, vm->def, 0);
+ char *xml = qemuDomainDefFormatXML(driver, vm->def, 0, false);
/* we can't stop the operation even if the script raised an error */
virHookCall(VIR_HOOK_DRIVER_QEMU, vm->def->name,