[libvirt] [PATCH v2 04/13] Merge virDomainObjListIsDuplicate into virDomainObjListAdd

Daniel P. Berrange berrange at redhat.com
Mon Jan 21 14:48:05 UTC 2013


From: "Daniel P. Berrange" <berrange at redhat.com>

The duplicate VM checking should be done atomically with
virDomainObjListAdd, so shoud not be a separate function.
Instead just use flags to indicate what kind of checks are
required.

This pair, used in virDomainCreateXML:

   if (virDomainObjListIsDuplicate(privconn->domains, def, 1) < 0)
     goto cleanup;
   if (!(dom = virDomainObjListAdd(privconn->domains,
                                   privconn->caps,
                                   def, false)))
     goto cleanup;

Changes to

   if (!(dom = virDomainObjListAdd(privconn->domains,
                                   privconn->caps,
                                   def,
                                   VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
                                   NULL)))
     goto cleanup;

This pair, used in virDomainRestoreFlags:

   if (virDomainObjListIsDuplicate(privconn->domains, def, 1) < 0)
     goto cleanup;
   if (!(dom = virDomainObjListAdd(privconn->domains,
                                   privconn->caps,
                                   def, true)))
     goto cleanup;

Changes to

   if (!(dom = virDomainObjListAdd(privconn->domains,
                                   privconn->caps,
                                   def,
                                   VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
                                   VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
                                   NULL)))
     goto cleanup;

This pair, used in virDomainDefinXML:

   if (virDomainObjListIsDuplicate(privconn->domains, def, 0) < 0)
     goto cleanup;
   if (!(dom = virDomainObjListAdd(privconn->domains,
                                   privconn->caps,
                                   def, false)))
     goto cleanup;

Changes to

   if (!(dom = virDomainObjListAdd(privconn->domains,
                                   privconn->caps,
                                   def,
                                   0, NULL)))
     goto cleanup;
---
 src/conf/domain_conf.c           | 156 +++++++++++++++++++--------------------
 src/conf/domain_conf.h           |  11 +--
 src/libxl/libxl_driver.c         |  27 ++++---
 src/lxc/lxc_driver.c             |  19 +++--
 src/openvz/openvz_conf.c         |  12 +--
 src/openvz/openvz_driver.c       |   6 +-
 src/parallels/parallels_driver.c |  16 ++--
 src/qemu/qemu_driver.c           |  71 +++++++-----------
 src/qemu/qemu_migration.c        |  11 ++-
 src/test/test_driver.c           |  31 ++++----
 src/uml/uml_driver.c             |  13 ++--
 src/vmware/vmware_conf.c         |   2 +-
 src/vmware/vmware_driver.c       |  12 +--
 13 files changed, 174 insertions(+), 213 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e9cc696..02fcd84 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1873,30 +1873,91 @@ void virDomainObjAssignDef(virDomainObjPtr domain,
     }
 }
 
