svn commit: r191508 - in head/sys: kern sys
Marko Zec
zec at icir.org
Sun Apr 26 07:38:47 UTC 2009
On Sunday 26 April 2009 09:09:39 Marko Zec wrote:
> 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.
Missing in the log:
Approved by: julian (mentor)
Reviewed by: bz
Sorry...
Marko
> 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-all
mailing list