1
2
3
4
5
6#include <errno.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <unistd.h>
11#include <fcntl.h>
12#include <signal.h>
13#include <getopt.h>
14#include <sys/ioctl.h>
15#include <linux/types.h>
16#include <linux/watchdog.h>
17
18#define DEFAULT_PING_RATE 1
19
20int fd;
21const char v = 'V';
22static const char sopts[] = "bdehp:t:Tn:NL";
23static const struct option lopts[] = {
24 {"bootstatus", no_argument, NULL, 'b'},
25 {"disable", no_argument, NULL, 'd'},
26 {"enable", no_argument, NULL, 'e'},
27 {"help", no_argument, NULL, 'h'},
28 {"pingrate", required_argument, NULL, 'p'},
29 {"timeout", required_argument, NULL, 't'},
30 {"gettimeout", no_argument, NULL, 'T'},
31 {"pretimeout", required_argument, NULL, 'n'},
32 {"getpretimeout", no_argument, NULL, 'N'},
33 {"gettimeleft", no_argument, NULL, 'L'},
34 {NULL, no_argument, NULL, 0x0}
35};
36
37
38
39
40
41
42static void keep_alive(void)
43{
44 int dummy;
45 int ret;
46
47 ret = ioctl(fd, WDIOC_KEEPALIVE, &dummy);
48 if (!ret)
49 printf(".");
50}
51
52
53
54
55
56
57static void term(int sig)
58{
59 int ret = write(fd, &v, 1);
60
61 close(fd);
62 if (ret < 0)
63 printf("\nStopping watchdog ticks failed (%d)...\n", errno);
64 else
65 printf("\nStopping watchdog ticks...\n");
66 exit(0);
67}
68
69static void usage(char *progname)
70{
71 printf("Usage: %s [options]\n", progname);
72 printf(" -b, --bootstatus Get last boot status (Watchdog/POR)\n");
73 printf(" -d, --disable Turn off the watchdog timer\n");
74 printf(" -e, --enable Turn on the watchdog timer\n");
75 printf(" -h, --help Print the help message\n");
76 printf(" -p, --pingrate=P Set ping rate to P seconds (default %d)\n", DEFAULT_PING_RATE);
77 printf(" -t, --timeout=T Set timeout to T seconds\n");
78 printf(" -T, --gettimeout Get the timeout\n");
79 printf(" -n, --pretimeout=T Set the pretimeout to T seconds\n");
80 printf(" -N, --getpretimeout Get the pretimeout\n");
81 printf(" -L, --gettimeleft Get the time left until timer expires\n");
82 printf("\n");
83 printf("Parameters are parsed left-to-right in real-time.\n");
84 printf("Example: %s -d -t 10 -p 5 -e\n", progname);
85 printf("Example: %s -t 12 -T -n 7 -N\n", progname);
86}
87
88int main(int argc, char *argv[])
89{
90 int flags;
91 unsigned int ping_rate = DEFAULT_PING_RATE;
92 int ret;
93 int c;
94 int oneshot = 0;
95
96 setbuf(stdout, NULL);
97
98 fd = open("/dev/watchdog", O_WRONLY);
99
100 if (fd == -1) {
101 if (errno == ENOENT)
102 printf("Watchdog device not enabled.\n");
103 else if (errno == EACCES)
104 printf("Run watchdog as root.\n");
105 else
106 printf("Watchdog device open failed %s\n",
107 strerror(errno));
108 exit(-1);
109 }
110
111 while ((c = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
112 switch (c) {
113 case 'b':
114 flags = 0;
115 oneshot = 1;
116 ret = ioctl(fd, WDIOC_GETBOOTSTATUS, &flags);
117 if (!ret)
118 printf("Last boot is caused by: %s.\n", (flags != 0) ?
119 "Watchdog" : "Power-On-Reset");
120 else
121 printf("WDIOC_GETBOOTSTATUS error '%s'\n", strerror(errno));
122 break;
123 case 'd':
124 flags = WDIOS_DISABLECARD;
125 ret = ioctl(fd, WDIOC_SETOPTIONS, &flags);
126 if (!ret)
127 printf("Watchdog card disabled.\n");
128 else {
129 printf("WDIOS_DISABLECARD error '%s'\n", strerror(errno));
130 oneshot = 1;
131 }
132 break;
133 case 'e':
134 flags = WDIOS_ENABLECARD;
135 ret = ioctl(fd, WDIOC_SETOPTIONS, &flags);
136 if (!ret)
137 printf("Watchdog card enabled.\n");
138 else {
139 printf("WDIOS_ENABLECARD error '%s'\n", strerror(errno));
140 oneshot = 1;
141 }
142 break;
143 case 'p':
144 ping_rate = strtoul(optarg, NULL, 0);
145 if (!ping_rate)
146 ping_rate = DEFAULT_PING_RATE;
147 printf("Watchdog ping rate set to %u seconds.\n", ping_rate);
148 break;
149 case 't':
150 flags = strtoul(optarg, NULL, 0);
151 ret = ioctl(fd, WDIOC_SETTIMEOUT, &flags);
152 if (!ret)
153 printf("Watchdog timeout set to %u seconds.\n", flags);
154 else {
155 printf("WDIOC_SETTIMEOUT error '%s'\n", strerror(errno));
156 oneshot = 1;
157 }
158 break;
159 case 'T':
160 oneshot = 1;
161 ret = ioctl(fd, WDIOC_GETTIMEOUT, &flags);
162 if (!ret)
163 printf("WDIOC_GETTIMEOUT returns %u seconds.\n", flags);
164 else
165 printf("WDIOC_GETTIMEOUT error '%s'\n", strerror(errno));
166 break;
167 case 'n':
168 flags = strtoul(optarg, NULL, 0);
169 ret = ioctl(fd, WDIOC_SETPRETIMEOUT, &flags);
170 if (!ret)
171 printf("Watchdog pretimeout set to %u seconds.\n", flags);
172 else {
173 printf("WDIOC_SETPRETIMEOUT error '%s'\n", strerror(errno));
174 oneshot = 1;
175 }
176 break;
177 case 'N':
178 oneshot = 1;
179 ret = ioctl(fd, WDIOC_GETPRETIMEOUT, &flags);
180 if (!ret)
181 printf("WDIOC_GETPRETIMEOUT returns %u seconds.\n", flags);
182 else
183 printf("WDIOC_GETPRETIMEOUT error '%s'\n", strerror(errno));
184 break;
185 case 'L':
186 oneshot = 1;
187 ret = ioctl(fd, WDIOC_GETTIMELEFT, &flags);
188 if (!ret)
189 printf("WDIOC_GETTIMELEFT returns %u seconds.\n", flags);
190 else
191 printf("WDIOC_GETTIMELEFT error '%s'\n", strerror(errno));
192 break;
193
194 default:
195 usage(argv[0]);
196 goto end;
197 }
198 }
199
200 if (oneshot)
201 goto end;
202
203 printf("Watchdog Ticking Away!\n");
204
205 signal(SIGINT, term);
206
207 while (1) {
208 keep_alive();
209 sleep(ping_rate);
210 }
211end:
212 ret = write(fd, &v, 1);
213 if (ret < 0)
214 printf("Stopping watchdog ticks failed (%d)...\n", errno);
215 close(fd);
216 return 0;
217}
218