+
+
+/*
+ *
+ * If flags & VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE then
+ * this will refuse updating an existing def if the
+ * current def is Live
+ *
+ */
 virDomainObjPtr virDomainObjListAdd(virDomainObjListPtr doms,
                                     virCapsPtr caps,
                                     const virDomainDefPtr def,
-                                    bool live)
+                                    unsigned int flags,
+                                    virDomainDefPtr *oldDef)
 {
-    virDomainObjPtr domain;
+    virDomainObjPtr vm;
     char uuidstr[VIR_UUID_STRING_BUFLEN];
+    if (oldDef)
+        *oldDef = false;
 
-    if ((domain = virDomainObjListFindByUUID(doms, def->uuid))) {
-        virDomainObjAssignDef(domain, def, live);
-        return domain;
-    }
+    /* See if a VM with matching UUID already exists */
+    if ((vm = virDomainObjListFindByUUID(doms, def->uuid))) {
+        /* UUID matches, but if names don't match, refuse it */
+        if (STRNEQ(vm->def->name, def->name)) {
+            virUUIDFormat(vm->def->uuid, uuidstr);
+            virReportError(VIR_ERR_OPERATION_FAILED,
+                           _("domain '%s' is already defined with uuid %s"),
+                           vm->def->name, uuidstr);
+            goto cleanup;
+        }
 
-    if (!(domain = virDomainObjNew(caps)))
-        return NULL;
-    domain->def = def;
+        if (flags & VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE) {
+            /* UUID & name match, but if VM is already active, refuse it */
+            if (virDomainObjIsActive(vm)) {
+                virReportError(VIR_ERR_OPERATION_INVALID,
+                               _("domain is already active as '%s'"),
+                               vm->def->name);
+                goto cleanup;
+            }
+        }
 
-    virUUIDFormat(def->uuid, uuidstr);
-    if (virHashAddEntry(doms->objs, uuidstr, domain) < 0) {
-        VIR_FREE(domain);
-        return NULL;
-    }
+        if (virDomainObjIsActive(vm)) {
+            if (oldDef)
+                *oldDef = vm->newDef;
+            else
+                virDomainDefFree(vm->newDef);
+            vm->newDef = def;
+        } else {
+            if (flags & VIR_DOMAIN_OBJ_LIST_ADD_LIVE) {
+                if (!vm->newDef)
+                    vm->newDef = vm->def;
+                else
+                    virDomainDefFree(vm->newDef);
+            } else {
+                if (oldDef)
+                    *oldDef = vm->def;
+                else
+                    virDomainDefFree(vm->def);
+            }
+            vm->def = def;
+        }
+    } else {
+        /* UUID does not match, but if a name matches, refuse it */
+        if ((vm = virDomainObjListFindByName(doms, def->name))) {
+            virUUIDFormat(vm->def->uuid, uuidstr);
+            virReportError(VIR_ERR_OPERATION_FAILED,
+                           _("domain '%s' already exists with uuid %s"),
+                           def->name, uuidstr);
+            virObjectUnlock(vm);
+            vm = NULL;
+            goto cleanup;
+        }
 
-    return domain;
+        if (!(vm = virDomainObjNew(caps)))
+            goto cleanup;
+        vm->def = def;
+
+        virUUIDFormat(def->uuid, uuidstr);
+        if (virHashAddEntry(doms->objs, uuidstr, vm) < 0) {
+            VIR_FREE(vm);
+            return NULL;
+        }
+    }
+cleanup:
+    return vm;
 }
 
 /*
@@ -14833,7 +14894,7 @@ virDomainObjListLoadConfig(virDomainObjListPtr doms,
         return dom;
     }
 
-    if (!(dom = virDomainObjListAdd(doms, caps, def, false)))
+    if (!(dom = virDomainObjListAdd(doms, caps, def, 0, NULL)))
         goto error;
 
     dom->autostart = autostart;
@@ -15059,69 +15120,6 @@ virDomainFSDefPtr virDomainGetRootFilesystem(virDomainDefPtr def)
     return NULL;
 }
 
-/*
- * virDomainObjListIsDuplicate:
- * @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
-virDomainObjListIsDuplicate(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 = virDomainObjListFindByUUID(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);
-            virReportError(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)) {
-                virReportError(VIR_ERR_OPERATION_INVALID,
-                               _("domain is already active as '%s'"),
-                               vm->def->name);
-                goto cleanup;
-            }
-        }
-
-        dupVM = 1;
-    } else {
-        /* UUID does not match, but if a name matches, refuse it */
-        vm = virDomainObjListFindByName(doms, def->name);
-        if (vm) {
-            char uuidstr[VIR_UUID_STRING_BUFLEN];
-            virUUIDFormat(vm->def->uuid, uuidstr);
-            virReportError(VIR_ERR_OPERATION_FAILED,
-                           _("domain '%s' already exists with uuid %s"),
-                           def->name, uuidstr);
-            goto cleanup;
-        }
-    }
-
-    ret = dupVM;
-cleanup:
-    if (vm)
-        virObjectUnlock(vm);
-    return ret;
-}
-
 
 static void virDomainObjListCountActive(void *payload, const void *name ATTRIBUTE_UNUSED, void *data)
 {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index e534ca8..5eed85d 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1967,10 +1967,15 @@ virDomainChrDefPtr virDomainChrDefNew(void);
 
 /* live == true means def describes an active domain (being migrated or
  * restored) as opposed to a new persistent configuration of the domain */
+enum {
+    VIR_DOMAIN_OBJ_LIST_ADD_LIVE = (1 << 0),
+    VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE = (1 << 1),
+};
 virDomainObjPtr virDomainObjListAdd(virDomainObjListPtr doms,
                                     virCapsPtr caps,
                                     const virDomainDefPtr def,
-                                    bool live);
+                                    unsigned int flags,
+                                    virDomainDefPtr *oldDef);
 void virDomainObjAssignDef(virDomainObjPtr domain,
                            const virDomainDefPtr def,
                            bool live);
