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--