diff options
Diffstat (limited to 'sys-utils/wdctl.c')
-rw-r--r-- | sys-utils/wdctl.c | 70 |
1 files changed, 49 insertions, 21 deletions
diff --git a/sys-utils/wdctl.c b/sys-utils/wdctl.c index 2a656b8..8611924 100644 --- a/sys-utils/wdctl.c +++ b/sys-utils/wdctl.c @@ -87,16 +87,16 @@ static const struct wdflag wdflags[] = { /* column names */ struct colinfo { - const char *name; /* header */ - double whint; /* width hint (N < 1 is in percent of termwidth) */ - int flags; /* SCOLS_FL_* */ - const char *help; + const char * const name; /* header */ + double whint; /* width hint (N < 1 is in percent of termwidth) */ + int flags; /* SCOLS_FL_* */ + const char *help; }; enum { COL_FLAG, COL_DESC, COL_STATUS, COL_BSTATUS, COL_DEVICE }; /* columns descriptions */ -static struct colinfo infos[] = { +static const struct colinfo infos[] = { [COL_FLAG] = { "FLAG", 14, 0, N_("flag name") }, [COL_DESC] = { "DESCRIPTION", 0.1, SCOLS_FL_TRUNC, N_("flag description") }, [COL_STATUS] = { "STATUS", 1, SCOLS_FL_RIGHT, N_("flag status") }, @@ -125,7 +125,12 @@ struct wd_device { struct watchdog_info ident; - unsigned int has_timeout : 1, + unsigned int has_identity : 1, + has_fw_version : 1, + has_options : 1, + has_status : 1, + has_bootstatus : 1, + has_timeout : 1, has_timeleft : 1, has_pretimeout : 1, has_nowayout : 1, @@ -188,7 +193,7 @@ static int get_column_id(int num) return columns[num]; } -static struct colinfo *get_column_info(unsigned num) +static const struct colinfo *get_column_info(unsigned num) { return &infos[ get_column_id(num) ]; } @@ -242,7 +247,7 @@ static void __attribute__((__noreturn__)) usage(void) " -x, --flags-only print only flags table (same as -I -T)\n"), out); fputs(USAGE_SEPARATOR, out); - printf(USAGE_HELP_OPTIONS(24)); + fprintf(out, USAGE_HELP_OPTIONS(24)); fputs(USAGE_SEPARATOR, out); if (dflt) @@ -254,7 +259,7 @@ static void __attribute__((__noreturn__)) usage(void) for (i = 0; i < ARRAY_SIZE(infos); i++) fprintf(out, " %13s %s\n", infos[i].name, _(infos[i].help)); - printf(USAGE_MAN_TAIL("wdctl(8)")); + fprintf(out, USAGE_MAN_TAIL("wdctl(8)")); exit(EXIT_SUCCESS); } @@ -354,7 +359,7 @@ static int show_flags(struct wd_control *ctl, struct wd_device *wd, uint32_t wan /* define columns */ for (i = 0; i < (size_t) ncolumns; i++) { - struct colinfo *col = get_column_info(i); + const struct colinfo *col = get_column_info(i); if (!scols_table_new_column(table, col->name, col->whint, col->flags)) { warnx(_("failed to allocate output column")); @@ -401,7 +406,7 @@ static int set_watchdog(struct wd_control *ctl, struct wd_device *wd) assert(wd->devpath); assert(ctl); - if (!ctl->set_timeout && !ctl->set_timeout) + if (!ctl->set_timeout && !ctl->set_pretimeout) goto sysfs_only; sigemptyset(&oldsigs); @@ -549,13 +554,16 @@ static int read_watchdog_from_sysfs(struct wd_device *wd) if (!sys) return 1; - ul_path_read_buffer(sys, (char *) wd->ident.identity, sizeof(wd->ident.identity), "identity"); - ul_path_read_u32(sys, &wd->ident.firmware_version, "fw_version"); - ul_path_scanf(sys, "options", "%x", &wd->ident.options); - - ul_path_scanf(sys, "status", "%x", &wd->status); - ul_path_read_u32(sys, &wd->bstatus, "bootstatus"); - + if (ul_path_read_buffer(sys, (char *) wd->ident.identity, sizeof(wd->ident.identity), "identity") >= 0) + wd->has_identity = 1; + if (ul_path_read_u32(sys, &wd->ident.firmware_version, "fw_version") == 0) + wd->has_fw_version = 1; + if (ul_path_scanf(sys, "options", "%x", &wd->ident.options) == 1) + wd->has_options = 1; + if (ul_path_scanf(sys, "status", "%x", &wd->status) == 1) + wd->has_status = 1; + if (ul_path_read_u32(sys, &wd->bstatus, "bootstatus") == 0) + wd->has_bootstatus = 1; if (ul_path_read_s32(sys, &wd->nowayout, "nowayout") == 0) wd->has_nowayout = 1; if (ul_path_read_s32(sys, &wd->timeout, "timeout") == 0) @@ -598,12 +606,32 @@ static int read_governors(struct wd_device *wd) return 0; } +static bool should_read_from_device(struct wd_device *wd) +{ + if (!wd->has_nowayout) + return false; + + if (wd->nowayout) + return false; + + return !wd->has_identity || + !wd->has_fw_version || + !wd->has_options || + !wd->has_status || + !wd->has_bootstatus || + !wd->has_timeout || + !wd->has_timeleft; + // pretimeout attribute may be hidden in sysfs +} + static int read_watchdog(struct wd_device *wd) { - int rc = read_watchdog_from_device(wd); + int rc; + + rc = read_watchdog_from_sysfs(wd); - if (rc == -EBUSY || rc == -EACCES || rc == -EPERM) - rc = read_watchdog_from_sysfs(wd); + if (rc && should_read_from_device(wd)) + rc = read_watchdog_from_device(wd); if (rc) { warn(_("cannot read information about %s"), wd->devpath); |