bozo: bosserver -pidfiles option
[openafs.git] / src / bozo / ezbnodeops.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13 #include <afs/procmgmt.h>
14 #include <roken.h>
15
16 #include <lwp.h>
17 #include <rx/rx.h>
18 #ifdef AFS_NT40_ENV
19 #include <io.h>
20 #endif
21
22 #include <afs/afsutil.h>
23 #include "bnode.h"
24 #include "bosprototypes.h"
25
26 extern char *DoPidFiles;
27
28 struct bnode *ez_create(char *, char *, char *, char *, char *, char *);
29 static int ez_hascore(struct bnode *bnode);
30 static int ez_restartp(struct bnode *bnode);
31 static int ez_delete(struct bnode *bnode);
32 static int ez_timeout(struct bnode *bnode);
33 static int ez_getstat(struct bnode *bnode, afs_int32 *status);
34 static int ez_setstat(struct bnode *bnode, afs_int32 status);
35 static int ez_procexit(struct bnode *bnode, struct bnode_proc *proc);
36 static int ez_getstring(struct bnode *bnode, char *abuffer, afs_int32 alen);
37 static int ez_getparm(struct bnode *bnode, afs_int32, char *, afs_int32);
38 static int ez_procstarted(struct bnode *bnode, struct bnode_proc *proc);
39
40 #define SDTIME          60      /* time in seconds given to a process to evaporate */
41
42 struct bnode_ops ezbnode_ops = {
43     ez_create,
44     ez_timeout,
45     ez_getstat,
46     ez_setstat,
47     ez_delete,
48     ez_procexit,
49     ez_getstring,
50     ez_getparm,
51     ez_restartp,
52     ez_hascore,
53     ez_procstarted
54 };
55
56 static int
57 ez_hascore(struct bnode *abnode)
58 {
59     char tbuffer[256];
60
61     bnode_CoreName(abnode, NULL, tbuffer);
62     if (access(tbuffer, 0) == 0)
63         return 1;
64     else
65         return 0;
66 }
67
68 static int
69 ez_restartp(struct bnode *bn)
70 {
71     struct ezbnode *abnode = (struct ezbnode *)bn;
72     struct bnode_token *tt;
73     afs_int32 code;
74     struct stat tstat;
75
76     code = bnode_ParseLine(abnode->command, &tt);
77     if (code)
78         return 0;
79     if (!tt)
80         return 0;
81     code = stat(tt->key, &tstat);
82     if (code) {
83         bnode_FreeTokens(tt);
84         return 0;
85     }
86     if (tstat.st_ctime > abnode->lastStart)
87         code = 1;
88     else
89         code = 0;
90     bnode_FreeTokens(tt);
91     return code;
92 }
93
94 static int
95 ez_delete(struct bnode *bn)
96 {
97     struct ezbnode *abnode = (struct ezbnode *)bn;
98
99     free(abnode->command);
100     free(abnode);
101     return 0;
102 }
103
104 struct bnode *
105 ez_create(char *ainstance, char *acommand, char *unused1, char *unused2,
106           char *unused3, char *unused4)
107 {
108     struct ezbnode *te;
109     char *cmdpath;
110
111     if (ConstructLocalBinPath(acommand, &cmdpath)) {
112         bozo_Log("BNODE: command path invalid '%s'\n", acommand);
113         return NULL;
114     }
115
116     te = (struct ezbnode *)malloc(sizeof(struct ezbnode));
117     memset(te, 0, sizeof(struct ezbnode));
118     if (bnode_InitBnode((struct bnode *)te, &ezbnode_ops, ainstance) != 0) {
119         free(te);
120         return NULL;
121     }
122     te->command = cmdpath;
123     return (struct bnode *)te;
124 }
125
126 /* called to SIGKILL a process if it doesn't terminate normally */
127 static int
128 ez_timeout(struct bnode *bn)
129 {
130     struct ezbnode *abnode = (struct ezbnode *)bn;
131
132     if (!abnode->waitingForShutdown)
133         return 0;               /* spurious */
134     /* send kill and turn off timer */
135     bnode_StopProc(abnode->proc, SIGKILL);
136     abnode->killSent = 1;
137     bnode_SetTimeout((struct bnode *)abnode, 0);
138     return 0;
139 }
140
141 static int
142 ez_getstat(struct bnode *bn, afs_int32 * astatus)
143 {
144     struct ezbnode *abnode = (struct ezbnode *)bn;
145
146     afs_int32 temp;
147     if (abnode->waitingForShutdown)
148         temp = BSTAT_SHUTTINGDOWN;
149     else if (abnode->running)
150         temp = BSTAT_NORMAL;
151     else
152         temp = BSTAT_SHUTDOWN;
153     *astatus = temp;
154     return 0;
155 }
156
157 static int
158 ez_setstat(struct bnode *bn, afs_int32 astatus)
159 {
160     struct ezbnode *abnode = (struct ezbnode *)bn;
161
162     struct bnode_proc *tp;
163     afs_int32 code;
164
165     if (abnode->waitingForShutdown)
166         return BZBUSY;
167     if (astatus == BSTAT_NORMAL && !abnode->running) {
168         /* start up */
169         abnode->lastStart = FT_ApproxTime();
170         code = bnode_NewProc((struct bnode *)abnode, abnode->command, NULL, &tp);
171         if (code)
172             return code;
173         abnode->running = 1;
174         abnode->proc = tp;
175         return 0;
176     } else if (astatus == BSTAT_SHUTDOWN && abnode->running) {
177         /* start shutdown */
178         bnode_StopProc(abnode->proc, SIGTERM);
179         abnode->waitingForShutdown = 1;
180         bnode_SetTimeout((struct bnode *)abnode, SDTIME);
181         return 0;
182     }
183     return 0;
184 }
185
186 static int
187 ez_procstarted(struct bnode *bn, struct bnode_proc *aproc)
188 {
189     int code = 0;
190
191     if (DoPidFiles) {
192         code = bozo_CreatePidFile(bn->name, NULL, aproc->pid);
193     }
194     return code;;
195 }
196
197 static int
198 ez_procexit(struct bnode *bn, struct bnode_proc *aproc)
199 {
200     struct ezbnode *abnode = (struct ezbnode *)bn;
201
202     /* process has exited */
203     afs_int32 code;
204
205     if (DoPidFiles) {
206         bozo_DeletePidFile(bn->name, NULL);
207     }
208
209     abnode->waitingForShutdown = 0;
210     abnode->running = 0;
211     abnode->killSent = 0;
212     abnode->proc = NULL;
213     bnode_SetTimeout((struct bnode *) abnode, 0);       /* clear timer */
214     if (abnode->b.goal)
215         code = ez_setstat((struct bnode *) abnode, BSTAT_NORMAL);
216     else
217         code = 0;
218     return code;
219 }
220
221 static int
222 ez_getstring(struct bnode *abnode, char *abuffer, afs_int32 alen)
223 {
224     return -1;                  /* don't have much to add */
225 }
226
227 static int
228 ez_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
229            afs_int32 alen)
230 {
231     struct ezbnode *abnode = (struct ezbnode *) bn;
232     if (aindex > 0)
233         return BZDOM;
234     strcpy(abuffer, abnode->command);
235     return 0;
236 }