]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
wdctl: add "--settimeout" to set the timeout
authorHarald Hoyer <harald@redhat.com>
Wed, 1 Aug 2012 11:39:06 +0000 (13:39 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 2 Aug 2012 17:23:15 +0000 (19:23 +0200)
[kzak@redhat.com: - fix usage() and man page]

Signed-off-by: Karel Zak <kzak@redhat.com>
Signed-off-by: Harald Hoyer <harald@redhat.com>
sys-utils/wdctl.8
sys-utils/wdctl.c

index a8f2254b64861b72085cda6c91c980309be0f0bd..05eaa25419b3d8f83ba8aca3c5248b1e3ed1d597 100644 (file)
@@ -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 \fIseconds\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
index 760586449ec8fc07cb7e815285f01fcc5ab7248d..6be6fd4c2893fb1ccfe1258aa549275c48e693c0 100644 (file)
@@ -146,15 +146,16 @@ static void usage(FILE *out)
 
        fputs(USAGE_OPTIONS, out);
 
-       fputs(_(" -f, --flags <list>    print selected flags only\n"
-               " -F, --noflags         don't print information about flags\n"
-               " -I, --noident         don't print watchdog identity information\n"
-               " -n, --noheadings      don't print headings for flags table\n"
-               " -O, --oneline         print all information on one line\n"
-               " -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"
-               " -x, --flags-only      print only flags table (same as -I -T)\n"), out);
+       fputs(_(" -f, --flags <list>     print selected flags only\n"
+               " -F, --noflags          don't print information about flags\n"
+               " -I, --noident          don't print watchdog identity information\n"
+               " -n, --noheadings       don't print headings for flags table\n"
+               " -O, --oneline          print all information on one line\n"
+               " -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 <sec> set watchdog timeout\n"
+               " -x, --flags-only       print only flags table (same as -I -T)\n"), out);
 
        fputs(USAGE_SEPARATOR, out);
        fputs(USAGE_HELP, 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;