From e4d511d40c492928b36286b2d64927ffa9382680 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 31 May 2019 14:06:04 +0200 Subject: wdctl: rename watch dog info struct Signed-off-by: Karel Zak --- sys-utils/wdctl.c | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/sys-utils/wdctl.c b/sys-utils/wdctl.c index 4574e10da..00f4bd774 100644 --- a/sys-utils/wdctl.c +++ b/sys-utils/wdctl.c @@ -108,8 +108,8 @@ static struct colinfo infos[] = { static int columns[ARRAY_SIZE(infos) * 2]; static int ncolumns; -struct wdinfo { - char *device; +struct wd_device { + char *devpath; int timeout; int timeleft; @@ -204,7 +204,7 @@ static void __attribute__((__noreturn__)) usage(void) exit(EXIT_SUCCESS); } -static void add_flag_line(struct libscols_table *table, struct wdinfo *wd, const struct wdflag *fl) +static void add_flag_line(struct libscols_table *table, struct wd_device *wd, const struct wdflag *fl) { int i; struct libscols_line *line; @@ -232,7 +232,7 @@ static void add_flag_line(struct libscols_table *table, struct wdinfo *wd, const str = wd->bstatus & fl->flag ? "1" : "0"; break; case COL_DEVICE: - str = wd->device; + str = wd->devpath; break; default: break; @@ -245,7 +245,7 @@ static void add_flag_line(struct libscols_table *table, struct wdinfo *wd, const } } -static int show_flags(struct wdinfo *wd, uint32_t wanted) +static int show_flags(struct wd_device *wd, uint32_t wanted) { size_t i; int rc = -1; @@ -287,7 +287,7 @@ static int show_flags(struct wdinfo *wd, uint32_t wanted) } if (flags) - warnx(_("%s: unknown flags 0x%x\n"), wd->device, flags); + warnx(_("%s: unknown flags 0x%x\n"), wd->devpath, flags); scols_print_table(table); rc = 0; @@ -301,25 +301,25 @@ done: * * Don't use err() or exit() here! */ -static int set_watchdog(struct wdinfo *wd, int timeout) +static int set_watchdog(struct wd_device *wd, int timeout) { int fd; sigset_t sigs, oldsigs; int rc = 0; - assert(wd->device); + assert(wd->devpath); sigemptyset(&oldsigs); sigfillset(&sigs); sigprocmask(SIG_BLOCK, &sigs, &oldsigs); - fd = open(wd->device, O_WRONLY|O_CLOEXEC); + fd = open(wd->devpath, 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); + wd->devpath); + warn(_("cannot open %s"), wd->devpath); return -1; } @@ -331,7 +331,7 @@ static int set_watchdog(struct wdinfo *wd, int timeout) if (write(fd, &v, 1) >= 0) break; if (errno != EINTR) { - warn(_("%s: failed to disarm watchdog"), wd->device); + warn(_("%s: failed to disarm watchdog"), wd->devpath); break; } /* Let's try hard, since if we don't get this right @@ -340,7 +340,7 @@ static int set_watchdog(struct wdinfo *wd, int timeout) if (ioctl(fd, WDIOC_SETTIMEOUT, &timeout) != 0) { rc = errno; - warn(_("cannot set timeout for %s"), wd->device); + warn(_("cannot set timeout for %s"), wd->devpath); } if (close(fd)) @@ -358,29 +358,29 @@ static int set_watchdog(struct wdinfo *wd, int timeout) * * Don't use err() or exit() here! */ -static int read_watchdog(struct wdinfo *wd) +static int read_watchdog(struct wd_device *wd) { int fd; sigset_t sigs, oldsigs; - assert(wd->device); + assert(wd->devpath); sigemptyset(&oldsigs); sigfillset(&sigs); sigprocmask(SIG_BLOCK, &sigs, &oldsigs); - fd = open(wd->device, O_WRONLY|O_CLOEXEC); + fd = open(wd->devpath, 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); + wd->devpath); + warn(_("cannot open %s"), wd->devpath); return -1; } if (ioctl(fd, WDIOC_GETSUPPORT, &wd->ident) < 0) - warn(_("%s: failed to get information about watchdog"), wd->device); + warn(_("%s: failed to get information about watchdog"), wd->devpath); else { ioctl(fd, WDIOC_GETSTATUS, &wd->status); ioctl(fd, WDIOC_GETBOOTSTATUS, &wd->bstatus); @@ -401,7 +401,7 @@ static int read_watchdog(struct wdinfo *wd) if (write(fd, &v, 1) >= 0) break; if (errno != EINTR) { - warn(_("%s: failed to disarm watchdog"), wd->device); + warn(_("%s: failed to disarm watchdog"), wd->devpath); break; } /* Let's try hard, since if we don't get this right @@ -415,10 +415,10 @@ static int read_watchdog(struct wdinfo *wd) return 0; } -static void print_oneline(struct wdinfo *wd, uint32_t wanted, +static void print_oneline(struct wd_device *wd, uint32_t wanted, int noident, int notimeouts, int noflags) { - printf("%s:", wd->device); + printf("%s:", wd->devpath); if (!noident) { printf(" VERSION=\"%x\"", wd->ident.firmware_version); @@ -459,7 +459,7 @@ static void print_oneline(struct wdinfo *wd, uint32_t wanted, fputc('\n', stdout); } -static void show_timeouts(struct wdinfo *wd) +static void show_timeouts(struct wd_device *wd) { if (wd->has_timeout) printf(P_("%-14s %2i second\n", "%-14s %2i seconds\n", wd->timeout), @@ -474,7 +474,7 @@ static void show_timeouts(struct wdinfo *wd) int main(int argc, char *argv[]) { - struct wdinfo wd; + struct wd_device wd; int c, res = EXIT_SUCCESS, count = 0; char noflags = 0, noident = 0, notimeouts = 0, oneline = 0; uint32_t wanted = 0; @@ -573,9 +573,9 @@ int main(int argc, char *argv[]) memset(&wd, 0, sizeof(wd)); if (optind == argc) - wd.device = _PATH_WATCHDOG_DEV; + wd.devpath = _PATH_WATCHDOG_DEV; else - wd.device = argv[optind++]; + wd.devpath = argv[optind++]; if (count) fputc('\n', stdout); @@ -601,7 +601,7 @@ int main(int argc, char *argv[]) /* pretty output */ if (!noident) { - printf("%-15s%s\n", _("Device:"), wd.device); + printf("%-15s%s\n", _("Device:"), wd.devpath); printf("%-15s%s [%s %x]\n", _("Identity:"), wd.ident.identity, -- cgit v1.2.3-55-g7522 From a599d1375e80d061dcc6b5fad3f0ffaef55d831d Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 31 May 2019 14:18:19 +0200 Subject: wdctl: add control struct * remove global variables * keep all together Signed-off-by: Karel Zak --- sys-utils/wdctl.c | 58 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/sys-utils/wdctl.c b/sys-utils/wdctl.c index 00f4bd774..6b04acd8b 100644 --- a/sys-utils/wdctl.c +++ b/sys-utils/wdctl.c @@ -59,10 +59,6 @@ other external alarm not a reboot */ #endif -/* basic output flags */ -static int no_headings; -static int raw; - struct wdflag { uint32_t flag; const char *name; @@ -125,6 +121,15 @@ struct wd_device { has_pretimeout : 1; }; +struct wd_control { + unsigned int show_oneline : 1, + show_raw : 1, + hide_headings : 1, + hide_flags : 1, + hide_ident : 1, + hide_timeouts : 1; +}; + /* converts flag name to flag bit */ static long name2bit(const char *name, size_t namesz) { @@ -245,7 +250,7 @@ static void add_flag_line(struct libscols_table *table, struct wd_device *wd, co } } -static int show_flags(struct wd_device *wd, uint32_t wanted) +static int show_flags(struct wd_control *ctl, struct wd_device *wd, uint32_t wanted) { size_t i; int rc = -1; @@ -260,8 +265,8 @@ static int show_flags(struct wd_device *wd, uint32_t wanted) warn(_("failed to allocate output table")); return -1; } - scols_table_enable_raw(table, raw); - scols_table_enable_noheadings(table, no_headings); + scols_table_enable_raw(table, ctl->show_raw); + scols_table_enable_noheadings(table, ctl->hide_headings); /* define columns */ for (i = 0; i < (size_t) ncolumns; i++) { @@ -415,18 +420,17 @@ static int read_watchdog(struct wd_device *wd) return 0; } -static void print_oneline(struct wd_device *wd, uint32_t wanted, - int noident, int notimeouts, int noflags) +static void print_oneline(struct wd_control *ctl, struct wd_device *wd, uint32_t wanted) { printf("%s:", wd->devpath); - if (!noident) { + if (!ctl->hide_ident) { printf(" VERSION=\"%x\"", wd->ident.firmware_version); printf(" IDENTITY="); fputs_quoted((char *) wd->ident.identity, stdout); } - if (!notimeouts) { + if (!ctl->hide_timeouts) { if (wd->has_timeout) printf(" TIMEOUT=\"%i\"", wd->timeout); if (wd->has_pretimeout) @@ -435,7 +439,7 @@ static void print_oneline(struct wd_device *wd, uint32_t wanted, printf(" TIMELEFT=\"%i\"", wd->timeleft); } - if (!noflags) { + if (!ctl->hide_flags) { size_t i; uint32_t flags = wd->ident.options; @@ -475,8 +479,8 @@ static void show_timeouts(struct wd_device *wd) int main(int argc, char *argv[]) { struct wd_device wd; + struct wd_control ctl = { .hide_headings = 0 }; int c, res = EXIT_SUCCESS, count = 0; - char noflags = 0, noident = 0, notimeouts = 0, oneline = 0; uint32_t wanted = 0; int timeout = 0; @@ -528,26 +532,26 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; break; case 'F': - noflags = 1; + ctl.hide_flags = 1; break; case 'I': - noident = 1; + ctl.hide_ident = 1; break; case 'T': - notimeouts = 1; + ctl.hide_timeouts = 1; break; case 'n': - no_headings = 1; + ctl.hide_headings = 1; break; case 'r': - raw = 1; + ctl.show_raw = 1; break; case 'O': - oneline = 1; + ctl.show_oneline = 1; break; case 'x': - noident = 1; - notimeouts = 1; + ctl.hide_ident = 1; + ctl.hide_timeouts = 1; break; case 'h': @@ -594,13 +598,13 @@ int main(int argc, char *argv[]) continue; } - if (oneline) { - print_oneline(&wd, wanted, noident, notimeouts, noflags); + if (ctl.show_oneline) { + print_oneline(&ctl, &wd, wanted); continue; } /* pretty output */ - if (!noident) { + if (!ctl.hide_ident) { printf("%-15s%s\n", _("Device:"), wd.devpath); printf("%-15s%s [%s %x]\n", _("Identity:"), @@ -608,10 +612,10 @@ int main(int argc, char *argv[]) _("version"), wd.ident.firmware_version); } - if (!notimeouts) + if (!ctl.hide_timeouts) show_timeouts(&wd); - if (!noflags) - show_flags(&wd, wanted); + if (!ctl.hide_flags) + show_flags(&ctl, &wd, wanted); } while (optind < argc); return res; -- cgit v1.2.3-55-g7522 From 5d628f37b7423c0047136c81aa7ff3b812fcaed9 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 31 May 2019 14:25:41 +0200 Subject: wdctl: remove printing from main() Signed-off-by: Karel Zak --- sys-utils/wdctl.c | 62 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/sys-utils/wdctl.c b/sys-utils/wdctl.c index 6b04acd8b..b4f2c6b56 100644 --- a/sys-utils/wdctl.c +++ b/sys-utils/wdctl.c @@ -420,6 +420,19 @@ static int read_watchdog(struct wd_device *wd) return 0; } +static void show_timeouts(struct wd_device *wd) +{ + if (wd->has_timeout) + printf(P_("%-14s %2i second\n", "%-14s %2i seconds\n", wd->timeout), + _("Timeout:"), wd->timeout); + if (wd->has_pretimeout) + printf(P_("%-14s %2i second\n", "%-14s %2i seconds\n", wd->pretimeout), + _("Pre-timeout:"), wd->pretimeout); + if (wd->has_timeleft) + printf(P_("%-14s %2i second\n", "%-14s %2i seconds\n", wd->timeleft), + _("Timeleft:"), wd->timeleft); +} + static void print_oneline(struct wd_control *ctl, struct wd_device *wd, uint32_t wanted) { printf("%s:", wd->devpath); @@ -463,17 +476,28 @@ static void print_oneline(struct wd_control *ctl, struct wd_device *wd, uint32_t fputc('\n', stdout); } -static void show_timeouts(struct wd_device *wd) +static void print_device(struct wd_control *ctl, struct wd_device *wd, uint32_t wanted) { - if (wd->has_timeout) - printf(P_("%-14s %2i second\n", "%-14s %2i seconds\n", wd->timeout), - _("Timeout:"), wd->timeout); - if (wd->has_pretimeout) - printf(P_("%-14s %2i second\n", "%-14s %2i seconds\n", wd->pretimeout), - _("Pre-timeout:"), wd->pretimeout); - if (wd->has_timeleft) - printf(P_("%-14s %2i second\n", "%-14s %2i seconds\n", wd->timeleft), - _("Timeleft:"), wd->timeleft); + /* NAME=value one line output */ + if (ctl->show_oneline) { + print_oneline(ctl, wd, wanted); + return; + } + + /* pretty output */ + if (!ctl->hide_ident) { + printf("%-15s%s\n", _("Device:"), wd->devpath); + printf("%-15s%s [%s %x]\n", + _("Identity:"), + wd->ident.identity, + _("version"), + wd->ident.firmware_version); + } + if (!ctl->hide_timeouts) + show_timeouts(wd); + + if (!ctl->hide_flags) + show_flags(ctl, wd, wanted); } int main(int argc, char *argv[]) @@ -598,24 +622,8 @@ int main(int argc, char *argv[]) continue; } - if (ctl.show_oneline) { - print_oneline(&ctl, &wd, wanted); - continue; - } + print_device(&ctl, &wd, wanted); - /* pretty output */ - if (!ctl.hide_ident) { - printf("%-15s%s\n", _("Device:"), wd.devpath); - printf("%-15s%s [%s %x]\n", - _("Identity:"), - wd.ident.identity, - _("version"), - wd.ident.firmware_version); - } - if (!ctl.hide_timeouts) - show_timeouts(&wd); - if (!ctl.hide_flags) - show_flags(&ctl, &wd, wanted); } while (optind < argc); return res; -- cgit v1.2.3-55-g7522 From 8c8df4214656794b82d4eac5dffe36d3cac389e3 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 31 May 2019 14:49:23 +0200 Subject: wdctl: default to /dev/watchdog0 Let's use miscdev /dev/watchdog as fallback only. We need (if possible) cdev /dev/watchdog0 as this device has entry in /sys/class/watchdog. Signed-off-by: Karel Zak --- include/pathnames.h | 3 --- sys-utils/wdctl.c | 43 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/include/pathnames.h b/include/pathnames.h index ee470ee4b..6f091d5f0 100644 --- a/include/pathnames.h +++ b/include/pathnames.h @@ -167,9 +167,6 @@ /* deprecated */ #define _PATH_RAWDEVCTL_OLD "/dev/rawctl" -/* wdctl path */ -#define _PATH_WATCHDOG_DEV "/dev/watchdog" - /* ipc paths */ #define _PATH_PROC_SYSV_MSG "/proc/sysvipc/msg" #define _PATH_PROC_SYSV_SEM "/proc/sysvipc/sem" diff --git a/sys-utils/wdctl.c b/sys-utils/wdctl.c index b4f2c6b56..772e6b968 100644 --- a/sys-utils/wdctl.c +++ b/sys-utils/wdctl.c @@ -105,7 +105,7 @@ static int columns[ARRAY_SIZE(infos) * 2]; static int ncolumns; struct wd_device { - char *devpath; + const char *devpath; int timeout; int timeleft; @@ -170,10 +170,32 @@ static struct colinfo *get_column_info(unsigned num) return &infos[ get_column_id(num) ]; } +/* We preffer cdev /dev/watchdog0 as this device has node in + * /sys/class/watchdog/. The old miscdev /dev/watchdog is fallback for old + * systemds only. + */ +static const char *get_default_device(void) +{ + const char **p; + static const char *devs[] = { + "/dev/watchdog0", + "/dev/watchdog", + NULL + }; + + for (p = devs; *p; p++) { + if (access(*p, F_OK) == 0) + return *p; + } + + return NULL; +} + static void __attribute__((__noreturn__)) usage(void) { FILE *out = stdout; size_t i; + const char *dflt = get_default_device(); fputs(USAGE_HEADER, out); fprintf(out, @@ -198,7 +220,10 @@ static void __attribute__((__noreturn__)) usage(void) printf(USAGE_HELP_OPTIONS(24)); fputs(USAGE_SEPARATOR, out); - fprintf(out, _("The default device is %s.\n"), _PATH_WATCHDOG_DEV); + if (dflt) + fprintf(out, _("The default device is %s.\n"), dflt); + else + fprintf(out, _("No default device is available.\n")); fputs(USAGE_COLUMNS, out); for (i = 0; i < ARRAY_SIZE(infos); i++) @@ -507,6 +532,7 @@ int main(int argc, char *argv[]) int c, res = EXIT_SUCCESS, count = 0; uint32_t wanted = 0; int timeout = 0; + const char *dflt_device = NULL; static const struct option long_opts[] = { { "flags", required_argument, NULL, 'f' }, @@ -595,15 +621,18 @@ int main(int argc, char *argv[]) columns[ncolumns++] = COL_BSTATUS; } + /* Device no specified, use default. */ + if (optind == argc) { + dflt_device = get_default_device(); + if (!dflt_device) + err(EXIT_FAILURE, _("No default device is available.")); + } + do { int rc; memset(&wd, 0, sizeof(wd)); - - if (optind == argc) - wd.devpath = _PATH_WATCHDOG_DEV; - else - wd.devpath = argv[optind++]; + wd.devpath = dflt_device ? dflt_device : argv[optind++]; if (count) fputc('\n', stdout); -- cgit v1.2.3-55-g7522 From e3188dd90a4cd51723fefdcea8c3b82a6e7afc29 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 6 Jun 2019 11:09:17 +0200 Subject: lib/path: make sure ul_path_read_buffer() derminate result Signed-off-by: Karel Zak --- lib/path.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/path.c b/lib/path.c index f7fd19592..8dce1da40 100644 --- a/lib/path.c +++ b/lib/path.c @@ -610,9 +610,10 @@ int ul_path_read_buffer(struct path_cxt *pc, char *buf, size_t bufsz, const char /* Remove tailing newline (usual in sysfs) */ if (rc > 0 && *(buf + rc - 1) == '\n') - --rc; + buf[--rc] = '\0'; + else + buf[rc - 1] = '\0'; - buf[rc] = '\0'; return rc; } -- cgit v1.2.3-55-g7522 From b3dd29d1b878865102c5cb366dd3e814ce043cb9 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 6 Jun 2019 11:17:13 +0200 Subject: wdctl; read from /sys if necessary The device can be inaccessible for non-root user or busy (already used by another process). In this case it seems better to read information from /sys. Note that /sys does not provide struct watchdog_info.options, so we cannot print list of supported watchdog features. Addresses: https://github.com/karelzak/util-linux/issues/804 Signed-off-by: Karel Zak --- include/pathnames.h | 1 + sys-utils/wdctl.8 | 4 +++ sys-utils/wdctl.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 77 insertions(+), 9 deletions(-) diff --git a/include/pathnames.h b/include/pathnames.h index 6f091d5f0..2e1f19355 100644 --- a/include/pathnames.h +++ b/include/pathnames.h @@ -104,6 +104,7 @@ #define _PATH_SYS_BLOCK "/sys/block" #define _PATH_SYS_DEVBLOCK "/sys/dev/block" +#define _PATH_SYS_DEVCHAR "/sys/dev/char" #define _PATH_SYS_CLASS "/sys/class" #define _PATH_SYS_SCSI "/sys/bus/scsi" diff --git a/sys-utils/wdctl.8 b/sys-utils/wdctl.8 index 7edf80866..efd8b5917 100644 --- a/sys-utils/wdctl.8 +++ b/sys-utils/wdctl.8 @@ -14,6 +14,10 @@ Show hardware watchdog status. The default device is If more than one device is specified then the output is separated by one blank line. .PP +If the device is already used or user has no permissions to read from the device than +.B wdctl +reads data from sysfs. In this case information about supported features (flags) might be missing. +.PP Note that the number of supported watchdog features is hardware specific. .SH OPTIONS .TP diff --git a/sys-utils/wdctl.c b/sys-utils/wdctl.c index 772e6b968..0bb245bae 100644 --- a/sys-utils/wdctl.c +++ b/sys-utils/wdctl.c @@ -25,6 +25,9 @@ #include #include #include +#include +#include +#include #include @@ -36,6 +39,7 @@ #include "pathnames.h" #include "strutils.h" #include "carefulputc.h" +#include "path.h" /* * since 2.6.18 @@ -113,12 +117,14 @@ struct wd_device { uint32_t status; uint32_t bstatus; + int nowayout; struct watchdog_info ident; unsigned int has_timeout : 1, has_timeleft : 1, - has_pretimeout : 1; + has_pretimeout : 1, + has_nowayout : 1; }; struct wd_control { @@ -282,6 +288,10 @@ static int show_flags(struct wd_control *ctl, struct wd_device *wd, uint32_t wan struct libscols_table *table; uint32_t flags; + /* information about supported bits is probably missing in /sys */ + if (!wd->ident.options) + return 0; + scols_init_debug(0); /* create output table */ @@ -388,7 +398,7 @@ static int set_watchdog(struct wd_device *wd, int timeout) * * Don't use err() or exit() here! */ -static int read_watchdog(struct wd_device *wd) +static int read_watchdog_from_device(struct wd_device *wd) { int fd; sigset_t sigs, oldsigs; @@ -401,13 +411,8 @@ static int read_watchdog(struct wd_device *wd) fd = open(wd->devpath, O_WRONLY|O_CLOEXEC); - if (fd < 0) { - if (errno == EBUSY) - warnx(_("%s: watchdog already in use, terminating."), - wd->devpath); - warn(_("cannot open %s"), wd->devpath); - return -1; - } + if (fd < 0) + return -errno; if (ioctl(fd, WDIOC_GETSUPPORT, &wd->ident) < 0) warn(_("%s: failed to get information about watchdog"), wd->devpath); @@ -445,6 +450,64 @@ static int read_watchdog(struct wd_device *wd) return 0; } +/* Returns: <0 error, 0 success, 1 unssuported */ +static int read_watchdog_from_sysfs(struct wd_device *wd) +{ + struct path_cxt *sys; + struct stat st; + int rc; + + rc = stat(wd->devpath, &st); + if (rc != 0) + return rc; + + sys = ul_new_path(_PATH_SYS_DEVCHAR "/%u:%u", + major(st.st_rdev), minor(st.st_rdev)); + if (!sys) + return -ENOMEM; + + 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?) */ + + ul_path_read_buffer(sys, (char *) wd->ident.identity, sizeof(wd->ident.identity), "identity"); + + ul_path_scanf(sys, "status", "%x", &wd->status); + ul_path_read_u32(sys, &wd->bstatus, "bootstatus"); + + if (ul_path_read_s32(sys, &wd->nowayout, "nowayout") == 0) + wd->has_nowayout = 1; + if (ul_path_read_s32(sys, &wd->timeout, "timeout") == 0) + wd->has_timeout = 1; + if (ul_path_read_s32(sys, &wd->pretimeout, "pretimeout") == 0) + wd->has_pretimeout = 1; + if (ul_path_read_s32(sys, &wd->timeleft, "timeleft") == 0) + wd->has_timeleft = 1; + + ul_unref_path(sys); + return 0; +nosysfs: + ul_unref_path(sys); + return 1; +} + +static int read_watchdog(struct wd_device *wd) +{ + int rc = read_watchdog_from_device(wd); + + if (rc == -EBUSY || rc == -EACCES || rc == -EPERM) + rc = read_watchdog_from_sysfs(wd); + + if (rc) { + warn(_("cannot read information about %s"), wd->devpath); + return -1; + } + + return 0; +} + static void show_timeouts(struct wd_device *wd) { if (wd->has_timeout) -- cgit v1.2.3-55-g7522