PERFORCE change 162046 for review

Marko Zec zec at FreeBSD.org
Wed May 13 23:47:27 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=162046

Change 162046 by zec at zec_tpx32 on 2009/05/13 23:46:54

	When processing requests to create an instance of a cloning
	ifnet, and the cloner for the requested cloning ifnet class
	is not found in the current vnet, look up for the cloner
	in the default vnet.  Apply the same logic when attempting
	to destroy a cloning ifnet.
	
	In effect, this simple change allows for having both per-vnet
	and global unit numbers for cloning ifnets.  Only if_loop is
	currently registered on a per-vnet basis, so by default all
	the other cloning ifnet types will be assigned globally
	unique ifunit numbers.
	
	Let it remain noted that I was personally strongly opposed
	to introducing such special-case logic, which I believe will
	cause us more trouble than good in the long run, as users /
	applications running in parallel vnets will not be able to
	rely on predictability and availability of free ifunits.
	For example, if a user / application in a non-default vnet
	requests and gets a vlan0 instance, a later request for vlan0
	creation in the default vnet will fail without any reasonable
	or obvious explanation.

Affected files ...

.. //depot/projects/vimage-commit2/src/sys/kern/kern_vimage.c#40 edit
.. //depot/projects/vimage-commit2/src/sys/net/if_clone.c#8 edit
.. //depot/projects/vimage-commit2/src/sys/sys/vimage.h#60 edit

Differences ...

==== //depot/projects/vimage-commit2/src/sys/kern/kern_vimage.c#40 (text+ko) ====

@@ -94,6 +94,8 @@
 static u_int last_vi_id = 0;
 static u_int last_vnet_id = 0;
 static u_int last_vprocg_id = 0;
+
+struct vnet *vnet0;
 #endif
 
 #ifdef VIMAGE
@@ -721,6 +723,8 @@
 		panic("vi_alloc: malloc failed for vnet \"%s\"\n", name);
 	vip->v_net = vnet;
 	vnet->vnet_id = last_vnet_id++;
+	if (vnet->vnet_id == 0)
+		vnet0 = vnet;
 	vnet->vnet_magic_n = VNET_MAGIC_N;
 
 	vprocg = malloc(sizeof(struct vprocg), M_VPROCG, M_NOWAIT | M_ZERO);

==== //depot/projects/vimage-commit2/src/sys/net/if_clone.c#8 (text+ko) ====

@@ -159,6 +159,17 @@
 			break;
 		}
 	}
+#ifdef VIMAGE
+	if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) {
+		CURVNET_SET_QUIET(vnet0);
+		INIT_VNET_NET(vnet0);
+		LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
+			if (ifc->ifc_match(ifc, name))
+				break;
+		}
+		CURVNET_RESTORE();
+	}
+#endif
 	IF_CLONERS_UNLOCK();
 
 	if (ifc == NULL)
@@ -217,6 +228,17 @@
 			break;
 		}
 	}
+#ifdef VIMAGE
+	if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) {
+		CURVNET_SET_QUIET(vnet0);
+		INIT_VNET_NET(vnet0);
+		LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
+			if (ifc->ifc_match(ifc, name))
+				break;
+		}
+		CURVNET_RESTORE();
+	}
+#endif
 	IF_CLONERS_UNLOCK();
 	if (ifc == NULL)
 		return (EINVAL);
@@ -235,6 +257,13 @@
 	if (ifc->ifc_destroy == NULL)
 		return(EOPNOTSUPP);
 
+	/*
+	 * Given that the cloned ifnet might be attached to a different
+	 * vnet from where it's cloner was registered, we have to
+	 * switch to the vnet context of the target vnet.
+	 */
+	CURVNET_SET_QUIET(ifp->if_vnet);
+
 	IF_CLONE_LOCK(ifc);
 	IFC_IFLIST_REMOVE(ifc, ifp);
 	IF_CLONE_UNLOCK(ifc);
@@ -250,6 +279,7 @@
 		IFC_IFLIST_INSERT(ifc, ifp);
 		IF_CLONE_UNLOCK(ifc);
 	}
+	CURVNET_RESTORE();
 	return (err);
 }
 

==== //depot/projects/vimage-commit2/src/sys/sys/vimage.h#60 (text+ko) ====

@@ -307,6 +307,7 @@
 #ifdef VIMAGE
 LIST_HEAD(vnet_list_head, vnet);
 extern struct vnet_list_head vnet_head;
+extern struct vnet *vnet0;
 #define	VNET_ITERATOR_DECL(arg) struct vnet *arg;
 #define	VNET_FOREACH(arg) LIST_FOREACH(arg, &vnet_head, vnet_le)
 #else


More information about the p4-projects mailing list