@@ -2155,10 +2160,6 @@ int virDomainFSIndexByName(virDomainDefPtr def, const char *name);
 int virDomainVideoDefaultType(virDomainDefPtr def);
 int virDomainVideoDefaultRAM(virDomainDefPtr def, int type);
 
-int virDomainObjListIsDuplicate(virDomainObjListPtr doms,
-                                virDomainDefPtr def,
-                                unsigned int check_active);
-
 int virDomainObjListNumOfDomains(virDomainObjListPtr doms, int active);
 
 int virDomainObjListGetActiveIDs(virDomainObjListPtr doms,
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index a79a9ff..d72ca34 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -1305,12 +1305,11 @@ libxlDomainCreateXML(virConnectPtr conn, const char *xml,
                                         VIR_DOMAIN_XML_INACTIVE)))
         goto cleanup;
 
-    if (virDomainObjListIsDuplicate(driver->domains, def, 1) < 0)
-        goto cleanup;
-
     if (!(vm = virDomainObjListAdd(driver->domains,
                                    driver->caps,
-                                   def, false)))
+                                   def,
+                                   VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
+                                   NULL)))
         goto cleanup;
     def = NULL;
 
@@ -2084,12 +2083,12 @@ libxlDomainRestoreFlags(virConnectPtr conn, const char *from,
     if (fd < 0)
         goto cleanup;
 
-    if (virDomainObjListIsDuplicate(driver->domains, def, 1) < 0)
-        goto cleanup;
-
     if (!(vm = virDomainObjListAdd(driver->domains,
                                    driver->caps,
-                                   def, true)))
+                                   def,
+                                   VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
+                                   VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
+                                   NULL)))
         goto cleanup;
 
     def = NULL;
@@ -2865,7 +2864,7 @@ libxlDomainDefineXML(virConnectPtr conn, const char *xml)
     virDomainObjPtr vm = NULL;
     virDomainPtr dom = NULL;
     virDomainEventPtr event = NULL;
-    int dupVM;
+    virDomainDefPtr oldDef = NULL;
 
     libxlDriverLock(driver);
     if (!(def = virDomainDefParseString(driver->caps, xml,
@@ -2873,12 +2872,11 @@ libxlDomainDefineXML(virConnectPtr conn, const char *xml)
                                         VIR_DOMAIN_XML_INACTIVE)))
         goto cleanup;
 
-   if ((dupVM = virDomainObjListIsDuplicate(driver->domains, def, 0)) < 0)
-        goto cleanup;
-
     if (!(vm = virDomainObjListAdd(driver->domains,
                                    driver->caps,
-                                   def, false)))
+                                   def,
+                                   0,
+                                   &oldDef)))
         goto cleanup;
     def = NULL;
     vm->persistent = 1;
@@ -2895,12 +2893,13 @@ libxlDomainDefineXML(virConnectPtr conn, const char *xml)
         dom->id = vm->def->id;
 
     event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_DEFINED,
-                                     !dupVM ?
+                                     !oldDef ?
                                      VIR_DOMAIN_EVENT_DEFINED_ADDED :
                                      VIR_DOMAIN_EVENT_DEFINED_UPDATED);
 
 cleanup:
     virDomainDefFree(def);
+    virDomainDefFree(oldDef);
     if (vm)
         virObjectUnlock(vm);
     if (event)
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index db183c8..f7ca70d 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -410,7 +410,7 @@ static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml)
     virDomainObjPtr vm = NULL;
     virDomainPtr dom = NULL;
     virDomainEventPtr event = NULL;
