提交 9eee40cc 编写于 作者: M Michal Privoznik

qemu: Fix define logic

With current flow in qemudDomainDefine we might lose data
when updating an existing domain. We parse given XML and
overwrite the configuration.  Then we try to save the new
config. However, this step may fail and we don't perform any
roll back.  In fact, we remove the domain from the list of
domains held up by qemu driver. This is okay as long as the
domain was brand new one.
上级 3e0cc630
...@@ -5540,6 +5540,7 @@ out: ...@@ -5540,6 +5540,7 @@ out:
static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) { static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
struct qemud_driver *driver = conn->privateData; struct qemud_driver *driver = conn->privateData;
virDomainDefPtr def; virDomainDefPtr def;
virDomainDefPtr def_backup = NULL;
virDomainObjPtr vm = NULL; virDomainObjPtr vm = NULL;
virDomainPtr dom = NULL; virDomainPtr dom = NULL;
virDomainEventPtr event = NULL; virDomainEventPtr event = NULL;
...@@ -5563,20 +5564,48 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) { ...@@ -5563,20 +5564,48 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
if (qemuDomainAssignAddresses(def, NULL, NULL) < 0) if (qemuDomainAssignAddresses(def, NULL, NULL) < 0)
goto cleanup; goto cleanup;
/* We need to differentiate two cases:
* a) updating an existing domain - must preserve previous definition
* so we can roll back if something fails
* b) defining a brand new domain - virDomainAssignDef is just sufficient
*/
if ((vm = virDomainFindByUUID(&driver->domains, def->uuid))) {
if (virDomainObjIsActive(vm)) {
def_backup = vm->newDef;
vm->newDef = def;
} else {
def_backup = vm->def;
vm->def = def;
}
} else {
if (!(vm = virDomainAssignDef(driver->caps, if (!(vm = virDomainAssignDef(driver->caps,
&driver->domains, &driver->domains,
def, false))) { def, false))) {
goto cleanup; goto cleanup;
} }
}
def = NULL; def = NULL;
vm->persistent = 1; vm->persistent = 1;
if (virDomainSaveConfig(driver->configDir, if (virDomainSaveConfig(driver->configDir,
vm->newDef ? vm->newDef : vm->def) < 0) { vm->newDef ? vm->newDef : vm->def) < 0) {
VIR_INFO("Defining domain '%s'", vm->def->name); if (def_backup) {
/* There is backup so this VM was defined before.
* Just restore the backup. */
VIR_INFO("Restoring domain '%s' definition", vm->def->name);
if (virDomainObjIsActive(vm))
vm->newDef = def_backup;
else
vm->def = def_backup;
} else {
/* Brand new domain. Remove it */
VIR_INFO("Deleting domain '%s'", vm->def->name);
qemuDomainRemoveInactive(driver, vm); qemuDomainRemoveInactive(driver, vm);
vm = NULL; vm = NULL;
}
goto cleanup; goto cleanup;
} else {
virDomainDefFree(def_backup);
} }
event = virDomainEventNewFromObj(vm, event = virDomainEventNewFromObj(vm,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册