From: "Daniel P. Berrange" <berra...@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/libvirt_private.syms         |   1 -
 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 +--
 14 files changed, 174 insertions(+), 214 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3861e68..79da5eb 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1871,30 +1871,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;
 }
 
 /*
@@ -14850,7 +14911,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;
@@ -15076,69 +15137,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 3ad1173..fa13e24 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1968,10 +1968,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);
@@ -2156,10 +2161,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/libvirt_private.syms b/src/libvirt_private.syms
index bdc8e9b..87171ae 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -478,7 +478,6 @@ virDomainObjListFindByUUID;
 virDomainObjListForEach;
 virDomainObjListGetActiveIDs;
 virDomainObjListGetInactiveNames;
-virDomainObjListIsDuplicate;
 virDomainObjListLoadAllConfigs;
 virDomainObjListNew;
 virDomainObjListNumOfDomains;
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 1ce3057..e0a9a8e 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -1449,12 +1449,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;
 
@@ -2230,12 +2229,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;
@@ -3019,7 +3018,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,
@@ -3027,12 +3026,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;
@@ -3049,12 +3047,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 9dbab67..5e664c7 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)
@@ -1077,9 +1077,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"));
@@ -1089,7 +1086,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 bc05a51..4e1889f 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 */
 
@@ -2324,7 +2324,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,
@@ -2335,14 +2334,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;
@@ -2373,7 +2367,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 a02e989..d6c6af5 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1589,9 +1589,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;
 
@@ -1603,7 +1600,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;
@@ -4987,15 +4986,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)
@@ -5585,12 +5582,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);
@@ -5603,9 +5599,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;
 
@@ -5615,26 +5608,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",
@@ -5646,14 +5627,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);
@@ -5661,13 +5643,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);
 
@@ -5676,6 +5656,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);
@@ -12612,9 +12593,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;
 
@@ -12623,7 +12601,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 cd47862..1b31e00 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -584,7 +584,7 @@ static int testOpenDefault(virConnectPtr conn) {
         goto error;
     if (!(domobj = virDomainObjListAdd(privconn->domains,
                                        privconn->caps,
-                                       domdef, false)))
+                                       domdef, 0, NULL)))
         goto error;
     domdef = NULL;
 
@@ -929,7 +929,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;
         }
@@ -1326,14 +1326,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;
 
@@ -1943,14 +1942,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;
 
@@ -2483,7 +2482,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,
@@ -2491,21 +2490,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);
 
@@ -2515,6 +2513,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 27f5118..f2cdc8d 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -1499,12 +1499,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;
 
@@ -1921,12 +1920,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.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to