Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Apr 2007 00:28:53 GMT
From:      Marko Zec <zec@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 118689 for review
Message-ID:  <200704240028.l3O0Srlp089395@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=118689

Change 118689 by zec@zec_tca51 on 2007/04/24 00:28:13

	An initial push for introducing infrastructure for
	releasing vnet instances.
	
	This change introduces per-domain and per-protosw destroy
	hooks which can be used for cleaning up state when vnets
	are to be released.  For now only the timers which
	are normally started through various init routines are
	stopped, which should allow for idle vnets to be destroyed
	without implicitly scheduling an imminent system crash.

Affected files ...

.. //depot/projects/vimage/src/sys/kern/kern_vimage.c#18 edit
.. //depot/projects/vimage/src/sys/net/route.c#6 edit
.. //depot/projects/vimage/src/sys/netinet/in_proto.c#3 edit
.. //depot/projects/vimage/src/sys/netinet/in_rmx.c#6 edit
.. //depot/projects/vimage/src/sys/netinet/ip_input.c#12 edit
.. //depot/projects/vimage/src/sys/netinet/ip_var.h#5 edit
.. //depot/projects/vimage/src/sys/netinet/ipprotosw.h#2 edit
.. //depot/projects/vimage/src/sys/netinet/vinet.h#13 edit
.. //depot/projects/vimage/src/sys/netinet6/in6_proto.c#4 edit
.. //depot/projects/vimage/src/sys/netinet6/in6_rmx.c#7 edit
.. //depot/projects/vimage/src/sys/netinet6/ip6_input.c#9 edit
.. //depot/projects/vimage/src/sys/netinet6/ip6_var.h#4 edit
.. //depot/projects/vimage/src/sys/netinet6/ip6protosw.h#2 edit
.. //depot/projects/vimage/src/sys/netinet6/nd6.c#10 edit
.. //depot/projects/vimage/src/sys/netinet6/nd6.h#3 edit
.. //depot/projects/vimage/src/sys/sys/domain.h#2 edit
.. //depot/projects/vimage/src/sys/sys/protosw.h#3 edit

Differences ...

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

@@ -100,8 +100,6 @@
 
 	if (modinfo->i_attach) {
 		VNET_ITERLOOP_BEGIN_QUIET();
-printf("Calling i_attach() for %s vnet %s\n",
-	modinfo->name, vnet_name(curvnet));
 			modinfo->i_attach();
 		VNET_ITERLOOP_END();
 	}
@@ -446,7 +444,6 @@
 		    modlnk_i->modinfo->flags & VNET_MFLAG_ORDER_1ST) {
 			VNET_ASSERT(!(modlnk_i->modinfo->flags & \
 				      VNET_MFLAG_ORDER_2ND));
-printf("Calling i_attach() for %s\n", modlnk_i->modinfo->name);
 			modlnk_i->modinfo->i_attach();
 		}
 
@@ -474,7 +471,6 @@
 		    modlnk_i->modinfo->flags & VNET_MFLAG_ORDER_2ND) {
 			VNET_ASSERT(!(modlnk_i->modinfo->flags & \
 				      VNET_MFLAG_ORDER_1ST));
-printf("Calling i_attach() for %s\n", modlnk_i->modinfo->name);
 			modlnk_i->modinfo->i_attach();
 		}
 
@@ -503,26 +499,33 @@
 	struct vcpu *vcpu = vip->v_cpu;
 	struct ifnet *ifp, *nifp;
 	struct vnet_modlink *modlnk_i;
-#if 0
 	struct domain *dp;
-#endif
 
 	CURVNET_SET_QUIET(vnet);
 	INIT_VNET_NET(vnet);
 
-	/* Return all inherited interfaces to their parent vnets */
-	/*for (ifp = TAILQ_FIRST(&V_ifnet); ifp; ifp = next) {*/
-	TAILQ_FOREACH_SAFE(ifp, &V_ifnet, if_link, nifp) 
+	/*
+	 * Return all inherited interfaces to their parent vnets,
+	 * alternatively attempt to kill cloning ifnets.
+	 */
+	TAILQ_FOREACH_SAFE(ifp, &V_ifnet, if_link, nifp) {
 		if (ifp->if_home_vnet != ifp->if_vnet)
 			vi_if_move(NULL, ifp, vip);
+		else
+			if_clone_destroy(ifp->if_xname);
+	}
 
 	/*
-	 * XXX TODO: kill all cloning ifnets
 	 * XXX TODO: kill all netgraph ifnets
-	 * XXX TODO: at this point only lo0 should be attached!!!
+	 */
+
+	/*
+	 * At this point only lo0 should be attached
 	 */
