1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: t -*-*/
4 * wdctl(8) - show hardware watchdog status
6 * Copyright (C) 2012 Lennart Poettering
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include <linux/watchdog.h>
24 #include <sys/ioctl.h>
31 #include "closestream.h"
32 #include "pathnames.h"
38 { WDIOF_OVERHEAT
, N_("OVERHEAT: Reset due to CPU overheat") },
39 { WDIOF_FANFAULT
, N_("FANFAULT: Fan failed") },
40 { WDIOF_EXTERN1
, N_("EXTERN1: External relay 1") },
41 { WDIOF_EXTERN2
, N_("EXTERN2: External relay 2") },
42 { WDIOF_POWERUNDER
, N_("POWERUNDER: Power bad/power fault") },
43 { WDIOF_CARDRESET
, N_("CARDRESET: Card previously reset the CPU") },
44 { WDIOF_POWEROVER
, N_("POWEROVER: Power over voltage") },
45 { WDIOF_SETTIMEOUT
, N_("SETTIMEOUT: Set timeout (in seconds)") },
46 { WDIOF_MAGICCLOSE
, N_("MAGICCLOSE: Supports magic close char") },
47 { WDIOF_PRETIMEOUT
, N_("PRETIMEOUT: Pretimeout (in seconds)") },
48 { WDIOF_KEEPALIVEPING
, N_("KEEPALIVEPING: Keep alive ping reply") }
51 static void usage(int status
)
53 FILE *out
= status
== EXIT_SUCCESS
? stdout
: stderr
;
55 fputs(USAGE_HEADER
, out
);
57 _(" %s [options]\n"), program_invocation_short_name
);
59 fputs(USAGE_OPTIONS
, out
);
61 _(" -d, --device <path> device to use (default is %s)\n"), _PATH_WATCHDOG_DEV
);
63 fputs(USAGE_SEPARATOR
, out
);
64 fputs(USAGE_HELP
, out
);
65 fputs(USAGE_VERSION
, out
);
66 fprintf(out
, USAGE_MAN_TAIL("wdctl(1)"));
71 static void print_options(uint32_t options
)
76 puts(_("\tNo flags set."));
80 for (i
= 0; i
< ARRAY_SIZE(flag_names
); i
++) {
81 if (options
& flag_names
[i
].flag
)
82 printf("\t%s\n", _(flag_names
[i
].name
));
83 options
&= ~flag_names
[i
].flag
;
87 printf(_("\tUnknown flags 0x%x\n"), options
);
90 int main(int argc
, char *argv
[])
92 static const struct option longopts
[] = {
93 { "help", no_argument
, 0, 'h' },
94 { "version", no_argument
, 0, 'V'},
95 { "device", required_argument
, 0, 'd' },
99 int c
, status
, sec
, fd
;
100 const char *device
= _PATH_WATCHDOG_DEV
;
101 struct watchdog_info ident
;
103 setlocale(LC_MESSAGES
, "");
104 bindtextdomain(PACKAGE
, LOCALEDIR
);
106 atexit(close_stdout
);
108 while((c
= getopt_long(argc
, argv
, "hVd:", longopts
, NULL
)) != -1) {
114 printf(UTIL_LINUX_VERSION
);
127 fd
= open(device
, O_WRONLY
|O_CLOEXEC
);
130 errx(EXIT_FAILURE
, _("Watchdog already in use, terminating."));
132 err(EXIT_FAILURE
, _("Failed to open watchdog device"));
135 if (ioctl(fd
, WDIOC_GETSUPPORT
, &ident
) >= 0) {
136 printf(_("Identity:\n\t%s\n"
137 "Firmware version:\n\t%x\n"
138 "Supported options:\n"),
140 ident
.firmware_version
);
141 print_options(ident
.options
);
144 if (ioctl(fd
, WDIOC_GETSTATUS
, &status
) >= 0) {
146 print_options((uint32_t) status
);
149 if (ioctl(fd
, WDIOC_GETBOOTSTATUS
, &status
) >= 0) {
150 puts(_("Boot status:"));
151 print_options((uint32_t) status
);
154 if (ioctl(fd
, WDIOC_GETTIMEOUT
, &sec
) >= 0)
155 printf(_("Timeout:\n\t%is\n"), sec
);
157 if (ioctl(fd
, WDIOC_GETPRETIMEOUT
, &sec
) >= 0)
158 printf(_("Pre-Timeout:\n\t%is\n"), sec
);
160 if (ioctl(fd
, WDIOC_GETTIMELEFT
, &sec
) >= 0)
161 printf(_("Time Left:\n\t%is\n"), sec
);
164 /* We just opened this to query the state, not to arm
165 * it hence use the magic close character */
167 static const char v
= 'V';
169 if (write(fd
, &v
, 1) >= 0)
172 if (errno
!= EINTR
) {
173 warn(_("Failed to disarm watchdog"));
177 /* Let's try hard, since if we don't get this right
178 * the machine might end up rebooting. */