Fri Nov 6 02:26:42 2015 UTC ()
In sysv_sem.c, defer establishment of exithook so we can initialize the
module code from module_init() rather than waiting until after calling
exec_init().  Use a RUN_ONCE routine at entry to each sys_sem* syscall
to establish the exithook, and no longer KASSERT that the hook has
been set before removing it.  (A manually loaded module can be unloaded
before any syscalls have been invoked.)

Remove the conditional calls to the various xxx_init() routines from
init_main.c - we now rely on module_init() to handle initialization.

Let each sub-component's xxx_init() routine handle its own sysctl
sub-tree initialization;  this removes another set of #ifdef ugliness.

Tested both built-in and loadable versions and verified that atf
test kernel/t_sysv passes.


(pgoyette)
diff -r1.472 -r1.473 src/sys/kern/init_main.c
diff -r1.29 -r1.30 src/sys/kern/sysv_ipc.c
diff -r1.69 -r1.70 src/sys/kern/sysv_msg.c
diff -r1.94 -r1.95 src/sys/kern/sysv_sem.c
diff -r1.129 -r1.130 src/sys/kern/sysv_shm.c
diff -r1.25 -r1.26 src/sys/sys/msg.h
diff -r1.31 -r1.32 src/sys/sys/sem.h
diff -r1.50 -r1.51 src/sys/sys/shm.h

cvs diff -r1.472 -r1.473 src/sys/kern/init_main.c (expand / switch to context diff)
--- src/sys/kern/init_main.c 2015/10/29 00:27:08 1.472
+++ src/sys/kern/init_main.c 2015/11/06 02:26:42 1.473
@@ -1,4 +1,4 @@
-/*	$NetBSD: init_main.c,v 1.472 2015/10/29 00:27:08 mrg Exp $	*/
+/*	$NetBSD: init_main.c,v 1.473 2015/11/06 02:26:42 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.472 2015/10/29 00:27:08 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.473 2015/11/06 02:26:42 pgoyette Exp $");
 
 #include "opt_ddb.h"
 #include "opt_ipsec.h"
@@ -179,15 +179,6 @@
 #ifdef IPSEC
 #include <netipsec/ipsec.h>
 #endif
-#ifdef SYSVSHM
-#include <sys/shm.h>
-#endif
-#ifdef SYSVSEM
-#include <sys/sem.h>
-#endif
-#ifdef SYSVMSG
-#include <sys/msg.h>
-#endif
 #include <sys/domain.h>
 #include <sys/namei.h>
 #include <sys/rnd.h>
@@ -525,25 +516,10 @@
 	kprintf_init_callout();
 #endif
 
-#ifdef SYSVSHM
-	/* Initialize System V style shared memory. */
-	shminit();
-#endif
-
 	vmem_rehash_start();	/* must be before exec_init */
 
 	/* Initialize exec structures */
 	exec_init(1);		/* seminit calls exithook_establish() */
-
-#ifdef SYSVSEM
-	/* Initialize System V style semaphores. */
-	seminit();
-#endif
-
-#ifdef SYSVMSG
-	/* Initialize System V style message queues. */
-	msginit();
-#endif
 
 #if NVERIEXEC > 0
 	/*

cvs diff -r1.29 -r1.30 src/sys/kern/sysv_ipc.c (expand / switch to context diff)
--- src/sys/kern/sysv_ipc.c 2015/11/06 01:00:41 1.29
+++ src/sys/kern/sysv_ipc.c 2015/11/06 02:26:42 1.30
@@ -1,4 +1,4 @@
-/*	$NetBSD: sysv_ipc.c,v 1.29 2015/11/06 01:00:41 pgoyette Exp $	*/
+/*	$NetBSD: sysv_ipc.c,v 1.30 2015/11/06 02:26:42 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2007 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sysv_ipc.c,v 1.29 2015/11/06 01:00:41 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysv_ipc.c,v 1.30 2015/11/06 02:26:42 pgoyette Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sysv.h"
@@ -127,14 +127,9 @@
 
 MODULE(MODULE_CLASS_EXEC, sysv_ipc, NULL);
  
-#ifdef _MODULE
 SYSCTL_SETUP_PROTO(sysctl_ipc_setup);
-SYSCTL_SETUP_PROTO(sysctl_ipc_shm_setup);
-SYSCTL_SETUP_PROTO(sysctl_ipc_sem_setup);
-SYSCTL_SETUP_PROTO(sysctl_ipc_msg_setup);
 
 static struct sysctllog *sysctl_sysvipc_clog = NULL;
-#endif
 
 static const struct syscall_package sysvipc_syscalls[] = {
 #ifdef SYSVSHM
@@ -165,35 +160,35 @@
 
 	switch (cmd) {
 	case MODULE_CMD_INIT:
-		/* Link the system calls */
-		error = syscall_establish(NULL, sysvipc_syscalls);
+		/* Set up the kauth listener */
+		sysvipcinit();
 
