[libvirt] [PATCH 1/2] qemu: Break out function to check if we can create/define/restore

Cole Robinson crobinso at redhat.com
Wed Nov 4 20:06:58 UTC 2009


Use this function in the qemu, uml, lxc, and test drivers.

Signed-off-by: Cole Robinson <crobinso at redhat.com>
---
 src/conf/domain_conf.c   |   64 +++++++++++++++++++++++++++++
 src/conf/domain_conf.h   |    4 ++
 src/libvirt_private.syms |    1 +
 src/lxc/lxc_driver.c     |   68 +++----------------------------
 src/qemu/qemu_driver.c   |  102 ++++------------------------------------------
 src/test/test_driver.c   |   14 ++++++-
 src/uml/uml_driver.c     |   20 ++-------
 7 files changed, 100 insertions(+), 173 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7dd3ce7..37209d4 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5014,6 +5014,70 @@ virDomainFSDefPtr virDomainGetRootFilesystem(virDomainDefPtr def)
     return NULL;
 }
 
+/*
+ * virDomainObjIsDuplicate:
+ * @doms : virDomainObjListPtr to search
+ * @def  : virDomainDefPtr definition of domain to lookup
+ * @check_active: If true, ensure that domain is not active
+ *
+ * Returns: -1 on error
+ *          0 if domain is new
+ *          1 if domain is a duplicate
+ */
+int
+virDomainObjIsDuplicate(virDomainObjListPtr doms,
+                        virDomainDefPtr def,
+                        unsigned int check_active)
+{
+    int ret = -1;
+    int dupVM = 0;
+    virDomainObjPtr vm = NULL;
+
+    /* See if a VM with matching UUID already exists */
+    vm = virDomainFindByUUID(doms, 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);
+            virDomainReportError(NULL, VIR_ERR_OPERATION_FAILED,
+                            _("domain '%s' is already defined with uuid %s"),
+                            vm->def->name, uuidstr);
+            goto cleanup;
+        }
+
+        if (check_active) {
+            /* UUID & name match, but if VM is already active, refuse it */
+            if (virDomainObjIsActive(vm)) {
+                virDomainReportError(NULL, VIR_ERR_OPERATION_INVALID,
+                                     _("domain is already active as '%s'"),
+                                     vm->def->name);
+                goto cleanup;
+            }
+        }
+
+        dupVM = 1;
+        virDomainObjUnlock(vm);
+    } else {
+        /* UUID does not match, but if a name matches, refuse it */
+        vm = virDomainFindByName(doms, def->name);
+        if (vm) {
+            char uuidstr[VIR_UUID_STRING_BUFLEN];
+            virUUIDFormat(vm->def->uuid, uuidstr);
+            virDomainReportError(NULL, VIR_ERR_OPERATION_FAILED,
+                                 _("domain '%s' already exists with uuid %s"),
+                                 def->name, uuidstr);
+            goto cleanup;
+        }
+    }
+
+    ret = dupVM;
+cleanup:
+    if (vm)
+        virDomainObjUnlock(vm);
+    return ret;
+}
+
 
 void virDomainObjLock(virDomainObjPtr obj)
 {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 8599ee7..9d3e9e2 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -788,6 +788,10 @@ virDomainFSDefPtr virDomainGetRootFilesystem(virDomainDefPtr def);
 int virDomainVideoDefaultType(virDomainDefPtr def);
 int virDomainVideoDefaultRAM(virDomainDefPtr def, int type);
 
+int virDomainObjIsDuplicate(virDomainObjListPtr doms,
+                            virDomainDefPtr def,
+                            unsigned int check_active);
+
 void virDomainObjLock(virDomainObjPtr obj);
 void virDomainObjUnlock(virDomainObjPtr obj);
 
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 15d75fd..451a883 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -146,6 +146,7 @@ virDomainObjLock;
 virDomainObjUnlock;
 virDomainStateTypeToString;
 virDomainStateTypeFromString;
+virDomainObjIsDuplicate;
 virDomainObjListGetInactiveNames;
 virDomainObjListGetActiveIDs;
 virDomainObjListNumOfDomains;
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 9ab94bf..4c237f2 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -273,41 +273,15 @@ static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml)
     virDomainObjPtr vm = NULL;
     virDomainPtr dom = NULL;
     virDomainEventPtr event = NULL;