-    int dupVM;
+    virDomainDefPtr oldDef = NULL;
 
     lxcDriverLock(driver);
     if (!(def = virDomainDefParseString(driver->caps, xml,
@@ -421,9 +421,6 @@ static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml)
     if (virSecurityManagerVerify(driver->securityManager, def) < 0)
         goto cleanup;
 
-    if ((dupVM = virDomainObjListIsDuplicate(driver->domains, def, 0)) < 0)
-        goto cleanup;
-
     if ((def->nets != NULL) && !(driver->have_netns)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
                        "%s", _("System lacks NETNS support"));
@@ -432,7 +429,9 @@ static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml)
 
     if (!(vm = virDomainObjListAdd(driver->domains,
                                    driver->caps,
-                                   def, false)))
+                                   def,
+                                   0,
+                                   &oldDef)))
         goto cleanup;
     def = NULL;
     vm->persistent = 1;
@@ -446,7 +445,7 @@ static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml)
 
     event = virDomainEventNewFromObj(vm,
                                      VIR_DOMAIN_EVENT_DEFINED,
-                                     !dupVM ?
+                                     !oldDef ?
                                      VIR_DOMAIN_EVENT_DEFINED_ADDED :
                                      VIR_DOMAIN_EVENT_DEFINED_UPDATED);
 
@@ -456,6 +455,7 @@ static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml)
 
 cleanup:
     virDomainDefFree(def);
+    virDomainDefFree(oldDef);
     if (vm)
         virObjectUnlock(vm);
     if (event)
@@ -1076,9 +1076,6 @@ lxcDomainCreateAndStart(virConnectPtr conn,
     if (virSecurityManagerVerify(driver->securityManager, def) < 0)
         goto cleanup;
 
-    if (virDomainObjListIsDuplicate(driver->domains, def, 1) < 0)
-        goto cleanup;
-
     if ((def->nets != NULL) && !(driver->have_netns)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        "%s", _("System lacks NETNS support"));
@@ -1088,7 +1085,9 @@ lxcDomainCreateAndStart(virConnectPtr conn,
 
     if (!(vm = virDomainObjListAdd(driver->domains,
                                    driver->caps,
-                                   def, false)))
+                                   def,
+                                   VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
+                                   NULL)))
         goto cleanup;
     def = NULL;
 
diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c
index 6eacbca..84ba3d6 100644
--- a/src/openvz/openvz_conf.c
+++ b/src/openvz/openvz_conf.c
@@ -642,17 +642,13 @@ int openvzLoadDomains(struct openvz_driver *driver) {
         openvzReadMemConf(def, veid);
 
         virUUIDFormat(def->uuid, uuidstr);
-        if (virDomainObjListIsDuplicate(driver->domains, def, true)) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("Duplicate container UUID %s detected for %d"),
-                           uuidstr,
-                           veid);
-            goto cleanup;
-        }
         if (!(dom = virDomainObjListAdd(driver->domains,
                                         driver->caps,
                                         def,
-                                        STRNEQ(status, "stopped"))))
+                                        VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE |
+                                        (STRNEQ(status, "stopped") ?
+                                         VIR_DOMAIN_OBJ_LIST_ADD_LIVE : 0),
+                                        NULL)))
             goto cleanup;
 
         if (STREQ(status, "stopped")) {
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index 24d4202..0cb5a1c 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -969,7 +969,7 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml)
     }
     if (!(vm = virDomainObjListAdd(driver->domains,
                                    driver->caps,
-                                   vmdef, false)))
+                                   vmdef, 0, NULL)))
         goto cleanup;
     vmdef = NULL;
     vm->persistent = 1;
