The network driver is not doing correct checking for
duplicate UUID/name values. This introduces a new method
virNetworkObjIsDuplicate, based on the previously
written virDomainObjIsDuplicate.
* src/conf/network_conf.c, src/conf/network_conf.c,
src/libvirt_private.syms: Add virNetworkObjIsDuplicate,
* src/network/bridge_driver.c: Call virNetworkObjIsDuplicate
for checking uniqueness of uuid/names
---
src/conf/network_conf.c | 65 +++++++++++++++++++++++++++++++++++++++++++
src/conf/network_conf.h | 4 ++
src/libvirt_private.syms | 1 +
src/network/bridge_driver.c | 7 ++++
4 files changed, 77 insertions(+), 0 deletions(-)
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 06537d1..347fc0b 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -940,6 +940,71 @@ error:
return ret;
}
+
+/*
+ * virNetworkObjIsDuplicate:
+ * @doms : virNetworkObjListPtr to search
+ * @def : virNetworkDefPtr definition of network to lookup
+ * @check_active: If true, ensure that network is not active
+ *
+ * Returns: -1 on error
+ * 0 if network is new
+ * 1 if network is a duplicate
+ */
+int
+virNetworkObjIsDuplicate(virNetworkObjListPtr doms,
+ virNetworkDefPtr def,
+ unsigned int check_active)
+{
+ int ret = -1;
+ int dupVM = 0;
+ virNetworkObjPtr vm = NULL;
+
+ /* See if a VM with matching UUID already exists */
+ vm = virNetworkFindByUUID(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);
+ virNetworkReportError(VIR_ERR_OPERATION_FAILED,
+ _("network '%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 (virNetworkObjIsActive(vm)) {
+ virNetworkReportError(VIR_ERR_OPERATION_INVALID,
+ _("network 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 = virNetworkFindByName(doms, def->name);
+ if (vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(vm->def->uuid, uuidstr);
+ virNetworkReportError(VIR_ERR_OPERATION_FAILED,
+ _("network '%s' already exists with uuid
%s"),
+ def->name, uuidstr);
+ goto cleanup;
+ }
+ }
+
+ ret = dupVM;
+cleanup:
+ if (vm)
+ virNetworkObjUnlock(vm);
+ return ret;
+}
+
+
void virNetworkObjLock(virNetworkObjPtr obj)
{
virMutexLock(&obj->lock);
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 127a23a..c4956b6 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -169,6 +169,10 @@ int virNetworkSetBridgeName(const virNetworkObjListPtr nets,
virNetworkDefPtr def,
int check_collision);
+int virNetworkObjIsDuplicate(virNetworkObjListPtr doms,
+ virNetworkDefPtr def,
+ unsigned int check_active);
+
void virNetworkObjLock(virNetworkObjPtr obj);
void virNetworkObjUnlock(virNetworkObjPtr obj);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index e7cd6dd..414e937 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -469,6 +469,7 @@ virNetworkSaveConfig;
virNetworkSetBridgeName;
virNetworkObjLock;
virNetworkObjUnlock;
+virNetworkObjIsDuplicate;
# nodeinfo.h
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 5d7ef19..01be425 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -1265,6 +1265,9 @@ static virNetworkPtr networkCreate(virConnectPtr conn, const char
*xml) {
if (!(def = virNetworkDefParseString(xml)))
goto cleanup;
+ if (virNetworkObjIsDuplicate(&driver->networks, def, 1) < 0)
+ goto cleanup;
+
if (virNetworkSetBridgeName(&driver->networks, def, 1))
goto cleanup;
@@ -1295,12 +1298,16 @@ static virNetworkPtr networkDefine(virConnectPtr conn, const char
*xml) {
virNetworkDefPtr def;
virNetworkObjPtr network = NULL;
virNetworkPtr ret = NULL;
+ int dupNet;
networkDriverLock(driver);
if (!(def = virNetworkDefParseString(xml)))
goto cleanup;
+ if ((dupNet = virNetworkObjIsDuplicate(&driver->networks, def, 0)) < 0)
+ goto cleanup;
+
if (virNetworkSetBridgeName(&driver->networks, def, 1))
goto cleanup;
--
1.6.6.1