-TAILQ_FOREACH(ifp, &V_ifnet, if_link) 
-	printf("attached ifnet: %s\n", ifp->if_xname);
+	TAILQ_FOREACH(ifp, &V_ifnet, if_link) 
+		if (ifp != V_loif)
+			panic("non-loif ifnet %s still attached",
+			      ifp->if_xname);
 
 	/*
 	 * Detach modules with ORDER_2ND flag set
@@ -532,14 +535,9 @@
 		    modlnk_i->modinfo->flags & VNET_MFLAG_ORDER_2ND) {
 			VNET_ASSERT(!(modlnk_i->modinfo->flags & \
 				      VNET_MFLAG_ORDER_1ST));
-printf("Calling i_detach() for %s\n", modlnk_i->modinfo->name);
 			modlnk_i->modinfo->i_detach();
 		}
 
-TAILQ_FOREACH(ifp, &V_ifnet, if_link) 
-	printf("attached ifnet: %s\n", ifp->if_xname);
-
-#if 0
 	/*
 	 * Detach protocol domains
 	 */
@@ -549,7 +547,6 @@
 			if ((--pr)->pr_destroy)
 				(*pr->pr_destroy)();
 	}
-#endif
 
 	/*
 	 * Detach modules with ORDER_1ST flag set
@@ -559,7 +556,6 @@
 		    modlnk_i->modinfo->flags & VNET_MFLAG_ORDER_1ST) {
 			VNET_ASSERT(!(modlnk_i->modinfo->flags & \
 				      VNET_MFLAG_ORDER_2ND));
-printf("Calling i_detach() for %s\n", modlnk_i->modinfo->name);
 			modlnk_i->modinfo->i_detach();
 		}
 

==== //depot/projects/vimage/src/sys/net/route.c#6 (text+ko) ====

@@ -61,6 +61,9 @@
 static void rt_maskedcopy(struct sockaddr *,
 	    struct sockaddr *, struct sockaddr *);
 static int rtable_init(void);
+#ifdef VIMAGE
+static int rtable_idetach(void);
+#endif
 
 /* compare two sockaddr structures */
 #define	sa_equal(a1, a2) (bcmp((a1), (a2), (a1)->sa_len) == 0)
@@ -82,7 +85,8 @@
 	.id		= VNET_MOD_RTABLE,
 	.flags		= VNET_MFLAG_ORDER_2ND,
 	.name		= "rtable",
-	.i_attach	= rtable_init
+	.i_attach	= rtable_init,
+	.i_detach	= rtable_idetach
 };
 #endif
 
@@ -99,6 +103,21 @@
 	return 0;
 }
 
+#ifdef VIMAGE
+static int
+rtable_idetach()
+{
+	INIT_VNET_NET(curvnet);
+
+	struct domain *dom;
+	for (dom = domains; dom; dom = dom->dom_next)
+		if (dom->dom_rtdetach)
+			dom->dom_rtdetach((void *)&V_rt_tables[dom->dom_family],
+			    dom->dom_rtoffset);
+	return 0;
+}
+#endif
+
 static uma_zone_t rtzone;		/* Routing table UMA zone. */
 
 static void

==== //depot/projects/vimage/src/sys/netinet/in_proto.c#3 (text+ko) ====

@@ -37,6 +37,7 @@
 #include "opt_pf.h"
 #include "opt_carp.h"
 #include "opt_sctp.h"
+#include "opt_vimage.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -118,6 +119,9 @@
 	.pr_domain =		&inetdomain,
 	.pr_protocol =		IPPROTO_IP,
 	.pr_init =		ip_init,
+#ifdef VIMAGE
+	.pr_destroy =		ip_detach,
+#endif
 	.pr_slowtimo =		ip_slowtimo,
 	.pr_drain =		ip_drain,
 	.pr_usrreqs =		&nousrreqs
@@ -396,6 +400,7 @@
 };
 
 extern int in_inithead(void **, int);
+extern int in_detachhead(void **, int);
 
 struct domain inetdomain = {
 	.dom_family =		AF_INET,
@@ -403,6 +408,9 @@
 	.dom_protosw =		inetsw,
 	.dom_protoswNPROTOSW =	&inetsw[sizeof(inetsw)/sizeof(inetsw[0])],
 	.dom_rtattach =		in_inithead,
+#ifdef VIMAGE
+	.dom_rtdetach =		in_detachhead,
+#endif
 	.dom_rtoffset =		32,
 	.dom_maxrtkey =		sizeof(struct sockaddr_in)
 };

==== //depot/projects/vimage/src/sys/netinet/in_rmx.c#6 (text+ko) ====