-    int newVM = 1;
+    int dupVM;
 
     lxcDriverLock(driver);
     if (!(def = virDomainDefParseString(conn, driver->caps, xml,
                                         VIR_DOMAIN_XML_INACTIVE)))
         goto cleanup;
 
-    /* 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);
-            lxcError(conn, 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);
-            lxcError(conn, NULL, VIR_ERR_OPERATION_FAILED,
-                     _("domain '%s' is already defined with uuid %s"),
-                     def->name, uuidstr);
-            goto cleanup;
-        }
-    }
+   if ((dupVM = virDomainObjIsDuplicate(&driver->domains, def, 0)) < 0)
+        goto cleanup;
 
     if ((def->nets != NULL) && !(driver->have_netns)) {
         lxcError(conn, NULL, VIR_ERR_NO_SUPPORT,
@@ -331,7 +305,7 @@ static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml)
 
     event = virDomainEventNewFromObj(vm,
                                      VIR_DOMAIN_EVENT_DEFINED,
-                                     newVM ?
+                                     !dupVM ?
                                      VIR_DOMAIN_EVENT_DEFINED_ADDED :
                                      VIR_DOMAIN_EVENT_DEFINED_UPDATED);
 
@@ -1273,38 +1247,8 @@ lxcDomainCreateAndStart(virConnectPtr conn,
                                         VIR_DOMAIN_XML_INACTIVE)))
         goto cleanup;
 
-    /* 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);
-            lxcError(conn, 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 (virDomainObjIsActive(vm)) {
-            lxcError(conn, 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);
-            lxcError(conn, NULL, VIR_ERR_OPERATION_FAILED,
-                     _("domain '%s' is already defined with uuid %s"),
-                     def->name, uuidstr);
-            goto cleanup;
-        }
-    }
+    if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
+        goto cleanup;
 
     if ((def->nets != NULL) && !(driver->have_netns)) {
         lxcError(conn, NULL, VIR_ERR_NO_SUPPORT,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5ff7e94..20621d1 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2638,38 +2638,8 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
     if (virSecurityDriverVerify(conn, def) < 0)
         goto cleanup;
 
-    /* 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, but if VM is already active, refuse it */
-        if (virDomainObjIsActive(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 (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
+        goto cleanup;
 
     if (!(vm = virDomainAssignDef(conn,
                                   driver->caps,
@@ -3699,38 +3669,8 @@ static int qemudDomainRestore(virConnectPtr conn,
         goto cleanup;
     }
 
-    /* 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, but if VM is already active, refuse it */
-        if (virDomainObjIsActive(vm)) {
-            qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_INVALID,
-                             _("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 (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
+        goto cleanup;
 
     if (!(vm = virDomainAssignDef(conn,
                                   driver->caps,
@@ -4177,7 +4117,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
     virDomainObjPtr vm = NULL;
     virDomainPtr dom = NULL;
     virDomainEventPtr event = NULL;
-    int newVM = 1;
+    int dupVM;
 
     qemuDriverLock(driver);
     if (!(def = virDomainDefParseString(conn, driver->caps, xml,
@@ -4187,34 +4127,8 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
     if (virSecurityDriverVerify(conn, def) < 0)
         goto cleanup;
 
-    /* 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 ((dupVM = virDomainObjIsDuplicate(&driver->domains, def, 0)) < 0)
+        goto cleanup;
 
     if (qemudCanonicalizeMachine(driver, def) < 0)
         goto cleanup;
@@ -4239,7 +4153,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
 
     event = virDomainEventNewFromObj(vm,
                                      VIR_DOMAIN_EVENT_DEFINED,
-                                     newVM ?
+                                     !dupVM ?
                                      VIR_DOMAIN_EVENT_DEFINED_ADDED :
                                      VIR_DOMAIN_EVENT_DEFINED_UPDATED);
 
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 343834c..fb367c9 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -1242,6 +1242,9 @@ testDomainCreateXML(virConnectPtr conn, const char *xml,
                                        VIR_DOMAIN_XML_INACTIVE)) == NULL)
         goto cleanup;
 
+    if (virDomainObjIsDuplicate(&privconn->domains, def, 1) < 0)
+        goto cleanup;
+
     if (testDomainGenerateIfnames(conn, def) < 0)
         goto cleanup;
     if (!(dom = virDomainAssignDef(conn, privconn->caps,
@@ -1785,6 +1788,9 @@ static int testDomainRestore(virConnectPtr conn,
     if (!def)
         goto cleanup;
 
+    if (virDomainObjIsDuplicate(&privconn->domains, def, 1) < 0)
+        goto cleanup;
+
     if (testDomainGenerateIfnames(conn, def) < 0)
         goto cleanup;
     if (!(dom = virDomainAssignDef(conn, privconn->caps,
@@ -2224,12 +2230,16 @@ static virDomainPtr testDomainDefineXML(virConnectPtr conn,
     virDomainDefPtr def;
     virDomainObjPtr dom = NULL;
     virDomainEventPtr event = NULL;
+    int dupVM;
 
     testDriverLock(privconn);
     if ((def = virDomainDefParseString(conn, privconn->caps, xml,
                                        VIR_DOMAIN_XML_INACTIVE)) == NULL)
         goto cleanup;
 
+    if ((dupVM = virDomainObjIsDuplicate(&privconn->domains, def, 0)) < 0)
+        goto cleanup;
+
     if (testDomainGenerateIfnames(conn, def) < 0)
         goto cleanup;
     if (!(dom = virDomainAssignDef(conn, privconn->caps,
@@ -2240,7 +2250,9 @@ static virDomainPtr testDomainDefineXML(virConnectPtr conn,
 
     event = virDomainEventNewFromObj(dom,
                                      VIR_DOMAIN_EVENT_DEFINED,
-                                     VIR_DOMAIN_EVENT_DEFINED_ADDED);
+                                     !dupVM ?
+                                     VIR_DOMAIN_EVENT_DEFINED_ADDED :
+                                     VIR_DOMAIN_EVENT_DEFINED_UPDATED);
 
     ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
     if (ret)
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index 212cd8f..0604742 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -1178,23 +1178,8 @@ static virDomainPtr umlDomainCreate(virConnectPtr conn, const char *xml,
                                         VIR_DOMAIN_XML_INACTIVE)))
         goto cleanup;
 
-    vm = virDomainFindByName(&driver->domains, def->name);
-    if (vm) {
-        umlReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
-                         _("domain '%s' is already defined"),
-                         def->name);
+    if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
         goto cleanup;
-    }
-    vm = virDomainFindByUUID(&driver->domains, def->uuid);
-    if (vm) {
-        char uuidstr[VIR_UUID_STRING_BUFLEN];
-
-        virUUIDFormat(def->uuid, uuidstr);
-        umlReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
-                         _("domain with uuid '%s' is already defined"),
-                         uuidstr);
-        goto cleanup;
-    }
 
     if (!(vm = virDomainAssignDef(conn,
                                   driver->caps,
@@ -1531,6 +1516,9 @@ static virDomainPtr umlDomainDefine(virConnectPtr conn, const char *xml) {
                                         VIR_DOMAIN_XML_INACTIVE)))
         goto cleanup;
 
+    if (virDomainObjIsDuplicate(&driver->domains, def, 0) < 0)
+        goto cleanup;
+
     if (!(vm = virDomainAssignDef(conn,
                                   driver->caps,
                                   &driver->domains,
-- 
1.6.5.1




More information about the libvir-list mailing list