]> git.neil.brown.name Git - metad.git/blob - loadstate.c
Assorted reformating
[metad.git] / loadstate.c
1
2 /*
3  * load process state from a file.
4  * when metad reruns itself, it saves state in the form
5  * of a "list" output.
6  * we now read that it and add proc entries as appropriate
7  *
8  */
9 #include        "metad.h"
10 #include        <fcntl.h>
11 #ifdef SOLARIS
12 #include        <sys/fcntl.h>
13 #else
14 #include        <sys/file.h>
15 #endif
16 #include        "skip.h"
17
18 void qfree(char *a)
19 {
20         if (a) free(a);
21 }
22
23 void loadstate(int fd)
24 {
25         int len = lseek(fd, 0, 2);
26         int b;
27         char *buf;
28         lseek(fd, 0, 0);
29
30         buf = (char*)malloc(len);
31         read(fd, buf, len);
32         close(fd);
33
34         init_recv(buf);
35         if (get_byte() != 3) return; /* something VERY wrong */
36         b = get_byte();
37         while ( b==1 || b == 2) { /* service */
38
39                 char *sname;
40                 int enabled;
41                 int args;
42                 int class;
43                 service_t sv, *svp = NULL;
44
45                 sname = get_str();
46                 if (sname) {
47                         svp = skip_search(services, sname);
48                         free(sname);
49                 }
50                 get_int();      /* max */
51                 qfree(get_str());       /* home */
52                 qfree(get_str());       /* user */
53                 qfree(get_str());       /* crash */
54                 if (b == 2) {
55                         get_int(); /* watch_output */
56                         qfree(get_str());       /* pidfile */
57                 }
58                 get_int();      /* cnt */
59                 enabled = get_int();
60                 qfree(get_str());       /* prog */
61                 args = get_int();
62                 while (args--)
63                         qfree(get_str());
64                 class = get_byte();
65                 switch(class) {
66                 case 1:
67                         get_int();
68                         get_int();
69                         get_int();
70                         break;
71                 case 2:
72                         get_int();
73                         get_int();
74                         get_int();
75                         get_int();
76                         break;
77                 }
78                 if (svp) sv=  *svp ;else sv= NULL;
79                 if (sv) sv->enabled = enabled;
80                 b = get_byte();
81                 while (b == 3 || b == 4) { /* process */
82
83                         int pid, start, xit;
84                         int forkedpid = 0, pipefd = -1;
85                         pid = get_int();
86                         if (b == 4) {
87                                 forkedpid = get_int();
88                                 pipefd = get_int();
89                         }
90
91                         start = get_int(); /* start */
92                         get_int(); /* hold */
93                         xit = get_int();
94                         get_int(); /* status */
95                         if ((sv && (xit == 0 && kill(pid, 0)==0)) ||
96                             (xit>0 && forkedpid>0 && kill(forkedpid,0)==0) ) {
97                                 proc_t p = (proc_t)malloc(sizeof(struct proc));
98                                 p->pid = pid;
99                                 p->service = sv;
100                                 p->pipefd = pipefd;
101                                 p->bufptr = 0;
102                                 p->it_forked = forkedpid;
103                                 p->is_crash = 0;
104                                 p->start_time = start;
105                                 p->hold_time = xit?1:0;
106                                 p->exit_time = xit;
107                                 skip_insert(sv->proc_list, p);
108                                 skip_insert(allprocs, p);
109                         }
110                         b = get_byte();
111                 }
112         }
113         free(buf);
114 }
115
116 extern char **gargv;
117 void restart(void)
118 {
119         int fd;
120         int len;
121         char *buf;
122         service_t *svp;
123         char *file = "/var/tmp/...metad-temp-file";
124
125         fd = open(file, O_RDWR|O_TRUNC|O_CREAT, 0600);
126         if (fd < 0) {
127                 close(0);
128                 execv(gargv[2], gargv);
129                 exit(1);
130         }
131         unlink(file);
132         init_return();
133         send_byte(3);           /* listing */
134         for (svp = skip_first(services) ; svp ; svp = skip_next(svp)) {
135                 send_service(*svp);
136         }
137         send_byte(0);           /* finished */
138
139         buf = get_return(&len);
140         write(fd, buf, len);
141         if (fd > 0) {
142                 close(0);
143                 dup(fd);
144                 close(fd);
145         }
146         gargv[0] = "metad-restart";
147         execv(gargv[2], gargv);
148         exit(1);
149 }