Module Name:    src
Committed By:   pgoyette
Date:           Fri Nov  6 02:26:42 UTC 2015

Modified Files:
        src/sys/kern: init_main.c sysv_ipc.c sysv_msg.c sysv_sem.c sysv_shm.c
        src/sys/sys: msg.h sem.h shm.h

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.472 -r1.473 src/sys/kern/init_main.c
cvs rdiff -u -r1.29 -r1.30 src/sys/kern/sysv_ipc.c
cvs rdiff -u -r1.69 -r1.70 src/sys/kern/sysv_msg.c
cvs rdiff -u -r1.94 -r1.95 src/sys/kern/sysv_sem.c
cvs rdiff -u -r1.129 -r1.130 src/sys/kern/sysv_shm.c
cvs rdiff -u -r1.25 -r1.26 src/sys/sys/msg.h
cvs rdiff -u -r1.31 -r1.32 src/sys/sys/sem.h
cvs rdiff -u -r1.50 -r1.51 src/sys/sys/shm.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/init_main.c
diff -u src/sys/kern/init_main.c:1.472 src/sys/kern/init_main.c:1.473
--- src/sys/kern/init_main.c:1.472	Thu Oct 29 00:27:08 2015
+++ src/sys/kern/init_main.c	Fri Nov  6 02:26:42 2015
@@ -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 @@ extern void *_binary_splash_image_end;
 #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,26 +516,11 @@ main(void)
 	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
 	/*
 	 * Initialise the Veriexec subsystem.

Index: src/sys/kern/sysv_ipc.c
diff -u src/sys/kern/sysv_ipc.c:1.29 src/sys/kern/sysv_ipc.c:1.30
--- src/sys/kern/sysv_ipc.c:1.29	Fri Nov  6 01:00:41 2015
+++ src/sys/kern/sysv_ipc.c	Fri Nov  6 02:26:42 2015
@@ -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 @@ struct	msginfo msginfo = {
 
 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 @@ sysv_ipc_modcmd(modcmd_t cmd, void *arg)
 
 	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 @@ sysv_ipc_modcmd(modcmd_t cmd, void *arg)
 #ifdef SYSVSEM
 		if (semfini()) {
 #ifdef SYSVSHM
-			shminit();
+			shminit(NULL);
 #endif
 			return EBUSY;
 		}
@@ -220,10 +215,10 @@ sysv_ipc_modcmd(modcmd_t cmd, void *arg)
 #ifdef SYSVMSG
 		if (msgfini()) {
 #ifdef SYSVSEM
-			seminit();
+			seminit(NULL);
 #endif
 #ifdef SYSVSHM
-			shminit();
+			shminit(NULL);
 #endif
 			return EBUSY;
 		}
@@ -237,7 +232,7 @@ sysv_ipc_modcmd(modcmd_t cmd, void *arg)
 #ifdef _MODULE
 		/* Remove the sysctl sub-trees */
 		sysctl_teardown(&sysctl_sysvipc_clog);
-#endif  
+#endif
 
 		/* Remove the kauth listener */
 		sysvipcfini();
@@ -345,8 +340,7 @@ void
 sysvipcinit(void)
 {
 
-	if (sysvipc_listener != NULL)
-		return;
+	KASSERT(sysvipc_listener == NULL);
 
 	sysvipc_listener = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
 	    sysvipc_listener_cb, NULL);

Index: src/sys/kern/sysv_msg.c
diff -u src/sys/kern/sysv_msg.c:1.69 src/sys/kern/sysv_msg.c:1.70
--- src/sys/kern/sysv_msg.c:1.69	Wed May 13 01:16:15 2015
+++ src/sys/kern/sysv_msg.c	Fri Nov  6 02:26:42 2015
@@ -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 @@ static void msg_freehdr(struct __msg *);
 
 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 @@ msginit(void)
 
 	kern_has_sysvmsg = 1;
 
-	sysvipcinit();
+#ifdef _MODULE
+	if (clog)
+		sysctl_ipc_msg_setup(clog);
+#endif
 }
 
 int

Index: src/sys/kern/sysv_sem.c
diff -u src/sys/kern/sysv_sem.c:1.94 src/sys/kern/sysv_sem.c:1.95
--- src/sys/kern/sysv_sem.c:1.94	Wed May 13 01:16:15 2015
+++ src/sys/kern/sysv_sem.c	Fri Nov  6 02:26:42 2015
@@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: sysv_sem.c,v
 #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 @@ void *hook;	/* cookie from exithook_esta
 
 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 @@ seminit(void)
 		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 @@ semfini(void)
 	}
 
 	/* 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 @@ int
 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 @@ sys_____semctl50(struct lwp *l, const st
 	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 @@ sys_semget(struct lwp *l, const struct s
 	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 @@ sys_semop(struct lwp *l, const struct sy
 	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 @@ semexit(struct proc *p, void *v)
 
 			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");
 

Index: src/sys/kern/sysv_shm.c
diff -u src/sys/kern/sysv_shm.c:1.129 src/sys/kern/sysv_shm.c:1.130
--- src/sys/kern/sysv_shm.c:1.129	Thu Nov  5 00:10:47 2015
+++ src/sys/kern/sysv_shm.c	Fri Nov  6 02:26:42 2015
@@ -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 @@ struct shmmap_state {
 
 extern int kern_has_sysvshm;
 
+SYSCTL_SETUP_PROTO(sysctl_ipc_shm_setup);
+
 #ifdef SHMDEBUG
 #define SHMPRINTF(a) printf a
 #else
@@ -951,7 +953,7 @@ shmrealloc(int newshmni)
 }
 
 void
-shminit(void)
+shminit(struct sysctllog **clog)
 {
 	vaddr_t v;
 	size_t sz;
@@ -994,7 +996,10 @@ shminit(void)
 	uvm_shmexit = shmexit;
 	uvm_shmfork = shmfork;
 
-	sysvipcinit();
+#ifdef _MODULE
+	if (clog)
+		sysctl_ipc_shm_setup(clog);
+#endif
 }
 
 int

Index: src/sys/sys/msg.h
diff -u src/sys/sys/msg.h:1.25 src/sys/sys/msg.h:1.26
--- src/sys/sys/msg.h:1.25	Wed May 13 01:16:15 2015
+++ src/sys/sys/msg.h	Fri Nov  6 02:26:42 2015
@@ -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 @@ __END_DECLS
 
 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,

Index: src/sys/sys/sem.h
diff -u src/sys/sys/sem.h:1.31 src/sys/sys/sem.h:1.32
--- src/sys/sys/sem.h:1.31	Wed May 13 01:16:15 2015
+++ src/sys/sys/sem.h	Fri Nov  6 02:26:42 2015
@@ -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 @@ int	semconfig(int);
 #endif
 __END_DECLS
 #else
-void	seminit(void);
+void	seminit(struct sysctllog **);
 int	semfini(void);
 void	semexit(struct proc *, void *);
 

Index: src/sys/sys/shm.h
diff -u src/sys/sys/shm.h:1.50 src/sys/sys/shm.h:1.51
--- src/sys/sys/shm.h:1.50	Thu Nov  5 00:10:48 2015
+++ src/sys/sys/shm.h	Fri Nov  6 02:26:42 2015
@@ -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 @@ extern int shm_nused;
 
 struct vmspace;
 
-void	shminit(void);
+void	shminit(struct sysctllog **);
 int	shmfini(void);
 void	shmfork(struct vmspace *, struct vmspace *);
 void	shmexit(struct vmspace *);

Reply via email to