From 18ba452f27e38412496f8ff3fe5adbc9de93176c Mon Sep 17 00:00:00 2001 From: Tomasz Flendrich Date: Sat, 16 Jul 2016 02:42:50 +0200 Subject: [PATCH] Split qemuDomainDetachDeviceFlags in two Previously, qemuDomainDetachDeviceFlags was doing two things: handling the job and detaching devices. Now the second part is in a new function. --- src/qemu/qemu_driver.c | 176 ++++++++++++++++++++++------------------- 1 file changed, 96 insertions(+), 80 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 62a6ed3471..d5ba3b8039 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -8324,6 +8324,100 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom, return ret; } +static int +qemuDomainDetachDeviceLiveAndConfig(virQEMUDriverPtr driver, + virDomainObjPtr vm, + const char *xml, + unsigned int flags) +{ + virCapsPtr caps = NULL; + virQEMUDriverConfigPtr cfg = NULL; + virDomainDeviceDefPtr dev = NULL, dev_copy = NULL; + unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE; + virDomainDefPtr vmdef = NULL; + int ret = -1; + + virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | + VIR_DOMAIN_AFFECT_CONFIG, -1); + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + cfg = virQEMUDriverGetConfig(driver); + + if ((flags & VIR_DOMAIN_AFFECT_CONFIG) && + !(flags & VIR_DOMAIN_AFFECT_LIVE)) + parse_flags |= VIR_DOMAIN_DEF_PARSE_INACTIVE; + + dev = dev_copy = virDomainDeviceDefParse(xml, vm->def, + caps, driver->xmlopt, + parse_flags); + if (dev == NULL) + goto cleanup; + + if (flags & VIR_DOMAIN_AFFECT_CONFIG && + flags & VIR_DOMAIN_AFFECT_LIVE) { + /* If we are affecting both CONFIG and LIVE + * create a deep copy of device as adding + * to CONFIG takes one instance. + */ + dev_copy = virDomainDeviceDefCopy(dev, vm->def, caps, driver->xmlopt); + if (!dev_copy) + goto cleanup; + } + + if (flags & VIR_DOMAIN_AFFECT_CONFIG) { + /* Make a copy for updated domain. */ + vmdef = virDomainObjCopyPersistentDef(vm, caps, driver->xmlopt); + if (!vmdef) + goto cleanup; + + if (virDomainDefCompatibleDevice(vmdef, dev, + VIR_DOMAIN_DEVICE_ACTION_DETACH) < 0) + goto cleanup; + + if ((ret = qemuDomainDetachDeviceConfig(vmdef, dev, caps, + parse_flags, + driver->xmlopt)) < 0) + goto cleanup; + } + + if (flags & VIR_DOMAIN_AFFECT_LIVE) { + if (virDomainDefCompatibleDevice(vm->def, dev_copy, + VIR_DOMAIN_DEVICE_ACTION_DETACH) < 0) + goto cleanup; + + if ((ret = qemuDomainDetachDeviceLive(vm, dev_copy, driver)) < 0) + goto cleanup; + /* + * update domain status forcibly because the domain status may be + * changed even if we failed to attach the device. For example, + * a new controller may be created. + */ + if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) { + ret = -1; + goto cleanup; + } + } + + /* Finally, if no error until here, we can save config. */ + if (flags & VIR_DOMAIN_AFFECT_CONFIG) { + ret = virDomainSaveConfig(cfg->configDir, driver->caps, vmdef); + if (!ret) { + virDomainObjAssignDef(vm, vmdef, false, NULL); + vmdef = NULL; + } + } + + cleanup: + virObjectUnref(caps); + virObjectUnref(cfg); + if (dev != dev_copy) + virDomainDeviceDefFree(dev_copy); + virDomainDeviceDefFree(dev); + virDomainDefFree(vmdef); + return ret; +} static int qemuDomainDetachDeviceFlags(virDomainPtr dom, @@ -8332,20 +8426,7 @@ qemuDomainDetachDeviceFlags(virDomainPtr dom, { virQEMUDriverPtr driver = dom->conn->privateData; virDomainObjPtr vm = NULL; - virDomainDefPtr vmdef = NULL; - virDomainDeviceDefPtr dev = NULL, dev_copy = NULL; int ret = -1; - unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE; - virQEMUDriverConfigPtr cfg = NULL; - virCapsPtr caps = NULL; - - virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | - VIR_DOMAIN_AFFECT_CONFIG, -1); - - cfg = virQEMUDriverGetConfig(driver); - - if (!(caps = virQEMUDriverGetCapabilities(driver, false))) - goto cleanup; if (!(vm = qemuDomObjFromDomain(dom))) goto cleanup; @@ -8359,81 +8440,16 @@ qemuDomainDetachDeviceFlags(virDomainPtr dom, if (virDomainObjUpdateModificationImpact(vm, &flags) < 0) goto endjob; - if ((flags & VIR_DOMAIN_AFFECT_CONFIG) && - !(flags & VIR_DOMAIN_AFFECT_LIVE)) - parse_flags |= VIR_DOMAIN_DEF_PARSE_INACTIVE; - - dev = dev_copy = virDomainDeviceDefParse(xml, vm->def, - caps, driver->xmlopt, - parse_flags); - if (dev == NULL) + if (qemuDomainDetachDeviceLiveAndConfig(driver, vm, xml, flags) < 0) goto endjob; - if (flags & VIR_DOMAIN_AFFECT_CONFIG && - flags & VIR_DOMAIN_AFFECT_LIVE) { - /* If we are affecting both CONFIG and LIVE - * create a deep copy of device as adding - * to CONFIG takes one instance. - */ - dev_copy = virDomainDeviceDefCopy(dev, vm->def, caps, driver->xmlopt); - if (!dev_copy) - goto endjob; - } - - if (flags & VIR_DOMAIN_AFFECT_CONFIG) { - /* Make a copy for updated domain. */ - vmdef = virDomainObjCopyPersistentDef(vm, caps, driver->xmlopt); - if (!vmdef) - goto endjob; - - if (virDomainDefCompatibleDevice(vmdef, dev, - VIR_DOMAIN_DEVICE_ACTION_DETACH) < 0) - goto endjob; - - if ((ret = qemuDomainDetachDeviceConfig(vmdef, dev, caps, - parse_flags, - driver->xmlopt)) < 0) - goto endjob; - } - - if (flags & VIR_DOMAIN_AFFECT_LIVE) { - if (virDomainDefCompatibleDevice(vm->def, dev_copy, - VIR_DOMAIN_DEVICE_ACTION_DETACH) < 0) - goto endjob; - - if ((ret = qemuDomainDetachDeviceLive(vm, dev_copy, driver)) < 0) - goto endjob; - /* - * update domain status forcibly because the domain status may be - * changed even if we failed to attach the device. For example, - * a new controller may be created. - */ - if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) { - ret = -1; - goto endjob; - } - } - - /* Finally, if no error until here, we can save config. */ - if (flags & VIR_DOMAIN_AFFECT_CONFIG) { - ret = virDomainSaveConfig(cfg->configDir, driver->caps, vmdef); - if (!ret) { - virDomainObjAssignDef(vm, vmdef, false, NULL); - vmdef = NULL; - } - } + ret = 0; endjob: qemuDomainObjEndJob(driver, vm); cleanup: - virDomainDefFree(vmdef); - if (dev != dev_copy) - virDomainDeviceDefFree(dev_copy); - virDomainDeviceDefFree(dev); virDomainObjEndAPI(&vm); - virObjectUnref(caps); - virObjectUnref(cfg); return ret; }