@@ -62,7 +62,10 @@
 #include <netinet/in_var.h>
 #include <netinet/ip_var.h>
 
-extern int	in_inithead(void **head, int off);
+int	in_inithead(void **head, int off);
+#ifdef VIMAGE
+int	in_detachhead(void **head, int off);
+#endif
 
 #define RTPRF_OURS		RTF_PROTO3	/* set on routes we manage */
 
@@ -367,6 +370,17 @@
 	return 1;
 }
 
+#ifdef VIMAGE
+int
+in_detachhead(void **head, int off)
+{
+	INIT_VNET_INET(curvnet);
+
+	callout_drain(&V_rtq_timer);
+	return 1;
+}
+#endif
+
 /*
  * This zaps old routes when the interface goes down or interface
  * address is deleted.  In the latter case, it deletes static routes

==== //depot/projects/vimage/src/sys/netinet/ip_input.c#12 (text+ko) ====

@@ -350,6 +350,17 @@
 	netisr_register(NETISR_IP, ip_input, &ipintrq, NETISR_MPSAFE);
 }
 
+#ifdef VIMAGE
+void
+ip_detach()
+{
+	INIT_VNET_INET(curvnet);
+
+	free(vnet_inet, M_INET);
+	curvnet->mod_data[vnet_inet_modinfo.id] = NULL;
+}
+#endif
+
 void ip_fini(xtp)
 	void *xtp;
 {

==== //depot/projects/vimage/src/sys/netinet/ip_var.h#5 (text+ko) ====

@@ -178,6 +178,9 @@
 void	ip_freemoptions(struct ip_moptions *);
 void	ip_forward(struct mbuf *m, int srcrt);
 void	ip_init(void);
+#ifdef VIMAGE
+void	ip_detach(void);
+#endif
 extern int
 	(*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
 	    struct ip_moptions *);

==== //depot/projects/vimage/src/sys/netinet/ipprotosw.h#2 (text+ko) ====

@@ -87,6 +87,7 @@
 	void	*pr_ousrreq;
 /* utility hooks */
 	pr_init_t *pr_init;
+	pr_destroy_t *pr_destroy;
 	pr_fasttimo_t *pr_fasttimo;	/* fast timeout (200ms) */
 	pr_slowtimo_t *pr_slowtimo;	/* slow timeout (500ms) */
 	pr_drain_t *pr_drain;		/* flush any excess space possible */

==== //depot/projects/vimage/src/sys/netinet/vinet.h#13 (text+ko) ====

@@ -181,7 +181,6 @@
 #define V_in_multihead		VNET_INET(in_multihead)
 
 #define V_llinfo_arp		VNET_INET(llinfo_arp)
-#define V_arp_callout		VNET_INET(arp_callout)
 #define V_arpt_prune		VNET_INET(arpt_prune)
 #define V_arpt_keep		VNET_INET(arpt_keep)
 #define V_arp_maxtries		VNET_INET(arp_maxtries)

==== //depot/projects/vimage/src/sys/netinet6/in6_proto.c#4 (text+ko) ====

@@ -166,6 +166,9 @@
 	.pr_domain =		&inet6domain,
 	.pr_protocol =		IPPROTO_IPV6,
 	.pr_init =		ip6_init,
+#ifdef VIMAGE
+	.pr_destroy =		ip6_destroy,
+#endif
 	.pr_slowtimo =		frag6_slowtimo,
 	.pr_drain =		frag6_drain,
 	.pr_usrreqs =		&nousrreqs,
@@ -367,7 +370,10 @@
 },
 };
 
-extern int in6_inithead __P((void **, int));
+extern int in6_inithead(void **, int);
+#ifdef VIMAGE
+extern int in6_detachhead(void **, int);
+#endif
 
 struct domain inet6domain = {
 	.dom_family =		AF_INET6,
@@ -376,6 +382,9 @@
 	.dom_protoswNPROTOSW =	(struct protosw *)
 				&inet6sw[sizeof(inet6sw)/sizeof(inet6sw[0])],
 	.dom_rtattach =		in6_inithead,
+#ifdef VIMAGE
+	.dom_rtdetach =		in6_detachhead,
+#endif
 	.dom_rtoffset =		offsetof(struct sockaddr_in6, sin6_addr) << 3,
 	.dom_maxrtkey =		sizeof(struct sockaddr_in6),
 	.dom_ifattach =		in6_domifattach,

==== //depot/projects/vimage/src/sys/netinet6/in6_rmx.c#7 (text+ko) ====

@@ -107,7 +107,10 @@
 #include <netinet/tcp_timer.h>
 #include <netinet/tcp_var.h>
 
-extern int	in6_inithead __P((void **head, int off));
+int	in6_inithead(void **head, int off);
+#ifdef VIMAGE
+int	in6_detachhead(void **head, int off);
+#endif
 
 #define RTPRF_OURS		RTF_PROTO3	/* set on routes we manage */
 
@@ -491,3 +494,15 @@
 	in6_mtutimo(curvnet);	/* kick off timeout first time */
 	return 1;
 }
