1 /* $OpenBSD: sthen $ */
4 * Copyright (c) 2005 Marc Balmer <mbalmer@openbsd.org>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/param.h>
20 #include <sys/ioctl.h>
22 #include <sys/resource.h>
23 #include <sys/sysctl.h>
25 #include <sys/types.h>
35 static volatile sig_atomic_t quit
= 0;
37 static void usage(void) __dead2
;
38 static void sighdlr(int);
43 fprintf(stderr
, "usage: %s [-dnq] [-i interval] [-p period]\n",
50 sighdlr(__unused
int signum
)
56 main(int argc
, char *argv
[])
61 u_int interval
= 0, period
= 30, nperiod
;
62 int fd
, ch
, trigauto
, sauto
, speriod
;
63 int quiet
= 0, daemonize
= 1, retval
= 1, do_restore
= 1;
65 while ((ch
= getopt(argc
, argv
, "di:np:q")) != -1) {
71 interval
= (u_int
)strtonum(optarg
, 1LL, 86400LL,
74 errx(1, "interval is %s: %s", errstr
, optarg
);
80 period
= (u_int
)strtonum(optarg
, 2LL, 86400LL, &errstr
);
82 errx(1, "period is %s: %s", errstr
, optarg
);
97 if (interval
== 0 && (interval
= period
/ 3) == 0)
100 if (period
<= interval
)
101 errx(1, "retrigger interval too long");
103 /* save kern.watchdog.period and kern.watchdog.auto for restore */
105 len
= sizeof(speriod
);
106 if (sysctlbyname("kern.watchdog.period", &speriod
, &len
, &period
, sizeof(period
)) == -1) {
107 if (errno
== EOPNOTSUPP
)
108 errx(1, "no watchdog timer available");
110 err(1, "can't access kern.watchdog.period");
116 if (sysctlbyname("kern.watchdog.auto", &sauto
, &len
, &trigauto
, sizeof(trigauto
)) == -1)
117 err(1, "can't access kern.watchdog.auto");
119 /* Double check the timeout period, some devices change the value */
120 len
= sizeof(nperiod
);
121 if (sysctlbyname("kern.watchdog.period", &nperiod
, &len
, NULL
, 0) == -1) {
122 warnx("can't read back kern.watchdog.period, "
123 "restoring original values");
127 if (nperiod
!= period
&& !quiet
)
128 warnx("period adjusted to %d by device", nperiod
);
130 if (nperiod
<= interval
) {
131 warnx("retrigger interval %d too long, "
132 "restoring original values", interval
);
136 if ((fd
= open("/dev/wdog", O_RDWR
)) == -1) {
137 err(1, "can't open /dev/wdog");
140 if (daemonize
&& daemon(0, 0)) {
141 warn("can't daemonize, restoring original values");
146 * mlockall() below will wire the whole stack up to the limit
147 * thus we have to reduce stack size to avoid resource abuse
149 rlim
.rlim_cur
= 256 * 1024;
150 rlim
.rlim_max
= 256 * 1024;
151 (void)setrlimit(RLIMIT_STACK
, &rlim
);
153 setpriority(PRIO_PROCESS
, getpid(), -5);
155 signal(SIGTERM
, sighdlr
);
159 if (ioctl(fd
, WDIOCRESET
, &period
, sizeof(period
)) == -1)
167 restore
: sysctlbyname("kern.watchdog.period", NULL
, 0, &speriod
, sizeof(speriod
));
168 sysctlbyname("kern.watchdog.auto", NULL
, 0, &sauto
, sizeof(sauto
));