From: Lennart Poettering Date: Sat, 10 Apr 2010 21:36:43 +0000 (+0200) Subject: main: switch to primary console vt on crash X-Git-Tag: v1~549 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=601f6a1e820462b1df6ff632d112bef241d556b1 main: switch to primary console vt on crash --- diff --git a/main.c b/main.c index 5f0aeba85..68a902108 100644 --- a/main.c +++ b/main.c @@ -48,7 +48,8 @@ static char *default_unit = NULL; static ManagerRunningAs running_as = _MANAGER_RUNNING_AS_INVALID; static bool dump_core = true; -static bool crash_shell = true; +static bool crash_shell = false; +static int crash_chvt = -1; _noreturn static void freeze(void) { for (;;) @@ -102,6 +103,9 @@ _noreturn static void crash(int sig) { } } + if (crash_chvt) + chvt(crash_chvt); + if (crash_shell) { log_info("Executing crash shell in 10s..."); sleep(10); @@ -170,7 +174,7 @@ static int parse_proc_cmdline_word(const char *word) { int r; if ((r = parse_boolean(word + 18)) < 0) - log_warning("Failed to parse dump core switch %s, Ignoring", word + 18); + log_warning("Failed to parse dump core switch %s, Ignoring.", word + 18); else dump_core = r; @@ -178,10 +182,18 @@ static int parse_proc_cmdline_word(const char *word) { int r; if ((r = parse_boolean(word + 20)) < 0) - log_warning("Failed to parse crash shell switch %s, Ignoring", word + 20); + log_warning("Failed to parse crash shell switch %s, Ignoring.", word + 20); else crash_shell = r; + } else if (startswith(word, "systemd.crash_chvt=")) { + int k; + + if (safe_atoi(word + 19, &k) < 0) + log_warning("Failed to parse crash chvt switch %s, Ignoring.", word + 19); + else + crash_chvt = k; + } else if (startswith(word, "systemd.")) { log_warning("Unknown kernel switch %s. Ignoring.", word); @@ -192,6 +204,7 @@ static int parse_proc_cmdline_word(const char *word) { log_info("systemd.log_level=LEVEL Log level"); log_info("systemd.dump_core=0|1 Dump core on crash"); log_info("systemd.crash_shell=0|1 On crash run shell"); + log_info("systemd.crash_chvt=N Change to VT #N on crash"); } else { unsigned i; diff --git a/util.c b/util.c index f3161bd7f..f9eae6bba 100644 --- a/util.c +++ b/util.c @@ -34,6 +34,9 @@ #include #include #include +#include +#include +#include #include "macro.h" #include "util.h" @@ -1294,6 +1297,31 @@ bool fstype_is_network(const char *fstype) { return false; } +int chvt(int vt) { + int fd, r = 0; + + if ((fd = open("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0) + return -errno; + + if (vt < 0) { + int tiocl[2] = { + TIOCL_GETKMSGREDIRECT, + 0 + }; + + if (ioctl(fd, TIOCLINUX, tiocl) < 0) + return -errno; + + vt = tiocl[0] <= 0 ? 1 : tiocl[0]; + } + + if (ioctl(fd, VT_ACTIVATE, vt) < 0) + r = -errno; + + close_nointr(r); + return r; +} + static const char *const ioprio_class_table[] = { [IOPRIO_CLASS_NONE] = "none", [IOPRIO_CLASS_RT] = "realtime", diff --git a/util.h b/util.h index a716d8a57..ba27b5aae 100644 --- a/util.h +++ b/util.h @@ -198,6 +198,8 @@ int close_all_fds(const int except[], unsigned n_except); bool fstype_is_network(const char *fstype); +int chvt(int vt); + extern char * __progname; const char *ioprio_class_to_string(int i);