]> git.proxmox.com Git - mirror_ovs.git/blob - utilities/ovs-wdt.c
Update primary code license to Apache 2.0.
[mirror_ovs.git] / utilities / ovs-wdt.c
1 /* Copyright (c) 2008, 2009 Nicira Networks, Inc.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <unistd.h>
20 #include <fcntl.h>
21 #include <errno.h>
22 #include <getopt.h>
23 #include <signal.h>
24 #include <sys/ioctl.h>
25 #include <linux/types.h>
26 #include <linux/watchdog.h>
27
28
29 /* Default values for the interval and timer. In seconds. */
30 #define DEFAULT_INTERVAL 1
31 #define DEFAULT_TIMEOUT 30
32
33 int fd = -1;
34
35 /* The WDT is automatically enabled when /dev/watchdog is opened. If we
36 * do not send the magic value to the device first before exiting, the
37 * system will reboot. This function allows the program to exit without
38 * causing a reboot.
39 */
40 static void
41 cleanup(void)
42 {
43 if (fd == -1) {
44 return;
45 }
46
47 /* Writing the magic value "V" to the device is an indication that
48 * the device is about to be closed. This causes the watchdog to be
49 * disabled after the call to close.
50 */
51 if (write(fd, "V", 1) != 1) {
52 fprintf(stderr, "Couldn't write magic val: %d\n", errno);
53 return;
54 }
55 close(fd);
56 fd = -1;
57 }
58
59
60 /* If we receive a SIGINT, cleanup first, which will disable the
61 * watchdog timer.
62 */
63 static void
64 sighandler(int signum)
65 {
66 cleanup();
67 signal(signum, SIG_DFL);
68 raise(signum);
69 }
70
71 static void
72 setup_signal(void)
73 {
74 struct sigaction action;
75
76 action.sa_handler = sighandler;
77 sigemptyset(&action.sa_mask);
78 action.sa_flags = 0;
79
80 if (sigaction(SIGINT, &action, NULL) != 0) {
81 fprintf(stderr, "Problem setting up SIGINT handler...\n");
82 }
83 if (sigaction(SIGTERM, &action, NULL) != 0) {
84 fprintf(stderr, "Problem setting up SIGTERM handler...\n");
85 }
86 }
87
88
89 /* Print information on the WDT hardware */
90 static void
91 print_wdt_info(void)
92 {
93 struct watchdog_info ident;
94
95 if (ioctl(fd, WDIOC_GETSUPPORT, &ident) == -1) {
96 fprintf(stderr, "Couldn't get version: %d\n", errno);
97 cleanup();
98 exit(-1);
99 }
100 printf("identity: %s, ver: %d, opt: %#x\n", ident.identity,
101 ident.firmware_version, ident.options);
102 }
103
104
105 static void
106 print_help(char *progname)
107 {
108 printf("%s: Watchdog timer utility\n", progname);
109 printf("usage: %s [OPTIONS]\n\n", progname);
110 printf("Options:\n");
111 printf(" -t, --timeout=SECS expiration time of WDT (default: %d)\n",
112 DEFAULT_TIMEOUT);
113 printf(" -i, --interval=SECS interval to send keep-alives (default: %d)\n",
114 DEFAULT_INTERVAL);
115 printf(" -d, --disable disable the WDT and exit\n");
116 printf(" -h, --help display this help message\n");
117 printf(" -v, --verbose enable verbose printing\n");
118 printf(" -V, --version display version information of WDT and exit\n");
119 }
120
121
122 int main(int argc, char *argv[])
123 {
124 int arg;
125 int optc;
126 int verbose = 0;
127 int interval = DEFAULT_INTERVAL;
128 int timeout = DEFAULT_TIMEOUT;
129 static struct option const longopts[] =
130 {
131 {"timeout", required_argument, NULL, 't'},
132 {"interval", required_argument, NULL, 'i'},
133 {"disable", no_argument, NULL, 'd'},
134 {"help", no_argument, NULL, 'h'},
135 {"verbose", no_argument, NULL, 'v'},
136 {"version", no_argument, NULL, 'V'},
137 {0, 0, 0, 0}
138 };
139
140 setup_signal();
141
142 fd = open("/dev/watchdog", O_RDWR);
143 if (fd == -1) {
144 fprintf(stderr, "Couldn't open watchdog device: %s\n", strerror(errno));
145 exit(-1);
146 }
147
148 while ((optc = getopt_long(argc, argv, "t:i:dh?vV", longopts, NULL)) != -1) {
149 switch (optc) {
150 case 't':
151 timeout = strtol(optarg, NULL, 10);
152 if (!timeout) {
153 fprintf(stderr, "Invalid timeout: %s\n", optarg);
154 goto error;
155 }
156 break;
157
158 case 'i':
159 interval = strtol(optarg, NULL, 10);
160 if (!interval) {
161 fprintf(stderr, "Invalid interval: %s\n", optarg);
162 goto error;
163 }
164 break;
165
166 case 'd':
167 arg = WDIOS_DISABLECARD;
168 if (ioctl(fd, WDIOC_SETOPTIONS, &arg) == -1) {
169 fprintf(stderr, "Couldn't disable: %d\n", errno);
170 goto error;
171 }
172 cleanup();
173 exit(0);
174 break;
175
176 case 'h':
177 print_help(argv[0]);
178 cleanup();
179 exit(0);
180 break;
181
182 case 'v':
183 verbose = 1;
184 break;
185
186 case 'V':
187 print_wdt_info();
188 cleanup();
189 exit(0);
190 break;
191
192 default:
193 print_help(argv[0]);
194 goto error;
195 break;
196 }
197 }
198
199 argc -= optind;
200 argv += optind;
201
202 /* Sanity-check the arguments */
203 if (argc != 0) {
204 fprintf(stderr, "Illegal argument: %s\n", argv[0]);
205 goto error;
206 }
207
208 if (verbose) {
209 print_wdt_info();
210 printf("timeout: %d, interval: %d\n", timeout, interval);
211 }
212
213 /* Prevent the interval being greater than the timeout, since it
214 * will always cause a reboot.
215 */
216 if (interval > timeout) {
217 fprintf(stderr, "Interval greater than timeout: %d > %d\n",
218 interval, timeout);
219 goto error;
220 }
221
222 /* Always set the timeout */
223 if (ioctl(fd, WDIOC_SETTIMEOUT, &timeout) == -1) {
224 fprintf(stderr, "Couldn't set timeout: %d\n", errno);
225 goto error;
226 }
227
228 /* Loop and send a keep-alive every "interval" seconds */
229 while (1) {
230 if (verbose) {
231 if (ioctl(fd, WDIOC_GETTIMELEFT, &arg) == -1) {
232 fprintf(stderr, "Couldn't get time left: %d\n", errno);
233 goto error;
234 }
235 printf("Sending keep alive, time remaining: %d\n", arg);
236 }
237
238 /* Send a keep-alive. The argument is ignored */
239 if (ioctl(fd, WDIOC_KEEPALIVE, &arg) == -1) {
240 fprintf(stderr, "Couldn't keepalive: %d\n", errno);
241 goto error;
242 }
243
244 sleep(interval);
245 }
246
247 /* Never directly reached... */
248 error:
249 cleanup();
250 exit(-1);
251 }