@@ -1056,7 +1056,9 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml,
     }
     if (!(vm = virDomainObjListAdd(driver->domains,
                                    driver->caps,
-                                   vmdef, false)))
+                                   vmdef,
+                                   VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
+                                   NULL)))
         goto cleanup;
     vmdef = NULL;
     /* All OpenVZ domains seem to be persistent - this is a bit of a violation
diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c
index ca1f862..02fbf03 100644
--- a/src/parallels/parallels_driver.c
+++ b/src/parallels/parallels_driver.c
@@ -832,7 +832,7 @@ parallelsLoadDomain(parallelsConnPtr privconn, virJSONValuePtr jobj)
 
     if (!(dom = virDomainObjListAdd(privconn->domains,
                                     privconn->caps,
-                                    def, false)))
+                                    def, 0, NULL)))
         goto cleanup;
     /* dom is locked here */
 
@@ -2316,7 +2316,6 @@ parallelsDomainDefineXML(virConnectPtr conn, const char *xml)
     virDomainPtr ret = NULL;
     virDomainDefPtr def;
     virDomainObjPtr dom = NULL, olddom = NULL;
-    int dupVM;
 
     parallelsDriverLock(privconn);
     if ((def = virDomainDefParseString(privconn->caps, xml,
@@ -2327,14 +2326,9 @@ parallelsDomainDefineXML(virConnectPtr conn, const char *xml)
         goto cleanup;
     }
 
-    if ((dupVM = virDomainObjListIsDuplicate(privconn->domains, def, 0)) < 0) {
-        virReportError(VIR_ERR_INVALID_ARG, "%s", _("Already exists"));
-        goto cleanup;
-    }
-
-    if (dupVM == 1) {
-        olddom = virDomainObjListFindByUUID(privconn->domains, def->uuid);
-    } else {
+    olddom = virDomainObjListFindByUUID(privconn->domains, def->uuid);
+    if (olddom == NULL) {
+        virResetLastError();
         if (STREQ(def->os.type, "hvm")) {
             if (parallelsCreateVm(conn, def))
                 goto cleanup;
@@ -2365,7 +2359,7 @@ parallelsDomainDefineXML(virConnectPtr conn, const char *xml)
 
     if (!(dom = virDomainObjListAdd(privconn->domains,
                                     privconn->caps,
-                                    def, false))) {
+                                    def, 0, NULL))) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("Can't allocate domobj"));
         goto cleanup;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 97f010b..603c4fa 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1590,9 +1590,6 @@ static virDomainPtr qemuDomainCreate(virConnectPtr conn, const char *xml,
     if (virSecurityManagerVerify(driver->securityManager, def) < 0)
         goto cleanup;
 
-    if (virDomainObjListIsDuplicate(driver->domains, def, 1) < 0)
-        goto cleanup;
-
     if (!(caps = qemuCapsCacheLookup(driver->capsCache, def->emulator)))
         goto cleanup;
 
@@ -1604,7 +1601,9 @@ static virDomainPtr qemuDomainCreate(virConnectPtr conn, const char *xml,
 
     if (!(vm = virDomainObjListAdd(driver->domains,
                                    driver->caps,
-                                   def, false)))
+                                   def,
+                                   VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
+                                   NULL)))
         goto cleanup;
 
     def = NULL;
@@ -4993,15 +4992,13 @@ qemuDomainRestoreFlags(virConnectPtr conn,
     if (fd < 0)
         goto cleanup;
 
-    if (virDomainObjListIsDuplicate(driver->domains, def, 1) < 0)
-        goto cleanup;
-
     if (!(vm = virDomainObjListAdd(driver->domains,
                                    driver->caps,
-                                   def, true))) {
-        /* virDomainLitsAdd already set the error */
+                                   def,
+                                   VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
+                                   VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
+                                   NULL)))
         goto cleanup;
-    }
     def = NULL;
 
     if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
