summaryrefslogtreecommitdiffstats
path: root/sys/ddb/db_command.c
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2010-05-24 16:41:05 +0000
committerbz <bz@FreeBSD.org>2010-05-24 16:41:05 +0000
commit6776200983bceda223944d82e99b820658ecd62b (patch)
treebdd087309119f3eab516764a7a8a1643c4691a2b /sys/ddb/db_command.c
parent36eb388782ebccd910604f919e2bd8f13cc05362 (diff)
downloadFreeBSD-src-6776200983bceda223944d82e99b820658ecd62b.zip
FreeBSD-src-6776200983bceda223944d82e99b820658ecd62b.tar.gz
MFp4 @178364:
Implement an optional delay to the ddb reset/reboot command. This allows textdumps to be run automatically with unattended reboots after a resonable timeout, while still permitting an administrator to break into debugger if attached to the console at the time of the event for further debugging. Cap the maximum delay at 1 week to avoid highly accidental results, and default to 15s in case of problems parsing the timeout value. Move hex2dec helper function from db_thread.c to db_command.c to make it generally available and prefix it with a "db_" to avoid namespace collisions. Reviewed by: rwatson MFC after: 4 weeks
Diffstat (limited to 'sys/ddb/db_command.c')
-rw-r--r--sys/ddb/db_command.c64
1 files changed, 59 insertions, 5 deletions
diff --git a/sys/ddb/db_command.c b/sys/ddb/db_command.c
index 73de0c5..7c7f54e 100644
--- a/sys/ddb/db_command.c
+++ b/sys/ddb/db_command.c
@@ -661,13 +661,42 @@ out:
#undef DB_ERROR
}
+/*
+ * Reboot. In case there is an additional argument, take it as delay in
+ * seconds. Default to 15s if we cannot parse it and make sure we will
+ * never wait longer than 1 week. Some code is similar to
+ * kern_shutdown.c:shutdown_panic().
+ */
+#ifndef DB_RESET_MAXDELAY
+#define DB_RESET_MAXDELAY (3600 * 24 * 7)
+#endif
+
static void
-db_reset(dummy1, dummy2, dummy3, dummy4)
- db_expr_t dummy1;
- boolean_t dummy2;
- db_expr_t dummy3;
- char * dummy4;
+db_reset(db_expr_t addr, boolean_t have_addr, db_expr_t count __unused,
+ char *modif __unused)
{
+ int delay, loop;
+
+ if (have_addr) {
+ delay = (int)db_hex2dec(addr);
+
+ /* If we parse to fail, use 15s. */
+ if (delay == -1)
+ delay = 15;
+
+ /* Cap at one week. */
+ if ((uintmax_t)delay > (uintmax_t)DB_RESET_MAXDELAY)
+ delay = DB_RESET_MAXDELAY;
+
+ db_printf("Automatic reboot in %d seconds - "
+ "press a key on the console to abort\n", delay);
+ for (loop = delay * 10; loop > 0; --loop) {
+ DELAY(1000 * 100); /* 1/10th second */
+ /* Did user type a key? */
+ if (cncheckc() != -1)
+ return;
+ }
+ }
cpu_reset();
}
@@ -771,3 +800,28 @@ db_stack_trace_all(db_expr_t dummy, boolean_t dummy2, db_expr_t dummy3,
kdb_jmpbuf(prev_jb);
}
}
+
+/*
+ * Take the parsed expression value from the command line that was parsed
+ * as a hexadecimal value and convert it as if the expression was parsed
+ * as a decimal value. Returns -1 if the expression was not a valid
+ * decimal value.
+ */
+db_expr_t
+db_hex2dec(db_expr_t expr)
+{
+ uintptr_t x, y;
+ db_expr_t val;
+
+ y = 1;
+ val = 0;
+ x = expr;
+ while (x != 0) {
+ if (x % 16 > 9)
+ return (-1);
+ val += (x % 16) * (y);
+ x >>= 4;
+ y *= 10;
+ }
+ return (val);
+}
OpenPOWER on IntegriCloud