Line data Source code
1 : /* $OpenBSD: kern_watchdog.c,v 1.13 2017/01/09 17:58:44 mpi Exp $ */
2 :
3 : /*
4 : * Copyright (c) 2003 Markus Friedl. All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions
8 : * are met:
9 : * 1. Redistributions of source code must retain the above copyright
10 : * notice, this list of conditions and the following disclaimer.
11 : * 2. Redistributions in binary form must reproduce the above copyright
12 : * notice, this list of conditions and the following disclaimer in the
13 : * documentation and/or other materials provided with the distribution.
14 : *
15 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 : * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 : */
26 : #include <sys/param.h>
27 : #include <sys/kernel.h>
28 : #include <sys/systm.h>
29 : #include <sys/timeout.h>
30 : #include <sys/sysctl.h>
31 : #include <sys/time.h>
32 :
33 : void wdog_tickle(void *arg);
34 : int (*wdog_ctl_cb)(void *, int) = NULL;
35 : void *wdog_ctl_cb_arg = NULL;
36 : int wdog_period = 0;
37 : int wdog_auto = 1;
38 : struct timeout wdog_timeout;
39 :
40 : void
41 0 : wdog_register(int (*cb)(void *, int), void *cb_arg)
42 : {
43 0 : if (wdog_ctl_cb != NULL)
44 : return;
45 :
46 0 : wdog_ctl_cb = cb;
47 0 : wdog_ctl_cb_arg = cb_arg;
48 0 : timeout_set(&wdog_timeout, wdog_tickle, NULL);
49 0 : }
50 :
51 : void
52 0 : wdog_tickle(void *arg)
53 : {
54 0 : if (wdog_ctl_cb == NULL)
55 : return;
56 0 : (void) (*wdog_ctl_cb)(wdog_ctl_cb_arg, wdog_period);
57 0 : timeout_add(&wdog_timeout, wdog_period * hz / 2);
58 0 : }
59 :
60 : void
61 0 : wdog_shutdown(void *arg)
62 : {
63 0 : if (wdog_ctl_cb == NULL || wdog_ctl_cb_arg != arg)
64 : return;
65 0 : timeout_del(&wdog_timeout);
66 0 : (void) (*wdog_ctl_cb)(wdog_ctl_cb_arg, 0);
67 0 : wdog_ctl_cb = NULL;
68 0 : wdog_period = 0;
69 0 : wdog_auto = 1;
70 0 : }
71 :
72 : int
73 0 : sysctl_wdog(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
74 : size_t newlen)
75 : {
76 0 : int error, period;
77 :
78 0 : if (wdog_ctl_cb == NULL)
79 0 : return (EOPNOTSUPP);
80 :
81 0 : switch (name[0]) {
82 : case KERN_WATCHDOG_PERIOD:
83 0 : period = wdog_period;
84 0 : error = sysctl_int(oldp, oldlenp, newp, newlen, &period);
85 0 : if (error)
86 0 : return (error);
87 0 : if (newp) {
88 0 : timeout_del(&wdog_timeout);
89 0 : wdog_period = (*wdog_ctl_cb)(wdog_ctl_cb_arg, period);
90 0 : }
91 : break;
92 : case KERN_WATCHDOG_AUTO:
93 0 : error = sysctl_int(oldp, oldlenp, newp, newlen, &wdog_auto);
94 0 : if (error)
95 0 : return (error);
96 : break;
97 : default:
98 0 : return (EINVAL);
99 : }
100 :
101 0 : if (wdog_auto && wdog_period > 0) {
102 0 : (void) (*wdog_ctl_cb)(wdog_ctl_cb_arg, wdog_period);
103 0 : timeout_add(&wdog_timeout, wdog_period * hz / 2);
104 0 : } else
105 0 : timeout_del(&wdog_timeout);
106 :
107 0 : return (error);
108 0 : }
|