+
+#ifdef VIMAGE
+int
+in6_detachhead(void **head, int off)
+{
+	INIT_VNET_INET6(curvnet);
+
+	callout_drain(&V_rtq_timer6);
+	callout_drain(&V_rtq_mtutimer);
+	return 1;
+}
+#endif

==== //depot/projects/vimage/src/sys/netinet6/ip6_input.c#9 (text+ko) ====

@@ -247,6 +247,20 @@
 	ip6_desync_factor = arc4random() % MAX_TEMP_DESYNC_FACTOR;
 }
 
+#ifdef VIMAGE
+void
+ip6_destroy()
+{
+	INIT_VNET_INET6(curvnet);
+
+	nd6_destroy();
+	callout_drain(&V_in6_tmpaddrtimer_ch);
+
+	free(vnet_inet6, M_INET6);
+	curvnet->mod_data[vnet_inet6_modinfo.id] = NULL;
+}
+#endif
+
 static void
 ip6_init2(dummy)
 	void *dummy;

==== //depot/projects/vimage/src/sys/netinet6/ip6_var.h#4 (text+ko) ====

@@ -342,6 +342,9 @@
 
 struct in6_ifaddr;
 void	ip6_init __P((void));
+#ifdef VIMAGE
+void	ip6_destroy __P((void));
+#endif
 void	ip6_input __P((struct mbuf *));
 struct in6_ifaddr *ip6_getdstifaddr __P((struct mbuf *));
 void	ip6_freepcbopts __P((struct ip6_pktopts *));

==== //depot/projects/vimage/src/sys/netinet6/ip6protosw.h#2 (text+ko) ====

@@ -136,6 +136,8 @@
 /* utility hooks */
 	void	(*pr_init)		/* initialization hook */
 			__P((void));
+	void	(*pr_destroy)		/* cleanup hook */
+			__P((void));
 
 	void	(*pr_fasttimo)		/* fast timeout (200ms) */
 			__P((void));

==== //depot/projects/vimage/src/sys/netinet6/nd6.c#10 (text+ko) ====

@@ -150,6 +150,17 @@
 	    nd6_slowtimo, curvnet);
 }
 
+#ifdef VIMAGE
+void
+nd6_destroy()
+{
+	INIT_VNET_INET6(curvnet);
+
+	callout_drain(&V_nd6_slowtimo_ch);
+	callout_drain(&V_nd6_timer_ch);
+}
+#endif
+
 struct nd_ifinfo *
 nd6_ifattach(ifp)
 	struct ifnet *ifp;

==== //depot/projects/vimage/src/sys/netinet6/nd6.h#3 (text+ko) ====

@@ -385,6 +385,9 @@
 /* XXX: need nd6_var.h?? */
 /* nd6.c */
 void nd6_init __P((void));
+#ifdef VIMAGE
+void nd6_destroy __P((void));
+#endif
 struct nd_ifinfo *nd6_ifattach __P((struct ifnet *));
 void nd6_ifdetach __P((struct nd_ifinfo *));
 int nd6_is_addr_neighbor __P((struct sockaddr_in6 *, struct ifnet *));

==== //depot/projects/vimage/src/sys/sys/domain.h#2 (text+ko) ====

@@ -56,6 +56,8 @@
 	struct	domain *dom_next;
 	int	(*dom_rtattach)		/* initialize routing table */
 		(void **, int);
+	int	(*dom_rtdetach)		/* clean up routing table */
+		(void **, int);
 	int	dom_rtoffset;		/* an arg to rtattach, in bits */
 	int	dom_maxrtkey;		/* for routing layer */
 	void	*(*dom_ifattach)(struct ifnet *);

==== //depot/projects/vimage/src/sys/sys/protosw.h#3 (text+ko) ====

@@ -94,6 +94,7 @@
 	pr_usrreq_t	*pr_ousrreq;
 /* utility hooks */
 	pr_init_t *pr_init;
+	pr_destroy_t *pr_destroy;
 	pr_fasttimo_t *pr_fasttimo;	/* fast timeout (200ms) */
 	pr_slowtimo_t *pr_slowtimo;	/* slow timeout (500ms) */
 	pr_drain_t *pr_drain;		/* flush any excess space possible */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200704240028.l3O0Srlp089395>