1 #include <u.h>
2 #include <libc.h>
3
4 void
reboot(void)5 reboot(void)
6 {
7 int fd;
8 fd = open("/dev/reboot", OWRITE);
9 if(fd >= 0)
10 write(fd, "reboot", 6);
11 exits(0);
12 }
13
14 char*
readenv(char * name,char * buf,int n)15 readenv(char *name, char *buf, int n)
16 {
17 char *ans;
18 int f;
19 char ename[200];
20
21 ans = buf;
22 ename[0] = 0;
23 strcat(ename, "/env/");
24 strcat(ename, name);
25 f = open(ename, OREAD);
26 if(f < 0)
27 return 0;
28 n = read(f, ans, n-1);
29 if(n < 0)
30 ans = 0;
31 else
32 ans[n] = 0;
33 close(f);
34 return ans;
35 }
36
37 int alarmed;
38
39 void
ding(void *,char * msg)40 ding(void*, char*msg)
41 {
42 if(strstr(msg, "alarm")){
43 alarmed = 1;
44 noted(NCONT);
45 }
46 noted(NDFLT);
47 }
48
49 void
main(int argc,char ** argv)50 main(int argc, char **argv)
51 {
52 int fd;
53 char buf[256];
54 char file[128];
55 char *p;
56 Dir *d;
57
58 if(argc > 1)
59 strecpy(file, file+sizeof file, argv[1]);
60 else{
61 p = readenv("cputype", buf, sizeof buf);
62 if(p == 0)
63 exits(0);
64 file[0] = 0;
65 strcat(file, "/");
66 strcat(file, p);
67 strcat(file, "/lib");
68 }
69 if (access(file, AREAD) < 0)
70 sysfatal("%s not readable: %r", file);
71
72 switch(rfork(RFPROC|RFNOWAIT|RFNOTEG|RFCFDG)){
73 case 0:
74 break;
75 default:
76 exits(0);
77 }
78
79 notify(ding);
80 fd = open(file, OREAD);
81 if (fd < 0)
82 exits("no file");
83
84 // the logic here is to make a request every 5 minutes.
85 // If the request alarms out, that's OK, the file server
86 // may just be busy. If the request fails for any other
87 // reason, it's probably because the connection went
88 // away so reboot.
89 for(;;){
90 alarm(1000*60);
91 alarmed = 0;
92
93 d = dirfstat(fd);
94 free(d);
95 if(d == nil)
96 if(!alarmed)
97 reboot();
98 alarm(0);
99 sleep(60*1000*5);
100 }
101 }
102