Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 15 Jun 2013 05:57:29 +0000 (UTC)
From:      Lawrence Stewart <lstewart@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r251774 - head/sys/kern
Message-ID:  <201306150557.r5F5vTmj042854@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: lstewart
Date: Sat Jun 15 05:57:29 2013
New Revision: 251774
URL: http://svnweb.freebsd.org/changeset/base/251774

Log:
  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.
  
  MFC after:	1 week

Modified:
  head/sys/kern/kern_hhook.c
  head/sys/kern/kern_khelp.c

Modified: head/sys/kern/kern_hhook.c
==============================================================================
--- head/sys/kern/kern_hhook.c	Sat Jun 15 05:04:14 2013	(r251773)
+++ head/sys/kern/kern_hhook.c	Sat Jun 15 05:57:29 2013	(r251774)
@@ -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: head/sys/kern/kern_khelp.c
==============================================================================
--- head/sys/kern/kern_khelp.c	Sat Jun 15 05:04:14 2013	(r251773)
+++ head/sys/kern/kern_khelp.c	Sat Jun 15 05:57:29 2013	(r251774)
@@ -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);



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