svn commit: r191508 - in head/sys: kern sys

Marko Zec zec at FreeBSD.org
Sun Apr 26 07:09:40 UTC 2009


Author: zec
Date: Sun Apr 26 07:09:39 2009
New Revision: 191508
URL: http://svn.freebsd.org/changeset/base/191508

Log:
  Extend the vnet module registration / initialization framework
  first introduced @ r190909 with a vnet module deregistration
  service.
  
  kldunloadable modules, which are currently using vnet_mod_register()
  to attach their per-vnet initialization routines to the vnet
  initialization framework, should call vnet_mod_deregister() before
  acknowledging MOD_UNLOAD requests in their mod_event handlers.  Such
  changes to the existing code base will follow in subsequent commits.
  
  vnet_mod_deregister() does not check whether departing vnet modules
  are registered as prerequisites for another module(s), so it should
  be used with care.  Currently I'm only aware of vnet modules which
  are leafs on module dependency graphs that are kldunloadable.
  
  This change also introduces per-vnet module destructor handler, which
  calls vnet's module cleanup function, which (if required) has to be
  registered in vnet module's vnet_modinfo_t structure .vmi_idetach
  field.  Once options VIMAGE becomes operational, the framework will
  take care that module's cleanup function become invoked for each
  active vnet instance, and that the memory allocated for each instance
  gets freed.  Currently calls to destructor handlers must always
  succeed.

Modified:
  head/sys/kern/kern_vimage.c
  head/sys/sys/vimage.h

Modified: head/sys/kern/kern_vimage.c
==============================================================================
--- head/sys/kern/kern_vimage.c	Sun Apr 26 03:55:08 2009	(r191507)
+++ head/sys/kern/kern_vimage.c	Sun Apr 26 07:09:39 2009	(r191508)
@@ -47,6 +47,7 @@ static TAILQ_HEAD(vnet_modlink_head, vne
 static TAILQ_HEAD(vnet_modpending_head, vnet_modlink) vnet_modpending_head;
 static void vnet_mod_complete_registration(struct vnet_modlink *);
 static int vnet_mod_constructor(struct vnet_modlink *);
+static int vnet_mod_destructor(struct vnet_modlink *);
 
 void
 vnet_mod_register(const struct vnet_modinfo *vmi)
@@ -144,6 +145,37 @@ vnet_mod_complete_registration(struct vn
 	} while (vml_iter != NULL);
 }
 
+void
+vnet_mod_deregister(const struct vnet_modinfo *vmi)
+{
+
+	vnet_mod_deregister_multi(vmi, NULL, NULL);
+}
+
+void
+vnet_mod_deregister_multi(const struct vnet_modinfo *vmi, void *iarg,
+    char *iname)
+{
+	VNET_ITERATOR_DECL(vnet_iter);
+	struct vnet_modlink *vml;
+
+	TAILQ_FOREACH(vml, &vnet_modlink_head, vml_mod_le)
+		if (vml->vml_modinfo == vmi && vml->vml_iarg == iarg)
+			break;
+	if (vml == NULL)
+		panic("cannot deregister unregistered vnet module %s",
+		    vmi->vmi_name);
+
+	VNET_FOREACH(vnet_iter) {
+		CURVNET_SET_QUIET(vnet_iter);
+		vnet_mod_destructor(vml);
+		CURVNET_RESTORE();
+	}
+
+	TAILQ_REMOVE(&vnet_modlink_head, vml, vml_mod_le);
+	free(vml, M_VIMAGE);
+}
+
 static int vnet_mod_constructor(struct vnet_modlink *vml)
 {
 	const struct vnet_modinfo *vmi = vml->vml_modinfo;
@@ -153,16 +185,18 @@ static int vnet_mod_constructor(struct v
 	if (vml->vml_iarg)
 		printf("/%s", vml->vml_iname);
 	printf(": ");
-	if (vmi->vmi_struct_size)
-		printf("malloc(%zu); ", vmi->vmi_struct_size);
+#ifdef VIMAGE
+	if (vmi->vmi_size)
+		printf("malloc(%zu); ", vmi->vmi_size);
+#endif
 	if (vmi->vmi_iattach != NULL)
 		printf("iattach()");
 	printf("\n");
 #endif
 
 #ifdef VIMAGE
-	if (vmi->vmi_struct_size) {
-		void *mem = malloc(vmi->vmi_struct_size, M_VNET,
+	if (vmi->vmi_size) {
+		void *mem = malloc(vmi->vmi_size, M_VNET,
 		    M_NOWAIT | M_ZERO);
 		if (mem == NULL) /* XXX should return error, not panic. */
 			panic("vi_alloc: malloc for %s\n", vmi->vmi_name);
@@ -176,6 +210,41 @@ static int vnet_mod_constructor(struct v
 	return (0);
 }
 
+
+static int
+vnet_mod_destructor(struct vnet_modlink *vml)
+{
+	const struct vnet_modinfo *vmi = vml->vml_modinfo;
+
+#ifdef DEBUG_ORDERING
+	printf("destroying vnet_%s", vmi->vmi_name);
+	if (vml->vml_iarg)
+		printf("/%s", vml->vml_iname);
+	printf(": ");
+	if (vmi->vmi_idetach != NULL)
+		printf("idetach(); ");
+#ifdef VIMAGE
+	if (vmi->vmi_size)
+		printf("free()");
+#endif
+	printf("\n");
+#endif
+
+	if (vmi->vmi_idetach)
+		vmi->vmi_idetach(vml->vml_iarg);
+
+#ifdef VIMAGE
+	if (vmi->vmi_size) {
+		if (curvnet->mod_data[vmi->vmi_id] == NULL)
+			panic("vi_destroy: %s\n", vmi->vmi_name);
+		free(curvnet->mod_data[vmi->vmi_id], M_VNET);
+		curvnet->mod_data[vmi->vmi_id] = NULL;
+	}
+#endif
+
+	return (0);
+}
+
 /*
  * vi_symlookup() attempts to resolve name to address queries for
  * variables which have been moved from global namespace to virtualization

Modified: head/sys/sys/vimage.h
==============================================================================
--- head/sys/sys/vimage.h	Sun Apr 26 03:55:08 2009	(r191507)
+++ head/sys/sys/vimage.h	Sun Apr 26 07:09:39 2009	(r191508)
@@ -121,6 +121,8 @@ struct vnet_modlink {
 int	vi_symlookup(struct kld_sym_lookup *, char *);
 void	vnet_mod_register(const struct vnet_modinfo *);
 void	vnet_mod_register_multi(const struct vnet_modinfo *, void *, char *);
+void	vnet_mod_deregister(const struct vnet_modinfo *);
+void	vnet_mod_deregister_multi(const struct vnet_modinfo *, void *, char *);
 
 #endif /* !VIMAGE_GLOBALS */
 


More information about the svn-src-head mailing list