@@ -5591,12 +5588,11 @@ qemuDomainStart(virDomainPtr dom)
 static virDomainPtr qemuDomainDefine(virConnectPtr conn, const char *xml) {
     virQEMUDriverPtr driver = conn->privateData;
     virDomainDefPtr def;
-    virDomainDefPtr def_backup = NULL;
+    virDomainDefPtr oldDef = NULL;
     virDomainObjPtr vm = NULL;
     virDomainPtr dom = NULL;
     virDomainEventPtr event = NULL;
     qemuCapsPtr caps = NULL;
-    int dupVM;
     virQEMUDriverConfigPtr cfg;
 
     qemuDriverLock(driver);
@@ -5609,9 +5605,6 @@ static virDomainPtr qemuDomainDefine(virConnectPtr conn, const char *xml) {
     if (virSecurityManagerVerify(driver->securityManager, def) < 0)
         goto cleanup;
 
-    if ((dupVM = virDomainObjListIsDuplicate(driver->domains, def, 0)) < 0)
-        goto cleanup;
-
     if (!(caps = qemuCapsCacheLookup(driver->capsCache, def->emulator)))
         goto cleanup;
 
@@ -5621,26 +5614,14 @@ static virDomainPtr qemuDomainDefine(virConnectPtr conn, const char *xml) {
     if (qemuDomainAssignAddresses(def, caps, NULL) < 0)
         goto cleanup;
 
-    /* We need to differentiate two cases:
-     * a) updating an existing domain - must preserve previous definition
-     *                                  so we can roll back if something fails
-     * b) defining a brand new domain - virDomainObjListAdd is just sufficient
-     */
-    if ((vm = virDomainObjListFindByUUID(driver->domains, def->uuid))) {
-        if (virDomainObjIsActive(vm)) {
-            def_backup = vm->newDef;
-            vm->newDef = def;
-        } else {
-            def_backup = vm->def;
-            vm->def = def;
-        }
-    } else {
-        if (!(vm = virDomainObjListAdd(driver->domains,
-                                       driver->caps,
-                                       def, false))) {
-            goto cleanup;
-        }
-    }
+    if (!(vm = virDomainObjListAdd(driver->domains,
+                                   driver->caps,
+                                   def,
+                                   VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
+                                   VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
+                                   &oldDef)))
+        goto cleanup;
+
     def = NULL;
     if (virDomainHasDiskMirror(vm)) {
         virReportError(VIR_ERR_BLOCK_COPY_ACTIVE, "%s",
@@ -5652,14 +5633,15 @@ static virDomainPtr qemuDomainDefine(virConnectPtr conn, const char *xml) {
 
     if (virDomainSaveConfig(cfg->configDir,
                             vm->newDef ? vm->newDef : vm->def) < 0) {
-        if (def_backup) {
+        if (oldDef) {
             /* There is backup so this VM was defined before.
              * Just restore the backup. */
             VIR_INFO("Restoring domain '%s' definition", vm->def->name);
             if (virDomainObjIsActive(vm))
-                vm->newDef = def_backup;
+                vm->newDef = oldDef;
             else
-                vm->def = def_backup;
+                vm->def = oldDef;
+            oldDef = NULL;
         } else {
             /* Brand new domain. Remove it */
             VIR_INFO("Deleting domain '%s'", vm->def->name);
@@ -5667,13 +5649,11 @@ static virDomainPtr qemuDomainDefine(virConnectPtr conn, const char *xml) {
             vm = NULL;
         }
         goto cleanup;
-    } else {
-        virDomainDefFree(def_backup);
     }
 
     event = virDomainEventNewFromObj(vm,
                                      VIR_DOMAIN_EVENT_DEFINED,
-                                     !dupVM ?
+                                     !oldDef ?
                                      VIR_DOMAIN_EVENT_DEFINED_ADDED :
                                      VIR_DOMAIN_EVENT_DEFINED_UPDATED);
 
@@ -5682,6 +5662,7 @@ static virDomainPtr qemuDomainDefine(virConnectPtr conn, const char *xml) {
     if (dom) dom->id = vm->def->id;
 
 cleanup:
+    virDomainDefFree(oldDef);
     virDomainDefFree(def);
     if (vm)
         virObjectUnlock(vm);
@@ -12592,9 +12573,6 @@ static virDomainPtr qemuDomainAttach(virConnectPtr conn,
     if (!(caps = qemuCapsCacheLookup(driver->capsCache, def->emulator)))
         goto cleanup;
 
-    if (virDomainObjListIsDuplicate(driver->domains, def, 1) < 0)
-        goto cleanup;
-
     if (qemuCanonicalizeMachine(def, caps) < 0)
         goto cleanup;
 
@@ -12603,7 +12581,10 @@ static virDomainPtr qemuDomainAttach(virConnectPtr conn,
 
     if (!(vm = virDomainObjListAdd(driver->domains,
                                    driver->caps,
-                                   def, false)))
+                                   def,
+                                   VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
+                                   VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
+                                   NULL)))
         goto cleanup;
 
     def = NULL;
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 5e10876..c59a540 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1639,15 +1639,14 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
         }
     }
 
-    if (virDomainObjListIsDuplicate(driver->domains, def, 1) < 0)
-        goto cleanup;
-
     if (!(vm = virDomainObjListAdd(driver->domains,
                                    driver->caps,
-                                   def, true))) {
-        /* virDomainAssignDef already set the error */
+                                   def,
+                                   VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
+                                   VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
+                                   NULL)))
         goto cleanup;
-    }
+
     def = NULL;
     priv = vm->privateData;
     priv->origname = origname;
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index c4685b7..a81f042 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -566,7 +566,7 @@ static int testOpenDefault(virConnectPtr conn) {
         goto error;
     if (!(domobj = virDomainObjListAdd(privconn->domains,
                                        privconn->caps,
-                                       domdef, false)))
+                                       domdef, 0, NULL)))
         goto error;
     domdef = NULL;
 
@@ -911,7 +911,7 @@ static int testOpenFromFile(virConnectPtr conn,
         if (testDomainGenerateIfnames(def) < 0 ||
             !(dom = virDomainObjListAdd(privconn->domains,
                                         privconn->caps,
-                                        def, false))) {
+                                        def, 0, NULL))) {
             virDomainDefFree(def);
             goto error;
         }