-		/* Initialize all sysctl sub-trees */
 #ifdef _MODULE
+		/* Set up the common sysctl tree */
 		sysctl_ipc_setup(&sysctl_sysvipc_clog);
-#ifdef	SYSVMSG
-		sysctl_ipc_msg_setup(&sysctl_sysvipc_clog);
 #endif
-#ifdef	SYSVSHM
-		sysctl_ipc_shm_setup(&sysctl_sysvipc_clog);
-#endif
-#ifdef	SYSVSEM
-		sysctl_ipc_sem_setup(&sysctl_sysvipc_clog);
-#endif
+
+		/* Link the system calls */
+		error = syscall_establish(NULL, sysvipc_syscalls);
+		if (error)
+			sysvipcfini();
+
 		/* Assume no compat sysctl routine for now */
 		kern_sysvipc50_sysctl_p = NULL;
 
-		/* Initialize each sub-component */
+		/*
+		 * Initialize each sub-component, including their
+		 * sysctl data
+		 */
 #ifdef SYSVSHM
-		shminit();
+		shminit(&sysctl_sysvipc_clog);
 #endif
 #ifdef SYSVSEM
-		seminit();
+		seminit(&sysctl_sysvipc_clog);
 #endif
 #ifdef SYSVMSG
-		msginit();
+		msginit(&sysctl_sysvipc_clog);
 #endif
-#endif /* _MODULE */
 		break;
 	case MODULE_CMD_FINI:
 		/*
@@ -212,7 +207,7 @@
 #ifdef SYSVSEM
 		if (semfini()) {
 #ifdef SYSVSHM
-			shminit();
+			shminit(NULL);
 #endif
 			return EBUSY;
 		}
@@ -220,10 +215,10 @@
 #ifdef SYSVMSG
 		if (msgfini()) {
 #ifdef SYSVSEM
-			seminit();
+			seminit(NULL);
 #endif
 #ifdef SYSVSHM
-			shminit();
+			shminit(NULL);
 #endif
 			return EBUSY;
 		}
@@ -237,7 +232,7 @@
 #ifdef _MODULE
 		/* Remove the sysctl sub-trees */
 		sysctl_teardown(&sysctl_sysvipc_clog);
-#endif  
+#endif
 
 		/* Remove the kauth listener */
 		sysvipcfini();
@@ -345,8 +340,7 @@
 sysvipcinit(void)
 {
 
-	if (sysvipc_listener != NULL)
-		return;
+	KASSERT(sysvipc_listener == NULL);
 
 	sysvipc_listener = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
 	    sysvipc_listener_cb, NULL);

