kern_watchdog.c 3.0 KB

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