wdctl: add --setpretimeout
Addresses: https://github.com/karelzak/util-linux/issues/1475 Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
c4a543ff6c
commit
152b47d27a
2 changed files with 38 additions and 8 deletions
|
@ -42,10 +42,17 @@ Define the output columns to use in table of watchdog flags. If no output arrang
|
|||
*-O*, *--oneline*::
|
||||
Print all wanted information on one line in key="value" output format.
|
||||
|
||||
*-p*, *--setpretimeout* _seconds_::
|
||||
Set the watchdog pre-timeout in seconds. A watchdog pre-timeout is a
|
||||
notification generated by the watchdog before the watchdog reset might occur in
|
||||
the event the watchdog has not been serviced. This notification is handled by
|
||||
the kernel and can be configured to take an action using sysfs (e.g.
|
||||
/sys/class/watchdog/watchdog0/pretimeout_governor).
|
||||
|
||||
*-r*, *--raw*::
|
||||
Use the raw output format.
|
||||
|
||||
*-s*, *-settimeout* _seconds_::
|
||||
*-s*, *--settimeout* _seconds_::
|
||||
Set the watchdog timeout in seconds.
|
||||
|
||||
*-T*, *--notimeouts*::
|
||||
|
|
|
@ -216,6 +216,7 @@ static void __attribute__((__noreturn__)) usage(void)
|
|||
" -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"
|
||||
" -p, --setpretimeout <sec> set watchdog pre-timeout\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"
|
||||
|
@ -334,19 +335,27 @@ done:
|
|||
scols_unref_table(table);
|
||||
return rc;
|
||||
}
|
||||
|
||||
enum {
|
||||
WDCTL_SET_TIMEOUT = (1 << 1),
|
||||
WDCTL_SET_PRETIMEOUT = (1 << 2)
|
||||
};
|
||||
|
||||
/*
|
||||
* 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 wd_device *wd, int timeout)
|
||||
static int set_watchdog(struct wd_device *wd, int timeout, int pretimeout,
|
||||
unsigned int flags)
|
||||
{
|
||||
int fd;
|
||||
sigset_t sigs, oldsigs;
|
||||
int rc = 0;
|
||||
|
||||
assert(wd->devpath);
|
||||
assert(flags);
|
||||
|
||||
sigemptyset(&oldsigs);
|
||||
sigfillset(&sigs);
|
||||
|
@ -377,11 +386,18 @@ static int set_watchdog(struct wd_device *wd, int timeout)
|
|||
* the machine might end up rebooting. */
|
||||
}
|
||||
|
||||
if (ioctl(fd, WDIOC_SETTIMEOUT, &timeout) != 0) {
|
||||
rc = errno;
|
||||
if ((flags & WDCTL_SET_TIMEOUT) &&
|
||||
ioctl(fd, WDIOC_SETTIMEOUT, &timeout) != 0) {
|
||||
rc += errno;
|
||||
warn(_("cannot set timeout for %s"), wd->devpath);
|
||||
}
|
||||
|
||||
if ((flags & WDCTL_SET_PRETIMEOUT) &&
|
||||
ioctl(fd, WDIOC_SETPRETIMEOUT, &pretimeout) != 0) {
|
||||
rc += errno;
|
||||
warn(_("cannot set pretimeout for %s"), wd->devpath);
|
||||
}
|
||||
|
||||
if (close(fd))
|
||||
warn(_("write failed"));
|
||||
sigprocmask(SIG_SETMASK, &oldsigs, NULL);
|
||||
|
@ -599,8 +615,9 @@ int main(int argc, char *argv[])
|
|||
struct wd_device wd;
|
||||
struct wd_control ctl = { .hide_headings = 0 };
|
||||
int c, res = EXIT_SUCCESS, count = 0;
|
||||
unsigned int wantset = 0;
|
||||
uint32_t wanted = 0;
|
||||
int timeout = 0;
|
||||
int timeout = 0, pretimeout = 0;
|
||||
const char *dflt_device = NULL;
|
||||
|
||||
static const struct option long_opts[] = {
|
||||
|
@ -612,6 +629,7 @@ int main(int argc, char *argv[])
|
|||
{ "noident", no_argument, NULL, 'I' },
|
||||
{ "notimeouts", no_argument, NULL, 'T' },
|
||||
{ "settimeout", required_argument, NULL, 's' },
|
||||
{ "setpretimeout", required_argument, NULL, 'p' },
|
||||
{ "output", required_argument, NULL, 'o' },
|
||||
{ "oneline", no_argument, NULL, 'O' },
|
||||
{ "raw", no_argument, NULL, 'r' },
|
||||
|
@ -631,7 +649,7 @@ int main(int argc, char *argv[])
|
|||
close_stdout_atexit();
|
||||
|
||||
while ((c = getopt_long(argc, argv,
|
||||
"d:f:hFnITo:s:OrVx", long_opts, NULL)) != -1) {
|
||||
"d:f:hFnITp:o:s:OrVx", long_opts, NULL)) != -1) {
|
||||
|
||||
err_exclusive_options(c, long_opts, excl, excl_st);
|
||||
|
||||
|
@ -645,6 +663,11 @@ int main(int argc, char *argv[])
|
|||
break;
|
||||
case 's':
|
||||
timeout = strtos32_or_err(optarg, _("invalid timeout argument"));
|
||||
wantset |= WDCTL_SET_TIMEOUT;
|
||||
break;
|
||||
case 'p':
|
||||
pretimeout = strtos32_or_err(optarg, _("invalid pretimeout argument"));
|
||||
wantset |= WDCTL_SET_PRETIMEOUT;
|
||||
break;
|
||||
case 'f':
|
||||
if (string_to_bitmask(optarg, (unsigned long *) &wanted, name2bit) != 0)
|
||||
|
@ -707,8 +730,8 @@ int main(int argc, char *argv[])
|
|||
fputc('\n', stdout);
|
||||
count++;
|
||||
|
||||
if (timeout) {
|
||||
rc = set_watchdog(&wd, timeout);
|
||||
if (wantset) {
|
||||
rc = set_watchdog(&wd, timeout, pretimeout, wantset);
|
||||
if (rc) {
|
||||
res = EXIT_FAILURE;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue