summaryrefslogtreecommitdiff
path: root/sys/src/cmd/aux/reboot.c
blob: 653f0b3fca2a5e1ca7cf7f94a4e1929011dae0eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <u.h>
#include <libc.h>

void
reboot(void)
{
	int fd;
	fd = open("/dev/reboot", OWRITE);
	if(fd >= 0)
		write(fd, "reboot", 6);
	exits(0);
}

char*
readenv(char *name, char *buf, int n)
{
	char *ans;
	int f;
	char ename[200];

	ans = buf;
	ename[0] = 0;
	strcat(ename, "/env/");
	strcat(ename, name);
	f = open(ename, OREAD);
	if(f < 0)
		return 0;
	n = read(f, ans, n-1);
	if(n < 0)
		ans = 0;
	else
		ans[n] = 0;
	close(f);
	return ans;
}

int alarmed;

void
ding(void*, char*msg)
{
	if(strstr(msg, "alarm")){
		alarmed = 1;
		noted(NCONT);
	}
	noted(NDFLT);
}

void
main(int argc, char **argv)
{
	int fd;
	char buf[256];
	char file[128];
	char *p;
	Dir *d;

	if(argc > 1)
		strecpy(file, file+sizeof file, argv[1]);
	else{
		p = readenv("cputype", buf, sizeof buf);
		if(p == 0)
			exits(0);
		file[0] = 0;
		strcat(file, "/");
		strcat(file, p);
		strcat(file, "/lib");
	}
	if (access(file, AREAD) < 0)
		sysfatal("%s not readable: %r", file);

	switch(rfork(RFPROC|RFNOWAIT|RFNOTEG|RFCFDG)){
	case 0:
		break;
	default:
		exits(0);
	}

	notify(ding);
	fd = open(file, OREAD);
	if (fd < 0)
		exits("no file");

	//  the logic here is to make a request every 5 minutes.
	//  If the request alarms out, that's OK, the file server
	//  may just be busy.  If the request fails for any other
	//  reason, it's probably because the connection went
	//  away so reboot.
	for(;;){
		alarm(1000*60);
		alarmed = 0;

		d = dirfstat(fd);
		free(d);
		if(d == nil)
			if(!alarmed)
				reboot();
		alarm(0);
		sleep(60*1000*5);
	}
}