diff -rupN libvirt-0.6.2/src/qemu_driver.c libvirt-0.6.2.new/src/qemu_driver.c --- libvirt-0.6.2/src/qemu_driver.c 2009-08-05 16:25:22.000000000 +0100 +++ libvirt-0.6.2.new/src/qemu_driver.c 2009-08-05 16:27:48.000000000 +0100 @@ -2174,22 +2174,37 @@ static virDomainPtr qemudDomainCreate(vi if (virSecurityDriverVerify(conn, def) < 0) goto cleanup; - vm = virDomainFindByName(&driver->domains, def->name); - if (vm) { - qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, - _("domain '%s' is already defined"), - def->name); - goto cleanup; - } + /* See if a VM with matching UUID already exists */ vm = virDomainFindByUUID(&driver->domains, def->uuid); if (vm) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; + /* UUID matches, but if names don't match, refuse it */ + if (STRNEQ(vm->def->name, def->name)) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virUUIDFormat(vm->def->uuid, uuidstr); + qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("domain '%s' is already defined with uuid %s"), + vm->def->name, uuidstr); + goto cleanup; + } - virUUIDFormat(def->uuid, uuidstr); - qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, - _("domain with uuid '%s' is already defined"), - uuidstr); - goto cleanup; + /* UUID & name match, but if VM is already active, refuse it */ + if (virDomainIsActive(vm)) { + qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("domain is already active as '%s'"), vm->def->name); + goto cleanup; + } + virDomainObjUnlock(vm); + } else { + /* UUID does not match, but if a name matches, refuse it */ + vm = virDomainFindByName(&driver->domains, def->name); + if (vm) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virUUIDFormat(vm->def->uuid, uuidstr); + qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("domain '%s' is already defined with uuid %s"), + def->name, uuidstr); + goto cleanup; + } } if (!(vm = virDomainAssignDef(conn, @@ -2368,6 +2383,11 @@ static int qemudDomainDestroy(virDomainP _("no domain with matching id %d"), dom->id); goto cleanup; } + if (!virDomainIsActive(vm)) { + qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, + "%s", _("domain is not running")); + goto cleanup; + } qemudShutdownVMDaemon(dom->conn, driver, vm); event = virDomainEventNewFromObj(vm, @@ -3272,17 +3292,36 @@ static int qemudDomainRestore(virConnect goto cleanup; } - /* Ensure the name and UUID don't already exist in an active VM */ + /* See if a VM with matching UUID already exists */ vm = virDomainFindByUUID(&driver->domains, def->uuid); - if (!vm) - vm = virDomainFindByName(&driver->domains, def->name); if (vm) { + /* UUID matches, but if names don't match, refuse it */ + if (STRNEQ(vm->def->name, def->name)) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virUUIDFormat(vm->def->uuid, uuidstr); + qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("domain '%s' is already defined with uuid %s"), + vm->def->name, uuidstr); + goto cleanup; + } + + /* UUID & name match, but if VM is already active, refuse it */ if (virDomainIsActive(vm)) { qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, _("domain is already active as '%s'"), vm->def->name); goto cleanup; - } else { - virDomainObjUnlock(vm); + } + virDomainObjUnlock(vm); + } else { + /* UUID does not match, but if a name matches, refuse it */ + vm = virDomainFindByName(&driver->domains, def->name); + if (vm) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virUUIDFormat(vm->def->uuid, uuidstr); + qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("domain '%s' is already defined with uuid %s"), + def->name, uuidstr); + goto cleanup; } } @@ -3470,18 +3509,41 @@ static virDomainPtr qemudDomainDefine(vi if (virSecurityDriverVerify(conn, def) < 0) goto cleanup; - vm = virDomainFindByName(&driver->domains, def->name); + /* See if a VM with matching UUID already exists */ + vm = virDomainFindByUUID(&driver->domains, def->uuid); if (vm) { + /* UUID matches, but if names don't match, refuse it */ + if (STRNEQ(vm->def->name, def->name)) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virUUIDFormat(vm->def->uuid, uuidstr); + qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("domain '%s' is already defined with uuid %s"), + vm->def->name, uuidstr); + goto cleanup; + } + + /* UUID & name match */ virDomainObjUnlock(vm); newVM = 0; + } else { + /* UUID does not match, but if a name matches, refuse it */ + vm = virDomainFindByName(&driver->domains, def->name); + if (vm) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virUUIDFormat(vm->def->uuid, uuidstr); + qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("domain '%s' is already defined with uuid %s"), + def->name, uuidstr); + goto cleanup; + } } if (!(vm = virDomainAssignDef(conn, &driver->domains, def))) { - virDomainDefFree(def); goto cleanup; } + def = NULL; vm->persistent = 1; if (virDomainSaveConfig(conn, @@ -3503,6 +3565,7 @@ static virDomainPtr qemudDomainDefine(vi if (dom) dom->id = vm->def->id; cleanup: + virDomainDefFree(def); if (vm) virDomainObjUnlock(vm); if (event)