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 volatile sig_atomic_t quit
= 0;
39 int main(int, char *[]);
44 fprintf(stderr
, "usage: %s [-dnq] [-i interval] [-p period]\n",
51 sighdlr(__unused
int signum
)
57 main(int argc
, char *argv
[])
62 u_int interval
= 0, period
= 30, nperiod
;
63 int fd
, ch
, trigauto
, sauto
, speriod
;
64 int quiet
= 0, daemonize
= 1, retval
= 1, do_restore
= 1;
66 while ((ch
= getopt(argc
, argv
, "di:np:q")) != -1) {
72 interval
= (u_int
)strtonum(optarg
, 1LL, 86400LL,
75 errx(1, "interval is %s: %s", errstr
, optarg
);
81 period
= (u_int
)strtonum(optarg
, 2LL, 86400LL, &errstr
);
83 errx(1, "period is %s: %s", errstr
, optarg
);
98 if (interval
== 0 && (interval
= period
/ 3) == 0)
101 if (period
<= interval
)
102 errx(1, "retrigger interval too long");
104 /* save kern.watchdog.period and kern.watchdog.auto for restore */
106 len
= sizeof(speriod
);
107 if (sysctlbyname("kern.watchdog.period", &speriod
, &len
, &period
, sizeof(period
)) == -1) {
108 if (errno
== EOPNOTSUPP
)
109 errx(1, "no watchdog timer available");
111 err(1, "can't access kern.watchdog.period");
117 if (sysctlbyname("kern.watchdog.auto", &sauto
, &len
, &trigauto
, sizeof(trigauto
)) == -1)
118 err(1, "can't access kern.watchdog.auto");
120 /* Double check the timeout period, some devices change the value */
121 len
= sizeof(nperiod
);
122 if (sysctlbyname("kern.watchdog.period", &nperiod
, &len
, NULL
, 0) == -1) {
123 warnx("can't read back kern.watchdog.period, "
124 "restoring original values");
128 if (nperiod
!= period
&& !quiet
)
129 warnx("period adjusted to %d by device", nperiod
);
131 if (nperiod
<= interval
) {
132 warnx("retrigger interval %d too long, "
133 "restoring original values", interval
);
137 if ((fd
= open("/dev/wdog", O_RDWR
)) == -1) {
138 err(1, "can't open /dev/wdog");
141 if (daemonize
&& daemon(0, 0)) {
142 warn("can't daemonize, restoring original values");
147 * mlockall() below will wire the whole stack up to the limit
148 * thus we have to reduce stack size to avoid resource abuse
150 rlim
.rlim_cur
= 256 * 1024;
151 rlim
.rlim_max
= 256 * 1024;
152 (void)setrlimit(RLIMIT_STACK
, &rlim
);
154 setpriority(PRIO_PROCESS
, getpid(), -5);
156 signal(SIGTERM
, sighdlr
);
160 if (ioctl(fd
, WDIOCRESET
, &period
, sizeof(period
)) == -1)
168 restore
: sysctlbyname("kern.watchdog.period", NULL
, 0, &speriod
, sizeof(speriod
));
169 sysctlbyname("kern.watchdog.auto", NULL
, 0, &sauto
, sizeof(sauto
));