cvs diff -r1.69 -r1.70 src/sys/kern/sysv_msg.c (expand / switch to context diff)
--- src/sys/kern/sysv_msg.c 2015/05/13 01:16:15 1.69
+++ src/sys/kern/sysv_msg.c 2015/11/06 02:26:42 1.70
@@ -1,4 +1,4 @@
-/*	$NetBSD: sysv_msg.c,v 1.69 2015/05/13 01:16:15 pgoyette Exp $	*/
+/*	$NetBSD: sysv_msg.c,v 1.70 2015/11/06 02:26:42 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2006, 2007 The NetBSD Foundation, Inc.
@@ -50,7 +50,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sysv_msg.c,v 1.69 2015/05/13 01:16:15 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysv_msg.c,v 1.70 2015/11/06 02:26:42 pgoyette Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sysv.h"
@@ -91,8 +91,10 @@
 
 extern int kern_has_sysvmsg;
 
+SYSCTL_SETUP_PROTO(sysctl_ipc_msg_setup);
+
 void
-msginit(void)
+msginit(struct sysctllog **clog)
 {
 	int i, sz;
 	vaddr_t v;
@@ -161,7 +163,10 @@
 
 	kern_has_sysvmsg = 1;
 
-	sysvipcinit();
+#ifdef _MODULE
+	if (clog)
+		sysctl_ipc_msg_setup(clog);
+#endif
 }
 
 int

cvs diff -r1.94 -r1.95 src/sys/kern/sysv_sem.c (expand / switch to context diff)
--- src/sys/kern/sysv_sem.c 2015/05/13 01:16:15 1.94
+++ src/sys/kern/sysv_sem.c 2015/11/06 02:26:42 1.95
@@ -1,4 +1,4 @@
-/*	$NetBSD: sysv_sem.c,v 1.94 2015/05/13 01:16:15 pgoyette Exp $	*/
+/*	$NetBSD: sysv_sem.c,v 1.95 2015/11/06 02:26:42 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2007 The NetBSD Foundation, Inc.
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sysv_sem.c,v 1.94 2015/05/13 01:16:15 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysv_sem.c,v 1.95 2015/11/06 02:26:42 pgoyette Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sysv.h"
@@ -53,6 +53,7 @@
 #include <sys/mount.h>		/* XXX for <sys/syscallargs.h> */
 #include <sys/syscallargs.h>
 #include <sys/kauth.h>
+#include <sys/once.h>
 
 /* 
  * Memory areas:
@@ -91,12 +92,17 @@
 
 extern int kern_has_sysvsem;
 
+SYSCTL_SETUP_PROTO(sysctl_ipc_sem_setup);
+
 struct sem_undo *semu_alloc(struct proc *);
 int semundo_adjust(struct proc *, struct sem_undo **, int, int, int);
 void semundo_clear(int, int);
 
+static ONCE_DECL(exithook_control);
+static int seminit_exithook(void);
+
 void
-seminit(void)
+seminit(struct sysctllog **clog)
 {
 	int i, sz;
 	vaddr_t v;
@@ -134,13 +140,21 @@
 		suptr->un_proc = NULL;
 	}
 	semu_list = NULL;
-	hook = exithook_establish(semexit, NULL);
 
 	kern_has_sysvsem = 1;
 
-	kern_has_sysvsem = 1;
+#ifdef _MODULE
+	if (clog)
+		sysctl_ipc_sem_setup(clog);
+#endif
+}
 
-	sysvipcinit();
+static int
+seminit_exithook(void)
+{
+
+	hook = exithook_establish(semexit, NULL);
+	return 0;
 }
 
 int
@@ -157,7 +171,8 @@
 	}
 
 	/* Remove the exit hook */