@@ -1308,14 +1308,13 @@ testDomainCreateXML(virConnectPtr conn, const char *xml,
                                        VIR_DOMAIN_XML_INACTIVE)) == NULL)
         goto cleanup;
 
-    if (virDomainObjListIsDuplicate(privconn->domains, def, 1) < 0)
-        goto cleanup;
-
     if (testDomainGenerateIfnames(def) < 0)
         goto cleanup;
     if (!(dom = virDomainObjListAdd(privconn->domains,
                                     privconn->caps,
-                                    def, false)))
+                                    def,
+                                    VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
+                                    NULL)))
         goto cleanup;
     def = NULL;
 
@@ -1925,14 +1924,14 @@ testDomainRestoreFlags(virConnectPtr conn,
     if (!def)
         goto cleanup;
 
-    if (virDomainObjListIsDuplicate(privconn->domains, def, 1) < 0)
-        goto cleanup;
-
     if (testDomainGenerateIfnames(def) < 0)
         goto cleanup;
     if (!(dom = virDomainObjListAdd(privconn->domains,
                                     privconn->caps,
-                                    def, true)))
+                                    def,
+                                    VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
+                                    VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
+                                    NULL)))
         goto cleanup;
     def = NULL;
 
@@ -2465,7 +2464,7 @@ static virDomainPtr testDomainDefineXML(virConnectPtr conn,
     virDomainDefPtr def;
     virDomainObjPtr dom = NULL;
     virDomainEventPtr event = NULL;
-    int dupVM;
+    virDomainDefPtr oldDef = NULL;
 
     testDriverLock(privconn);
     if ((def = virDomainDefParseString(privconn->caps, xml,
@@ -2473,21 +2472,20 @@ static virDomainPtr testDomainDefineXML(virConnectPtr conn,
                                        VIR_DOMAIN_XML_INACTIVE)) == NULL)
         goto cleanup;
 
-    if ((dupVM = virDomainObjListIsDuplicate(privconn->domains, def, 0)) < 0)
-        goto cleanup;
-
     if (testDomainGenerateIfnames(def) < 0)
         goto cleanup;
     if (!(dom = virDomainObjListAdd(privconn->domains,
                                     privconn->caps,
-                                    def, false)))
+                                    def,
+                                    0,
+                                    &oldDef)))
         goto cleanup;
     def = NULL;
     dom->persistent = 1;
 
     event = virDomainEventNewFromObj(dom,
                                      VIR_DOMAIN_EVENT_DEFINED,
-                                     !dupVM ?
+                                     !oldDef ?
                                      VIR_DOMAIN_EVENT_DEFINED_ADDED :
                                      VIR_DOMAIN_EVENT_DEFINED_UPDATED);
 
