When defining a VM config, we need to apply the following logi - If existing VM has same UUID - If name also matches => allow - Else => raise error
- Else - If name matches => raise error - Else => allow When creating a live VM, or restoring a VM we need to apply similar, but slightly different logic - If existing VM has same UUID - If name also matches - If existing VM is running => raise error - Else => allow - Else => raise error - Else - If name matches => raise error - Else => allow This patch applies those checks for the QEMU driver Daniel diff -r 4e6a98395da5 src/qemu_driver.c --- a/src/qemu_driver.c Thu Apr 30 14:50:14 2009 +0100 +++ b/src/qemu_driver.c Thu Apr 30 15:03:03 2009 +0100 @@ -2145,22 +2145,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]; - - virUUIDFormat(def->uuid, uuidstr); - qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, - _("domain with uuid '%s' is already defined"), - uuidstr); - goto cleanup; + /* 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; + } + 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, @@ -2348,6 +2363,11 @@ static int qemudDomainDestroy(virDomainP _("no domain with matching uuid '%s'"), uuidstr); 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, @@ -3258,17 +3278,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_INVALID, _("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; } } @@ -3603,18 +3642,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; - } + goto cleanup; + } + def = NULL; vm->persistent = 1; if (virDomainSaveConfig(conn, @@ -3636,6 +3698,7 @@ static virDomainPtr qemudDomainDefine(vi if (dom) dom->id = vm->def->id; cleanup: + virDomainDefFree(def); if (vm) virDomainObjUnlock(vm); if (event) -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list