2009-08-17 08:08:56 +00:00
|
|
|
From 1f1a0ca63c5492c7d41a0cdbd452a2743f314ebc Mon Sep 17 00:00:00 2001
|
|
|
|
From: Daniel P. Berrange <berrange@redhat.com>
|
|
|
|
Date: Fri, 8 May 2009 10:11:14 +0000
|
|
|
|
Subject: [PATCH] Improve name & UUID uniqueness checking in QEMU driver
|
|
|
|
|
|
|
|
(cherry picked from commit 54ebbde1e18ec831ff2fddb44ec27ed5dde7874a)
|
|
|
|
|
|
|
|
Fedora-patch: libvirt-0.6.2-qemu-name-uniqueness.patch
|
|
|
|
---
|
|
|
|
src/qemu_driver.c | 103 ++++++++++++++++++++++++++++++++++++++++++----------
|
|
|
|
1 files changed, 83 insertions(+), 20 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
|
|
|
|
index 8473616..dfd19c5 100644
|
|
|
|
--- a/src/qemu_driver.c
|
|
|
|
+++ b/src/qemu_driver.c
|
|
|
|
@@ -2174,22 +2174,37 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
|
2009-08-05 15:48:14 +00:00
|
|
|
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,
|
2009-08-17 08:08:56 +00:00
|
|
|
@@ -2368,6 +2383,11 @@ static int qemudDomainDestroy(virDomainPtr dom) {
|
2009-08-05 15:48:14 +00:00
|
|
|
_("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,
|
2009-08-17 08:08:56 +00:00
|
|
|
@@ -3272,17 +3292,36 @@ static int qemudDomainRestore(virConnectPtr conn,
|
2009-08-05 15:48:14 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-17 08:08:56 +00:00
|
|
|
@@ -3470,18 +3509,41 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
|
2009-08-05 15:48:14 +00:00
|
|
|
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,
|
2009-08-17 08:08:56 +00:00
|
|
|
@@ -3503,6 +3565,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
|
2009-08-05 15:48:14 +00:00
|
|
|
if (dom) dom->id = vm->def->id;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
+ virDomainDefFree(def);
|
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
|
|
|
if (event)
|
2009-08-17 08:08:56 +00:00
|
|
|
--
|
|
|
|
1.6.2.5
|
|
|
|
|