]> xenbits.xensource.com Git - libvirt.git/commitdiff
Improve name & UUID uniqueness checking in QEMU driver
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 8 May 2009 10:11:14 +0000 (10:11 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 8 May 2009 10:11:14 +0000 (10:11 +0000)
ChangeLog
src/qemu_driver.c

index a9bba46bd4df061eeff4fc3a7fc7d7f088f660c8..7f2c44078c2f0382b7da7a6a4d05eb6c0d09dabe 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Fri May  8 11:10:22 BST 2009 Daniel P. Berrange <berrange@redhat.com>
+
+       * src/qemu_driver.c: Make name & UUID uniqueness checking in
+       define, create & restore functions more robust. Throw error
+       in destory operation, if guest isn't running
+
 Fri May  8 11:07:22 BST 2009 Daniel P. Berrange <berrange@redhat.com>
 
        * src/qemu_conf.c: Enable migrate/save/restore for QEMU
index 404d773018428fb5212092053a7705fff1330bf6..7a46b1c06b7661e78b6f888bd3c671db46098623 100644 (file)
@@ -2147,22 +2147,37 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
     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,
@@ -2350,6 +2365,11 @@ static int qemudDomainDestroy(virDomainPtr dom) {
                          _("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,
@@ -3270,17 +3290,36 @@ static int qemudDomainRestore(virConnectPtr conn,
         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;
         }
     }
 
@@ -3470,18 +3509,41 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
     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(virConnectPtr conn, const char *xml) {
     if (dom) dom->id = vm->def->id;
 
 cleanup:
+    virDomainDefFree(def);
     if (vm)
         virDomainObjUnlock(vm);
     if (event)