Use this function in the qemu, uml, lxc, and test drivers.
Signed-off-by: Cole Robinson <crobinso(a)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