Module Name:    src
Committed By:   pgoyette
Date:           Tue Jan 10 00:50:57 UTC 2017

Modified Files:
        src/sys/kern: kern_history.c
        src/sys/sys: kernhist.h

Log Message:
Rework the sysctl initialization to avoid creating new nodes from
within the helper function.  This should avoid the "locking against
myself" error reported earlier.


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/sys/kern/kern_history.c
cvs rdiff -u -r1.17 -r1.18 src/sys/sys/kernhist.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/kern_history.c
diff -u src/sys/kern/kern_history.c:1.12 src/sys/kern/kern_history.c:1.13
--- src/sys/kern/kern_history.c:1.12	Sun Jan  8 19:49:25 2017
+++ src/sys/kern/kern_history.c	Tue Jan 10 00:50:57 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_history.c,v 1.12 2017/01/08 19:49:25 christos Exp $	 */
+/*	$NetBSD: kern_history.c,v 1.13 2017/01/10 00:50:57 pgoyette Exp $	 */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_history.c,v 1.12 2017/01/08 19:49:25 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_history.c,v 1.13 2017/01/10 00:50:57 pgoyette Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kernhist.h"
@@ -77,6 +77,7 @@ struct addr_xlt {
  */
 
 struct kern_history_head kern_histories;
+bool kernhist_sysctl_ready = 0;
 
 int kernhist_print_enabled = 1;
 
@@ -275,20 +276,25 @@ kernhist_print(void *addr, void (*pr)(co
  */
 
 /*
- * sysctl_hist_new()
+ * sysctl_kernhist_new()
  *
- *	Scan the list of histories;  for any history that does not already
- *	have a sysctl node (under kern.hist) we create a new one and record
- *	it's node number.
+ *	If the specified history (or, if no history is specified, any
+ *	history) does not already have a sysctl node (under kern.hist)
+ *	we create a new one and record it's node number.
  */
-static void
-sysctl_hist_new(void)
+void
+sysctl_kernhist_new(struct kern_history *hist)
 {
 	int error;
 	struct kern_history *h;
 	const struct sysctlnode *rnode = NULL;
 
+	if (kernhist_sysctl_ready == 0)
+		return;
+
 	LIST_FOREACH(h, &kern_histories, list) {
+		if (hist && h != hist)
+			continue;
 		if (h->s != 0)
 			continue;
 		error = sysctl_createv(NULL, 0, NULL, &rnode,
@@ -299,6 +305,8 @@ sysctl_hist_new(void)
 			    CTL_KERN, sysctl_hist_node, CTL_CREATE, CTL_EOL);
 		if (error == 0)
 			h->s = rnode->sysctl_num;
+		if (hist == h)
+			break;
 	}
 }
 
@@ -320,7 +328,9 @@ sysctl_kernhist_init(void)
 			CTL_KERN, CTL_CREATE, CTL_EOL);
 	sysctl_hist_node = rnode->sysctl_num;
 
-	sysctl_hist_new();
+	kernhist_sysctl_ready = 1;
+
+	sysctl_kernhist_new(NULL);
 }
 
 /*
@@ -386,8 +396,6 @@ sysctl_kernhist_helper(SYSCTLFN_ARGS)
 	int i, j;
 	int error;
 
-	sysctl_hist_new();	/* make sure we're up to date */
-
 	if (namelen == 1 && name[0] == CTL_QUERY)
 		return sysctl_query(SYSCTLFN_CALL(rnode));
 

Index: src/sys/sys/kernhist.h
diff -u src/sys/sys/kernhist.h:1.17 src/sys/sys/kernhist.h:1.18
--- src/sys/sys/kernhist.h:1.17	Thu Jan  5 03:40:33 2017
+++ src/sys/sys/kernhist.h	Tue Jan 10 00:50:57 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: kernhist.h,v 1.17 2017/01/05 03:40:33 pgoyette Exp $	*/
+/*	$NetBSD: kernhist.h,v 1.18 2017/01/10 00:50:57 pgoyette Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -157,6 +157,7 @@ do { \
 		kmem_zalloc(sizeof(struct kern_history_ent) * (N), KM_SLEEP); \
 	(NAME).s = 0; \
 	LIST_INSERT_HEAD(&kern_histories, &(NAME), list); \
+	sysctl_kernhist_new(&(NAME)); \
 } while (/*CONSTCOND*/ 0)
 
 #define KERNHIST_INITIALIZER(NAME,BUF) \
@@ -183,6 +184,7 @@ do { \
 	(NAME).s = 0; \
 	memset((NAME).e, 0, sizeof(struct kern_history_ent) * (NAME).n); \
 	KERNHIST_LINK_STATIC(NAME); \
+	sysctl_kernhist_new(&(NAME)); \
 } while (/*CONSTCOND*/ 0)
 
 #ifndef KERNHIST_DELAY
@@ -271,6 +273,7 @@ void	kernhist_print(void *, void (*)(con
 #endif /* DDB */
 
 void sysctl_kernhist_init(void);
+void sysctl_kernhist_new(struct kern_history *);
 
 #endif /* KERNHIST */
 

Reply via email to