From: Harald Hoyer <harald@xxxxxxxxxx> --- sys-utils/wdctl.8 | 2 ++ sys-utils/wdctl.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/sys-utils/wdctl.8 b/sys-utils/wdctl.8 index a8f2254..5fa1173 100644 --- a/sys-utils/wdctl.8 +++ b/sys-utils/wdctl.8 @@ -27,6 +27,8 @@ Do not print a header line for flags table. Do not print watchdog identity information. .IP "\fB\-T\fR, \fB\-\-notimeouts\fP" Do not print watchdog timeouts. +.IP "\fB\-s\fR, \fB\-\-settimeout \fI<seconds>\fP" +Set the watchdog timeout in seconds. .IP "\fB\-o\fR, \fB\-\-output \fIlist\fP" Define the output columns to use in table of watchdog flags. If no output arrangement is specified, then a default set is used. Use diff --git a/sys-utils/wdctl.c b/sys-utils/wdctl.c index 7605864..b266969 100644 --- a/sys-utils/wdctl.c +++ b/sys-utils/wdctl.c @@ -154,6 +154,7 @@ static void usage(FILE *out) " -o, --output <list> output columns of the flags\n" " -r, --raw use raw output format for flags table\n" " -T, --notimeouts don't print watchdog timeouts\n" + " -s, --settimeout set watchdog timeout\n" " -x, --flags-only print only flags table (same as -I -T)\n"), out); fputs(USAGE_SEPARATOR, out); @@ -258,6 +259,60 @@ done: tt_free_table(tt); return rc; } +/* + * Warning: successfully opened watchdog has to be properly closed with magic + * close character otherwise the machine will be rebooted! + * + * Don't use err() or exit() here! + */ +static int set_watchdog(struct wdinfo *wd, int timeout) +{ + int fd; + sigset_t sigs, oldsigs; + int rc = 0; + + assert(wd->device); + + sigemptyset(&oldsigs); + sigfillset(&sigs); + sigprocmask(SIG_BLOCK, &sigs, &oldsigs); + + fd = open(wd->device, O_WRONLY|O_CLOEXEC); + + if (fd < 0) { + if (errno == EBUSY) + warnx(_("%s: watchdog already in use, terminating."), + wd->device); + warn(_("cannot open %s"), wd->device); + return -1; + } + + for (;;) { + /* We just opened this to query the state, not to arm + * it hence use the magic close character */ + static const char v = 'V'; + + if (write(fd, &v, 1) >= 0) + break; + if (errno != EINTR) { + warn(_("%s: failed to disarm watchdog"), wd->device); + break; + } + /* Let's try hard, since if we don't get this right + * the machine might end up rebooting. */ + } + + if (ioctl(fd, WDIOC_SETTIMEOUT, &timeout) != 0) { + rc = errno; + warn(_("cannot set timeout for %s"), wd->device); + } + + close(fd); + sigprocmask(SIG_SETMASK, &oldsigs, NULL); + printf("Set timeout to %d seconds\n", timeout); + + return rc; +} /* * Warning: successfully opened watchdog has to be properly closed with magic @@ -381,6 +436,7 @@ int main(int argc, char *argv[]) int c, tt_flags = 0, res = EXIT_SUCCESS, count = 0; char noflags = 0, noident = 0, notimeouts = 0, oneline = 0; uint32_t wanted = 0; + int timeout = 0; static const struct option long_opts[] = { { "flags", required_argument, NULL, 'f' }, @@ -390,6 +446,7 @@ int main(int argc, char *argv[]) { "noheadings", no_argument, NULL, 'n' }, { "noident", no_argument, NULL, 'I' }, { "notimeouts", no_argument, NULL, 'T' }, + { "settimeout", required_argument, NULL, 's' }, { "output", required_argument, NULL, 'o' }, { "oneline", no_argument, NULL, 'O' }, { "raw", no_argument, NULL, 'r' }, @@ -409,7 +466,7 @@ int main(int argc, char *argv[]) atexit(close_stdout); while ((c = getopt_long(argc, argv, - "d:f:hFnITo:OrVx", long_opts, NULL)) != -1) { + "d:f:hFnITo:s:OrVx", long_opts, NULL)) != -1) { err_exclusive_options(c, long_opts, excl, excl_st); @@ -421,6 +478,9 @@ int main(int argc, char *argv[]) if (ncolumns < 0) return EXIT_FAILURE; break; + case 's': + timeout = strtos32_or_err(optarg, _("invalid timeout argument")); + break; case 'f': if (string_to_bitmask(optarg, (unsigned long *) &wanted, name2bit) != 0) return EXIT_FAILURE; @@ -481,6 +541,13 @@ int main(int argc, char *argv[]) fputc('\n', stdout); count++; + if (timeout) { + rc = set_watchdog(&wd, timeout); + if (rc) { + res = EXIT_FAILURE; + } + } + rc = read_watchdog(&wd); if (rc) { res = EXIT_FAILURE; -- 1.7.11.2 -- To unsubscribe from this list: send the line "unsubscribe util-linux" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html