Author: lstewart
Date: Wed Jul  3 05:48:46 2013
New Revision: 252539
URL: http://svnweb.freebsd.org/changeset/base/252539

Log:
  MFC r251774:
  
  Add a private KPI between hhook and khelp that allows khelp modules to insert
  hook functions into hhook points which register after the modules were loaded 
-
  potentially useful during boot or if hhook points are dynamically registered.

Modified:
  stable/9/sys/kern/kern_hhook.c
  stable/9/sys/kern/kern_khelp.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/kern/kern_hhook.c
==============================================================================
--- stable/9/sys/kern/kern_hhook.c      Wed Jul  3 05:47:28 2013        
(r252538)
+++ stable/9/sys/kern/kern_hhook.c      Wed Jul  3 05:48:46 2013        
(r252539)
@@ -74,6 +74,7 @@ static uint32_t n_hhookheads;
 
 /* Private function prototypes. */
 static void hhook_head_destroy(struct hhook_head *hhh);
+void khelp_new_hhook_registered(struct hhook_head *hhh, uint32_t flags);
 
 #define        HHHLIST_LOCK() mtx_lock(&hhook_head_list_lock)
 #define        HHHLIST_UNLOCK() mtx_unlock(&hhook_head_list_lock)
@@ -311,12 +312,7 @@ hhook_head_register(int32_t hhook_type, 
        tmphhh->hhh_nhooks = 0;
        STAILQ_INIT(&tmphhh->hhh_hooks);
        HHH_LOCK_INIT(tmphhh);
-
-       if (hhh != NULL) {
-               refcount_init(&tmphhh->hhh_refcount, 1);
-               *hhh = tmphhh;
-       } else
-               refcount_init(&tmphhh->hhh_refcount, 0);
+       refcount_init(&tmphhh->hhh_refcount, 1);
 
        HHHLIST_LOCK();
        if (flags & HHOOK_HEADISINVNET) {
@@ -331,6 +327,13 @@ hhook_head_register(int32_t hhook_type, 
        n_hhookheads++;
        HHHLIST_UNLOCK();
 
+       khelp_new_hhook_registered(tmphhh, flags);
+
+       if (hhh != NULL)
+               *hhh = tmphhh;
+       else
+               refcount_release(&tmphhh->hhh_refcount);
+
        return (0);
 }
 

Modified: stable/9/sys/kern/kern_khelp.c
==============================================================================
--- stable/9/sys/kern/kern_khelp.c      Wed Jul  3 05:47:28 2013        
(r252538)
+++ stable/9/sys/kern/kern_khelp.c      Wed Jul  3 05:48:46 2013        
(r252539)
@@ -40,7 +40,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/hhook.h>
-#include <sys/jail.h>
 #include <sys/khelp.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
@@ -52,8 +51,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/rwlock.h>
 #include <sys/systm.h>
 
-#include <net/vnet.h>
-
 static struct rwlock khelp_list_lock;
 RW_SYSINIT(khelplistlock, &khelp_list_lock, "helper list lock");
 
@@ -61,6 +58,7 @@ static TAILQ_HEAD(helper_head, helper) h
 
 /* Private function prototypes. */
 static inline void khelp_remove_osd(struct helper *h, struct osd *hosd);
+void khelp_new_hhook_registered(struct hhook_head *hhh, uint32_t flags);
 
 #define        KHELP_LIST_WLOCK() rw_wlock(&khelp_list_lock)
 #define        KHELP_LIST_WUNLOCK() rw_wunlock(&khelp_list_lock)
@@ -289,6 +287,36 @@ khelp_remove_hhook(struct hookinfo *hki)
        return (error);
 }
 
+/*
+ * Private KPI between hhook and khelp that allows khelp modules to insert hook
+ * functions into hhook points which register after the modules were loaded.
+ */
+void
+khelp_new_hhook_registered(struct hhook_head *hhh, uint32_t flags)
+{
+       struct helper *h;
+       int error, i;
+
+       KHELP_LIST_RLOCK();
+       TAILQ_FOREACH(h, &helpers, h_next) {
+               for (i = 0; i < h->h_nhooks; i++) {
+                       if (hhh->hhh_type != h->h_hooks[i].hook_type ||
+                           hhh->hhh_id != h->h_hooks[i].hook_id)
+                               continue;
+                       error = hhook_add_hook(hhh, &h->h_hooks[i], flags);
+                       if (error) {
+                               printf("%s: \"%s\" khelp module unable to "
+                                   "hook type %d id %d due to error %d\n",
+                                   __func__, h->h_name,
+                                   h->h_hooks[i].hook_type,
+                                   h->h_hooks[i].hook_id, error);
+                               error = 0;
+                       }
+               }
+       }
+       KHELP_LIST_RUNLOCK();
+}
+
 int
 khelp_modevent(module_t mod, int event_type, void *data)
 {
@@ -348,95 +376,3 @@ khelp_modevent(module_t mod, int event_t
 
        return (error);
 }
-
-/*
- * This function is called in two separate situations:
- *
- * - When the kernel is booting, it is called directly by the SYSINIT framework
- * to allow Khelp modules which were compiled into the kernel or loaded by the
- * boot loader to insert their non-virtualised hook functions into the kernel.
- *
- * - When the kernel is booting or a vnet is created, this function is also
- * called indirectly through khelp_vnet_init() by the vnet initialisation code.
- * In this situation, Khelp modules are able to insert their virtualised hook
- * functions into the virtualised hook points in the vnet which is being
- * initialised. In the case where the kernel is not compiled with "options
- * VIMAGE", this step is still run once at boot, but the hook functions get
- * transparently inserted into the standard unvirtualised network stack.
- */
-static void
-khelp_init(const void *vnet)
-{
-       struct helper *h;
-       int error, i, vinit;
-       int32_t htype, hid;
-
-       error = 0;
-       vinit = vnet != NULL;
-
-       KHELP_LIST_RLOCK();
-       TAILQ_FOREACH(h, &helpers, h_next) {
-               for (i = 0; i < h->h_nhooks && !error; i++) {
-                       htype = h->h_hooks[i].hook_type;
-                       hid = h->h_hooks[i].hook_id;
-
-                       /*
-                        * If we're doing a virtualised init (vinit != 0) and
-                        * the hook point is virtualised, or we're doing a plain
-                        * sysinit at boot and the hook point is not
-                        * virtualised, insert the hook.
-                        */
-                       if ((hhook_head_is_virtualised_lookup(htype, hid) ==
-                           HHOOK_HEADISINVNET && vinit) ||
-                           (!hhook_head_is_virtualised_lookup(htype, hid) &&
-                           !vinit)) {
-                               error = hhook_add_hook_lookup(&h->h_hooks[i],
-                                   HHOOK_NOWAIT);
-                       }
-               }
-
-               if (error) {
-                        /* Remove any helper's hooks we successfully added. */
-                       for (i--; i >= 0; i--)
-                               hhook_remove_hook_lookup(&h->h_hooks[i]);
-
-                       printf("%s: Failed to add hooks for helper \"%s\" (%p)",
-                               __func__, h->h_name, h);
-                       if (vinit)
-                                   printf(" to vnet %p.\n", vnet);
-                       else
-                               printf(".\n");
-
-                       error = 0;
-               }
-       }
-       KHELP_LIST_RUNLOCK();
-}
-
-/*
- * Vnet created and being initialised.
- */
-static void
-khelp_vnet_init(const void *unused __unused)
-{
-
-       khelp_init(TD_TO_VNET(curthread));
-}
-
-
-/*
- * As the kernel boots, allow Khelp modules which were compiled into the kernel
- * or loaded by the boot loader to insert their non-virtualised hook functions
- * into the kernel.
- */
-SYSINIT(khelp_init, SI_SUB_PROTO_END, SI_ORDER_FIRST, khelp_init, NULL);
-
-/*
- * When a vnet is created and being initialised, we need to insert the helper
- * hook functions for all currently registered Khelp modules into the vnet's
- * helper hook points.  The hhook KPI provides a mechanism for subsystems which
- * export helper hook points to clean up on vnet shutdown, so we don't need a
- * VNET_SYSUNINIT for Khelp.
- */
-VNET_SYSINIT(khelp_vnet_init, SI_SUB_PROTO_END, SI_ORDER_FIRST,
-    khelp_vnet_init, NULL);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to