From 7d64a2b5d5eeaacd4d7e9b2d201374cc6890c6fb Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 21 Oct 2021 12:38:16 +0200 Subject: [PATCH] wdctl: set_watchdog() refactoring * keep wanted values in struct wd_control * make set_watchdog() more readable Signed-off-by: Karel Zak --- sys-utils/wdctl.c | 126 ++++++++++++++++++++++++---------------------- 1 file changed, 66 insertions(+), 60 deletions(-) diff --git a/sys-utils/wdctl.c b/sys-utils/wdctl.c index 220229a27e..809a47bd2f 100644 --- a/sys-utils/wdctl.c +++ b/sys-utils/wdctl.c @@ -133,6 +133,13 @@ struct wd_device { }; struct wd_control { + /* set */ + int timeout; /* --settimeout */ + int pretimeout; /* --setpretimeout */ + unsigned int set_timeout : 1, + set_pretimeout : 1; + + /* output */ unsigned int show_oneline : 1, show_raw : 1, hide_headings : 1, @@ -141,6 +148,8 @@ struct wd_control { hide_timeouts : 1; }; +#define want_set(_ctl) ((_ctl)->set_timeout || (_ctl)->set_pretimeout) + /* converts flag name to flag bit */ static long name2bit(const char *name, size_t namesz) { @@ -246,6 +255,36 @@ static void __attribute__((__noreturn__)) usage(void) exit(EXIT_SUCCESS); } +static struct path_cxt *get_sysfs(struct wd_device *wd) +{ + struct path_cxt *sys; + struct stat st; + + if (wd->no_sysfs) + return NULL; + if (wd->sysfs) + return wd->sysfs; + if (stat(wd->devpath, &st) != 0) + goto nosysfs; + + sys = ul_new_path(_PATH_SYS_DEVCHAR "/%u:%u", + major(st.st_rdev), minor(st.st_rdev)); + if (!sys) + return NULL; + + if (ul_path_get_dirfd(sys) < 0) + goto nosysfs; /* device not in /sys */ + + if (ul_path_access(sys, F_OK, "identity") != 0) + goto nosysfs; /* no info in /sys (old miscdev?) */ + + wd->sysfs = sys; + return sys; +nosysfs: + wd->no_sysfs = 1; + return NULL; +} + static void add_flag_line(struct libscols_table *table, struct wd_device *wd, const struct wdflag *fl) { int i; @@ -342,26 +381,21 @@ done: 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, int pretimeout, - unsigned int flags) +static int set_watchdog(struct wd_control *ctl, struct wd_device *wd) { int fd; sigset_t sigs, oldsigs; int rc = 0; + assert(wd); assert(wd->devpath); - assert(flags); + assert(ctl); sigemptyset(&oldsigs); sigfillset(&sigs); @@ -392,24 +426,30 @@ static int set_watchdog(struct wd_device *wd, int timeout, int pretimeout, * the machine might end up rebooting. */ } - if ((flags & WDCTL_SET_TIMEOUT) && - ioctl(fd, WDIOC_SETTIMEOUT, &timeout) != 0) { - rc += errno; - warn(_("cannot set timeout for %s"), wd->devpath); + if (ctl->set_timeout) { + if (ioctl(fd, WDIOC_SETTIMEOUT, &ctl->timeout) != 0) { + rc += errno; + warn(_("cannot set timeout for %s"), wd->devpath); + } else + printf(P_("Timeout has been set to %d second.\n", + "Timeout has been set to %d seconds.\n", + ctl->timeout), ctl->timeout); } - if ((flags & WDCTL_SET_PRETIMEOUT) && - ioctl(fd, WDIOC_SETPRETIMEOUT, &pretimeout) != 0) { - rc += errno; - warn(_("cannot set pretimeout for %s"), wd->devpath); + if (ctl->set_pretimeout) { + if (ioctl(fd, WDIOC_SETPRETIMEOUT, &ctl->pretimeout) != 0) { + rc += errno; + warn(_("cannot set pretimeout for %s"), wd->devpath); + } else + printf(P_("Pre-timeout has been set to %d second.\n", + "Pre-timeout has been set to %d seconds.\n", + ctl->pretimeout), ctl->pretimeout); } if (close(fd)) warn(_("write failed")); - sigprocmask(SIG_SETMASK, &oldsigs, NULL); - printf(P_("Timeout has been set to %d second.\n", - "Timeout has been set to %d seconds.\n", timeout), timeout); + sigprocmask(SIG_SETMASK, &oldsigs, NULL); return rc; } @@ -478,35 +518,6 @@ static int read_watchdog_from_device(struct wd_device *wd) return 0; } -static struct path_cxt *get_sysfs(struct wd_device *wd) -{ - struct path_cxt *sys; - struct stat st; - - if (wd->no_sysfs) - return NULL; - if (wd->sysfs) - return wd->sysfs; - if (stat(wd->devpath, &st) != 0) - goto nosysfs; - - sys = ul_new_path(_PATH_SYS_DEVCHAR "/%u:%u", - major(st.st_rdev), minor(st.st_rdev)); - if (!sys) - return NULL; - - if (ul_path_get_dirfd(sys) < 0) - goto nosysfs; /* device not in /sys */ - - if (ul_path_access(sys, F_OK, "identity") != 0) - goto nosysfs; /* no info in /sys (old miscdev?) */ - - wd->sysfs = sys; - return sys; -nosysfs: - wd->no_sysfs = 1; - return NULL; -} /* Returns: <0 error, 0 success, 1 unssuported */ static int read_watchdog_from_sysfs(struct wd_device *wd) @@ -577,9 +588,6 @@ static int read_watchdog(struct wd_device *wd) } read_governors(wd); - - ul_unref_path(wd->sysfs); - wd->sysfs = NULL; return 0; } @@ -684,9 +692,7 @@ 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, pretimeout = 0; const char *dflt_device = NULL; static const struct option long_opts[] = { @@ -731,12 +737,12 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; break; case 's': - timeout = strtos32_or_err(optarg, _("invalid timeout argument")); - wantset |= WDCTL_SET_TIMEOUT; + ctl.timeout = strtos32_or_err(optarg, _("invalid timeout argument")); + ctl.set_timeout = 1; break; case 'p': - pretimeout = strtos32_or_err(optarg, _("invalid pretimeout argument")); - wantset |= WDCTL_SET_PRETIMEOUT; + ctl.pretimeout = strtos32_or_err(optarg, _("invalid pretimeout argument")); + ctl.set_pretimeout = 1; break; case 'f': if (string_to_bitmask(optarg, (unsigned long *) &wanted, name2bit) != 0) @@ -799,8 +805,8 @@ int main(int argc, char *argv[]) fputc('\n', stdout); count++; - if (wantset) { - rc = set_watchdog(&wd, timeout, pretimeout, wantset); + if (want_set(&ctl)) { + rc = set_watchdog(&ctl, &wd); if (rc) { res = EXIT_FAILURE; } @@ -813,7 +819,7 @@ int main(int argc, char *argv[]) } print_device(&ctl, &wd, wanted); - + ul_unref_path(wd.sysfs); } while (optind < argc); return res; -- 2.47.2