]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
wdctl: set_watchdog() refactoring
authorKarel Zak <kzak@redhat.com>
Thu, 21 Oct 2021 10:38:16 +0000 (12:38 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 21 Oct 2021 11:01:49 +0000 (13:01 +0200)
* keep wanted values in struct wd_control
* make set_watchdog() more readable

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

index 220229a27ee87482bfe39f6ce607476c786fd164..809a47bd2f5f69c7f174d9e9480433adc6b7c518 100644 (file)
@@ -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;