xref: /plan9-contrib/sys/src/cmd/aux/reboot.c (revision ec59a3ddbfceee0efe34584c2c9981a5e5ff1ec4)
1 #include <u.h>
2 #include <libc.h>
3 
4 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*
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
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
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 	switch(rfork(RFPROC|RFNOWAIT|RFNOTEG|RFCFDG)){
59 	case 0:
60 		break;
61 	default:
62 		exits(0);
63 	}
64 
65 	notify(ding);
66 	if(argc > 1)
67 		strecpy(file, file+sizeof file, argv[1]);
68 	else{
69 		p = readenv("cputype", buf, sizeof buf);
70 		if(p == 0)
71 			exits(0);
72 		file[0] = 0;
73 		strcat(file, "/");
74 		strcat(file, p);
75 		strcat(file, "/lib");
76 	}
77 
78 	fd = open(file, OREAD);
79 
80 	//  the logic here is to make a request every 5 minutes.
81 	//  If the request alarms out, that's OK, the file server
82 	//  may just be busy.  If the request fails for any other
83 	//  reason, it's probably because the connection went
84 	//  away so reboot.
85 	for(;;){
86 		alarm(1000*60*5);
87 		alarmed = 0;
88 
89 		d = dirfstat(fd);
90 		free(d);
91 		if(d == nil)
92 			if(!alarmed)
93 				reboot();
94 		alarm(0);
95 		sleep(60*1000);
96 	}
97 }
98