-	exithook_disestablish(hook);
+	if (hook)
+		exithook_disestablish(hook);
 
 	/* Destroy all our condvars */
 	for (i = 0; i < seminfo.semmni; i++) {
@@ -332,6 +347,8 @@
 sys_semconfig(struct lwp *l, const struct sys_semconfig_args *uap, register_t *retval)
 {
 
+	RUN_ONCE(&exithook_control, seminit_exithook);
+
 	*retval = 0;
 	return 0;
 }
@@ -489,6 +506,8 @@
 	void *pass_arg;
 	union __semun karg;
 
+	RUN_ONCE(&exithook_control, seminit_exithook);
+
 	cmd = SCARG(uap, cmd);
 
 	pass_arg = get_semctl_arg(cmd, &sembuf, &karg);
@@ -690,6 +709,8 @@
 	int semflg = SCARG(uap, semflg);
 	kauth_cred_t cred = l->l_cred;
 
+	RUN_ONCE(&exithook_control, seminit_exithook);
+
 	SEM_PRINTF(("semget(0x%x, %d, 0%o)\n", key, nsems, semflg));
 
 	mutex_enter(&semlock);
@@ -797,6 +818,8 @@
 	int i, error;
 	int do_wakeup, do_undos;
 
+	RUN_ONCE(&exithook_control, seminit_exithook);
+
 	SEM_PRINTF(("call to semop(%d, %p, %zd)\n", semid, SCARG(uap,sops), nsops));
 
 	if (__predict_false((p->p_flag & PK_SYSVSEM) == 0)) {
@@ -1112,7 +1135,6 @@
 
 			semaptr = &sema[semid];
 			if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0)
-				panic("semexit - semid not allocated");
 			if (semnum >= semaptr->sem_nsems)
 				panic("semexit - semnum out of range");
 

cvs diff -r1.129 -r1.130 src/sys/kern/sysv_shm.c (expand / switch to context diff)
--- src/sys/kern/sysv_shm.c 2015/11/05 00:10:47 1.129
+++ src/sys/kern/sysv_shm.c 2015/11/06 02:26:42 1.130
@@ -1,4 +1,4 @@
-/*	$NetBSD: sysv_shm.c,v 1.129 2015/11/05 00:10:47 pgoyette Exp $	*/
+/*	$NetBSD: sysv_shm.c,v 1.130 2015/11/06 02:26:42 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2007 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sysv_shm.c,v 1.129 2015/11/05 00:10:47 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysv_shm.c,v 1.130 2015/11/06 02:26:42 pgoyette Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sysv.h"
@@ -110,6 +110,8 @@
 
 extern int kern_has_sysvshm;
 
+SYSCTL_SETUP_PROTO(sysctl_ipc_shm_setup);
+
 #ifdef SHMDEBUG
 #define SHMPRINTF(a) printf a
 #else
@@ -951,7 +953,7 @@
 }
 
 void
-shminit(void)
+shminit(struct sysctllog **clog)
 {
 	vaddr_t v;
 	size_t sz;
@@ -994,7 +996,10 @@
 	uvm_shmexit = shmexit;
 	uvm_shmfork = shmfork;
 
-	sysvipcinit();
+#ifdef _MODULE
+	if (clog)
+		sysctl_ipc_shm_setup(clog);
+#endif
 }
 
 int

cvs diff -r1.25 -r1.26 src/sys/sys/msg.h (expand / switch to context diff)
--- src/sys/sys/msg.h 2015/05/13 01:16:15 1.25
+++ src/sys/sys/msg.h 2015/11/06 02:26:42 1.26
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg.h,v 1.25 2015/05/13 01:16:15 pgoyette Exp $	*/
+/*	$NetBSD: msg.h,v 1.26 2015/11/06 02:26:42 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2007 The NetBSD Foundation, Inc.
@@ -209,7 +209,7 @@
 
 struct proc;
 
-void	msginit(void);
+void	msginit(struct sysctllog **);
 int	msgfini(void);
 int	msgctl1(struct lwp *, int, int, struct msqid_ds *);
 int	msgsnd1(struct lwp *, int, const char *, size_t, int, size_t,

cvs diff -r1.31 -r1.32 src/sys/sys/sem.h (expand / switch to context diff)
--- src/sys/sys/sem.h 2015/05/13 01:16:15 1.31
+++ src/sys/sys/sem.h 2015/11/06 02:26:42 1.32
@@ -1,4 +1,4 @@
-/*	$NetBSD: sem.h,v 1.31 2015/05/13 01:16:15 pgoyette Exp $	*/
+/*	$NetBSD: sem.h,v 1.32 2015/11/06 02:26:42 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -222,7 +222,7 @@
 #endif
 __END_DECLS
 #else
-void	seminit(void);
+void	seminit(struct sysctllog **);
 int	semfini(void);
 void	semexit(struct proc *, void *);
 

cvs diff -r1.50 -r1.51 src/sys/sys/shm.h (expand / switch to context diff)
--- src/sys/sys/shm.h 2015/11/05 00:10:48 1.50
+++ src/sys/sys/shm.h 2015/11/06 02:26:42 1.51
@@ -1,4 +1,4 @@
-/*	$NetBSD: shm.h,v 1.50 2015/11/05 00:10:48 pgoyette Exp $	*/
+/*	$NetBSD: shm.h,v 1.51 2015/11/06 02:26:42 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -172,7 +172,7 @@
 
 struct vmspace;
 
-void	shminit(void);
+void	shminit(struct sysctllog **);
 int	shmfini(void);
 void	shmfork(struct vmspace *, struct vmspace *);
 void	shmexit(struct vmspace *);