devwd.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * watchdog framework
  3. */
  4. #include "u.h"
  5. #include "../port/lib.h"
  6. #include "mem.h"
  7. #include "dat.h"
  8. #include "fns.h"
  9. #include "io.h"
  10. #include "../port/error.h"
  11. enum {
  12. Qdir,
  13. Qwdctl,
  14. };
  15. static Watchdog *wd;
  16. static Dirtab wddir[] = {
  17. ".", { Qdir, 0, QTDIR }, 0, 0550,
  18. "wdctl", { Qwdctl, 0 }, 0, 0660,
  19. };
  20. void
  21. addwatchdog(Watchdog *watchdog)
  22. {
  23. if(wd){
  24. print("addwatchdog: watchdog already installed\n");
  25. return;
  26. }
  27. wd = watchdog;
  28. if(wd)
  29. wd->disable();
  30. }
  31. static Chan*
  32. wdattach(char *spec)
  33. {
  34. return devattach('w', spec);
  35. }
  36. static Walkqid*
  37. wdwalk(Chan *c, Chan *nc, char **name, int nname)
  38. {
  39. return devwalk(c, nc, name, nname, wddir, nelem(wddir), devgen);
  40. }
  41. static int
  42. wdstat(Chan *c, uchar *dp, int n)
  43. {
  44. return devstat(c, dp, n, wddir, nelem(wddir), devgen);
  45. }
  46. static Chan*
  47. wdopen(Chan* c, int omode)
  48. {
  49. return devopen(c, omode, wddir, nelem(wddir), devgen);
  50. }
  51. static void
  52. wdclose(Chan*)
  53. {
  54. }
  55. static long
  56. wdread(Chan* c, void* a, long n, vlong off)
  57. {
  58. ulong offset = off;
  59. char *p;
  60. switch((ulong)c->qid.path){
  61. case Qdir:
  62. return devdirread(c, a, n, wddir, nelem(wddir), devgen);
  63. case Qwdctl:
  64. if(wd == nil || wd->stat == nil)
  65. return 0;
  66. p = malloc(READSTR);
  67. if(waserror()){
  68. free(p);
  69. nexterror();
  70. }
  71. wd->stat(p, p + READSTR);
  72. n = readstr(offset, a, n, p);
  73. free(p);
  74. poperror();
  75. return n;
  76. default:
  77. error(Egreg);
  78. break;
  79. }
  80. return 0;
  81. }
  82. static long
  83. wdwrite(Chan* c, void* a, long n, vlong off)
  84. {
  85. ulong offset = off;
  86. char *p;
  87. switch((ulong)c->qid.path){
  88. case Qdir:
  89. error(Eperm);
  90. case Qwdctl:
  91. if(wd == nil)
  92. return n;
  93. if(offset || n >= READSTR)
  94. error(Ebadarg);
  95. if((p = strchr(a, '\n')) != nil)
  96. *p = 0;
  97. if(strncmp(a, "enable", n) == 0)
  98. wd->enable();
  99. else if(strncmp(a, "disable", n) == 0)
  100. wd->disable();
  101. else if(strncmp(a, "restart", n) == 0)
  102. wd->restart();
  103. else
  104. error(Ebadarg);
  105. return n;
  106. default:
  107. error(Egreg);
  108. break;
  109. }
  110. return 0;
  111. }
  112. Dev wddevtab = {
  113. 'w',
  114. "watchdog",
  115. devreset,
  116. devinit,
  117. devshutdown,
  118. wdattach,
  119. wdwalk,
  120. wdstat,
  121. wdopen,
  122. devcreate,
  123. wdclose,
  124. wdread,
  125. devbread,
  126. wdwrite,
  127. devbwrite,
  128. devremove,
  129. devwstat,
  130. devpower,
  131. };