Subject: run ddb(4) in "batch mode"
To: None <current-users@netbsd.org>
From: Jukka Salmi <j+nbsd@2007.salmi.ch>
List: current-users
Date: 03/28/2007 15:45:02
--n8g4imXOkfNTN/H1
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,

on a semi-production system I wanted to run some ddb commands in case
of kernel panics while still achieving best possible uptime, i.e.
without having to intervene manually to get the system up and running
again. I set

	ddb.onpanic=1
	ddb.tee_msgbuf=1
	ddb.commandonenter='trace; [...]; reboot 0x4'

and configured the system notice me in case of an unclean shutdown.

This didn't really work as expected because the ddb.commandonenter
commands caused ddb to print more than ddb.lines (24) lines of output;
thus ddb waited for user input to print the next page of output, and
didn't execute the `reboot' command automatically...

To fix this problem I added a new variable `batchmode', accessible via
sysctl(3) as the other built-in ddb variables. The resulting patch
against netbsd-4 is attached.

Comments are welcome. Please tell in case this is of use for anybody
else, and I'll send a PR.


Regards, Jukka

-- 
bashian roulette:
$ ((RANDOM%6)) || rm -rf ~

--n8g4imXOkfNTN/H1
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff

Index: sys/ddb/db_output.c
===================================================================
RCS file: /cvsroot/src/sys/ddb/db_output.c,v
retrieving revision 1.29
diff -u -p -r1.29 db_output.c
--- sys/ddb/db_output.c	11 Dec 2005 12:20:53 -0000	1.29
+++ sys/ddb/db_output.c	28 Mar 2007 13:16:33 -0000
@@ -33,6 +33,8 @@
 #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD: db_output.c,v 1.29 2005/12/11 12:20:53 christos Exp $");
 
+#include "opt_ddbparam.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 
@@ -72,10 +74,15 @@ __KERNEL_RCSID(0, "$NetBSD: db_output.c,
 #define DB_MIN_MAX_LINE		3	/* minimum max line */
 #define CTRL(c)			((c) & 0xff)
 
+#ifndef DDB_BATCHMODE
+#define DDB_BATCHMODE		0	/* run in batch mode if non-zero */
+#endif /* DDB_BATCHMODE */
+
 int	db_output_line = 0;			/* output line number */
 int	db_tab_stop_width = 8;			/* how wide are tab stops? */
 int	db_max_line = DB_MAX_LINE;		/* output max lines */
 int	db_max_width = DB_MAX_WIDTH;		/* output line width */
+int	db_batchmode = DDB_BATCHMODE;		/* run in batch mode */
 
 static int	db_output_position = 0;		/* output column */
 static int	db_last_non_space = 0;		/* last non-space character */
@@ -142,7 +149,7 @@ db_more(void)
 void
 db_putchar(int c)
 {
-	if (db_max_line >= DB_MIN_MAX_LINE && db_output_line >= db_max_line-1)
+	if (!db_batchmode && db_max_line >= DB_MIN_MAX_LINE && db_output_line >= db_max_line-1)
 		db_more();
 	if (c > ' ' && c <= '~') {
 		/*
Index: sys/ddb/db_output.h
===================================================================
RCS file: /cvsroot/src/sys/ddb/db_output.h,v
retrieving revision 1.17
diff -u -p -r1.17 db_output.h
--- sys/ddb/db_output.h	5 Jun 2002 17:53:52 -0000	1.17
+++ sys/ddb/db_output.h	28 Mar 2007 13:16:33 -0000
@@ -47,6 +47,7 @@ extern int	db_max_width;
 extern int	db_output_line;
 extern int	db_radix;
 extern int	db_tab_stop_width;
+extern int	db_batchmode;
 
 #define	DB_NEXT_TAB(i) \
 	((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width)
Index: sys/ddb/db_variables.c
===================================================================
RCS file: /cvsroot/src/sys/ddb/db_variables.c,v
retrieving revision 1.38
diff -u -p -r1.38 db_variables.c
--- sys/ddb/db_variables.c	16 Nov 2006 01:32:44 -0000	1.38
+++ sys/ddb/db_variables.c	28 Mar 2007 13:16:33 -0000
@@ -88,6 +88,7 @@ const struct db_variable db_vars[] = {
 	{ "onpanic",	(void *)&db_onpanic,	db_rw_internal_variable, NULL },
 	{ "fromconsole", (void *)&db_fromconsole, db_rw_internal_variable, NULL },
 	{ "tee_msgbuf",	(void *)&db_tee_msgbuf,	db_rw_internal_variable, NULL },
+	{ "batchmode",	(void *)&db_batchmode,	db_rw_internal_variable, NULL },
 };
 const struct db_variable * const db_evars = db_vars + sizeof(db_vars)/sizeof(db_vars[0]);
 
@@ -166,6 +167,13 @@ SYSCTL_SETUP(sysctl_ddb_setup, "sysctl d
 		       SYSCTL_DESCR("Whether to tee ddb output to the msgbuf"),
 		       NULL, 0, &db_tee_msgbuf, 0,
 		       CTL_DDB, CTL_CREATE, CTL_EOL);
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+		       CTLTYPE_INT, "batchmode",
+		       SYSCTL_DESCR("Whether to show more than one page of "
+				    "ddb output at a time"),
+		       NULL, 0, &db_batchmode, 0,
+		       CTL_DDB, DDBCTL_BATCHMODE, CTL_EOL);
 
 	sysctl_createv(clog, 0, NULL, NULL,
 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
Index: sys/ddb/files.ddb
===================================================================
RCS file: /cvsroot/src/sys/ddb/files.ddb,v
retrieving revision 1.1
diff -u -p -r1.1 files.ddb
--- sys/ddb/files.ddb	27 Nov 2005 22:44:35 -0000	1.1
+++ sys/ddb/files.ddb	28 Mar 2007 13:16:33 -0000
@@ -6,7 +6,7 @@
 defflag opt_ddb.h		DDB
 defparam opt_ddbparam.h		DDB_FROMCONSOLE DDB_ONPANIC DDB_HISTORY_SIZE
 				DDB_BREAK_CHAR DDB_KEYCODE SYMTAB_SPACE
-				DDB_COMMANDONENTER
+				DDB_COMMANDONENTER DDB_BATCHMODE
 
 file	ddb/db_access.c			ddb | kgdb	# XXX kgdb reference
 file	ddb/db_aout.c			ddb
Index: sys/sys/sysctl.h
===================================================================
RCS file: /cvsroot/src/sys/sys/sysctl.h,v
retrieving revision 1.165
diff -u -p -r1.165 sysctl.h
--- sys/sys/sysctl.h	25 Nov 2006 21:40:06 -0000	1.165
+++ sys/sys/sysctl.h	28 Mar 2007 13:16:34 -0000
@@ -818,7 +818,8 @@ struct kinfo_file {
 #define	DDBCTL_TABSTOPS		5	/* int: tab width */
 #define	DDBCTL_ONPANIC		6	/* int: DDB on panic if non-zero */
 #define	DDBCTL_FROMCONSOLE	7	/* int: DDB via console if non-zero */
-#define	DDBCTL_MAXID		8	/* number of valid DDB ids */
+#define	DDBCTL_BATCHMODE	8	/* int: DDB in batch mode if non-zero */
+#define	DDBCTL_MAXID		9	/* number of valid DDB ids */
 
 #define	CTL_DDB_NAMES { \
 	{ 0, 0 }, \
@@ -829,6 +830,7 @@ struct kinfo_file {
 	{ "tabstops", CTLTYPE_INT }, \
 	{ "onpanic", CTLTYPE_INT }, \
 	{ "fromconsole", CTLTYPE_INT }, \
+	{ "batchmode", CTLTYPE_INT }, \
 }
 
 /*

--n8g4imXOkfNTN/H1--