@@ -2497,6 +2495,7 @@ static virDomainPtr testDomainDefineXML(virConnectPtr conn,
 
 cleanup:
     virDomainDefFree(def);
+    virDomainDefFree(oldDef);
     if (dom)
         virObjectUnlock(dom);
     if (event)
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index 6702a7e..fc6bb29 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -1497,12 +1497,11 @@ static virDomainPtr umlDomainCreate(virConnectPtr conn, const char *xml,
                                         VIR_DOMAIN_XML_INACTIVE)))
         goto cleanup;
 
-    if (virDomainObjListIsDuplicate(driver->domains, def, 1) < 0)
-        goto cleanup;
-
     if (!(vm = virDomainObjListAdd(driver->domains,
                                    driver->caps,
-                                   def, false)))
+                                   def,
+                                   VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
+                                   NULL)))
         goto cleanup;
     def = NULL;
 
@@ -1919,12 +1918,10 @@ static virDomainPtr umlDomainDefine(virConnectPtr conn, const char *xml) {
                                         VIR_DOMAIN_XML_INACTIVE)))
         goto cleanup;
 
-    if (virDomainObjListIsDuplicate(driver->domains, def, 0) < 0)
-        goto cleanup;
-
     if (!(vm = virDomainObjListAdd(driver->domains,
                                    driver->caps,
-                                   def, false)))
+                                   def,
+                                   0, NULL)))
         goto cleanup;
     def = NULL;
     vm->persistent = 1;
diff --git a/src/vmware/vmware_conf.c b/src/vmware/vmware_conf.c
index b616c1b..1afd372 100644
--- a/src/vmware/vmware_conf.c
+++ b/src/vmware/vmware_conf.c
@@ -179,7 +179,7 @@ vmwareLoadDomains(struct vmware_driver *driver)
 
         if (!(vm = virDomainObjListAdd(driver->domains,
                                        driver->caps,
-                                       vmdef, false)))
+                                       vmdef, 0, NULL)))
             goto cleanup;
 
         pDomain = vm->privateData;
diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c
index b99fca3..8684f56 100644
--- a/src/vmware/vmware_driver.c
+++ b/src/vmware/vmware_driver.c
@@ -320,9 +320,6 @@ vmwareDomainDefineXML(virConnectPtr conn, const char *xml)
                                          VIR_DOMAIN_XML_INACTIVE)) == NULL)
         goto cleanup;
 
-    if (virDomainObjListIsDuplicate(driver->domains, vmdef, 1) < 0)
-        goto cleanup;
-
     /* generate vmx file */
     vmx = virVMXFormatConfig(&ctx, driver->caps, vmdef, 7);
     if (vmx == NULL)
@@ -341,7 +338,7 @@ vmwareDomainDefineXML(virConnectPtr conn, const char *xml)
     /* assign def */
     if (!(vm = virDomainObjListAdd(driver->domains,
                                    driver->caps,
-                                   vmdef, false)))
+                                   vmdef, 0, NULL)))
         goto cleanup;
 
     pDomain = vm->privateData;
@@ -592,9 +589,6 @@ vmwareDomainCreateXML(virConnectPtr conn, const char *xml,
                                          VIR_DOMAIN_XML_INACTIVE)) == NULL)
         goto cleanup;
 
-    if (virDomainObjListIsDuplicate(driver->domains, vmdef, 1) < 0)
-        goto cleanup;
-
     /* generate vmx file */
     vmx = virVMXFormatConfig(&ctx, driver->caps, vmdef, 7);
     if (vmx == NULL)
@@ -613,7 +607,9 @@ vmwareDomainCreateXML(virConnectPtr conn, const char *xml,
     /* assign def */
     if (!(vm = virDomainObjListAdd(driver->domains,
                                    driver->caps,
-                                   vmdef, false)))
+                                   vmdef,
+                                   VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
+                                   NULL)))
         goto cleanup;
 
     pDomain = vm->privateData;
-- 
1.8.0.2




More information about the libvir-list mailing list