Parallel make: additional fixes
[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
14 #include <sys/types.h>
15 #include <errno.h>
16 #include <sys/stat.h>
17 #include <lwp.h>
18 #include <rx/rx.h>
19 #ifdef AFS_NT40_ENV
20 #include <io.h>
21 #endif
22
23 #include <string.h>
24 #include <stdlib.h>
25
26 #include <afs/afsutil.h>
27 #include <afs/procmgmt.h>       /* signal(), kill(), wait(), etc. */
28 #include "bnode.h"
29 #include "bosprototypes.h"
30
31
32 struct bnode *ez_create(char *, char *, char *, char *, char *, char *);
33 static int ez_hascore(struct bnode *bnode);
34 static int ez_restartp(struct bnode *bnode);
35 static int ez_delete(struct bnode *bnode);
36 static int ez_timeout(struct bnode *bnode);
37 static int ez_getstat(struct bnode *bnode, afs_int32 *status);
38 static int ez_setstat(struct bnode *bnode, afs_int32 status);
39 static int ez_procexit(struct bnode *bnode, struct bnode_proc *proc);
40 static int ez_getstring(struct bnode *bnode, char *abuffer, afs_int32 alen);
41 static int ez_getparm(struct bnode *bnode, afs_int32, char *, afs_int32);
42
43 #define SDTIME          60      /* time in seconds given to a process to evaporate */
44
45 struct bnode_ops ezbnode_ops = {
46     ez_create,
47     ez_timeout,
48     ez_getstat,
49     ez_setstat,
50     ez_delete,
51     ez_procexit,
52     ez_getstring,
53     ez_getparm,
54     ez_restartp,
55     ez_hascore,
56 };
57
58 static int
59 ez_hascore(struct bnode *abnode)
60 {
61     char tbuffer[256];
62
63     bnode_CoreName(abnode, NULL, tbuffer);
64     if (access(tbuffer, 0) == 0)
65         return 1;
66     else
67         return 0;
68 }
69
70 static int
71 ez_restartp(struct bnode *bn)
72 {
73     struct ezbnode *abnode = (struct ezbnode *)bn;
74     struct bnode_token *tt;
75     register afs_int32 code;
76     struct stat tstat;
77
78     code = bnode_ParseLine(abnode->command, &tt);
79     if (code)
80         return 0;
81     if (!tt)
82         return 0;
83     code = stat(tt->key, &tstat);
84     if (code) {
85         bnode_FreeTokens(tt);
86         return 0;
87     }
88     if (tstat.st_ctime > abnode->lastStart)
89         code = 1;
90     else
91         code = 0;
92     bnode_FreeTokens(tt);
93     return code;
94 }
95
96 static int
97 ez_delete(struct bnode *bn)
98 {
99     struct ezbnode *abnode = (struct ezbnode *)bn;
100     
101     free(abnode->command);
102     free(abnode);
103     return 0;
104 }
105
106 struct bnode *
107 ez_create(char *ainstance, char *acommand, char *unused1, char *unused2, 
108           char *unused3, char *unused4)
109 {
110     struct ezbnode *te;
111     char *cmdpath;
112
113     if (ConstructLocalBinPath(acommand, &cmdpath)) {
114         bozo_Log("BNODE: command path invalid '%s'\n", acommand);
115         return NULL;
116     }
117
118     te = (struct ezbnode *)malloc(sizeof(struct ezbnode));
119     memset(te, 0, sizeof(struct ezbnode));
120     if (bnode_InitBnode((struct bnode *)te, &ezbnode_ops, ainstance) != 0) {
121         free(te);
122         return NULL;
123     }
124     te->command = cmdpath;
125     return (struct bnode *)te;
126 }
127
128 /* called to SIGKILL a process if it doesn't terminate normally */
129 static int
130 ez_timeout(struct bnode *bn)
131 {
132     struct ezbnode *abnode = (struct ezbnode *)bn;
133         
134     if (!abnode->waitingForShutdown)
135         return 0;               /* spurious */
136     /* send kill and turn off timer */
137     bnode_StopProc(abnode->proc, SIGKILL);
138     abnode->killSent = 1;
139     bnode_SetTimeout((struct bnode *)abnode, 0);
140     return 0;
141 }
142
143 static int
144 ez_getstat(struct bnode *bn, afs_int32 * astatus)
145 {
146     struct ezbnode *abnode = (struct ezbnode *)bn;
147     
148     register afs_int32 temp;
149     if (abnode->waitingForShutdown)
150         temp = BSTAT_SHUTTINGDOWN;
151     else if (abnode->running)
152         temp = BSTAT_NORMAL;
153     else
154         temp = BSTAT_SHUTDOWN;
155     *astatus = temp;
156     return 0;
157 }
158
159 static int
160 ez_setstat(struct bnode *bn, afs_int32 astatus)
161 {
162     struct ezbnode *abnode = (struct ezbnode *)bn;
163     
164     struct bnode_proc *tp;
165     register afs_int32 code;
166
167     if (abnode->waitingForShutdown)
168         return BZBUSY;
169     if (astatus == BSTAT_NORMAL && !abnode->running) {
170         /* start up */
171         abnode->lastStart = FT_ApproxTime();
172         code = bnode_NewProc((struct bnode *)abnode, abnode->command, NULL, &tp);
173         if (code)
174             return code;
175         abnode->running = 1;
176         abnode->proc = tp;
177         return 0;
178     } else if (astatus == BSTAT_SHUTDOWN && abnode->running) {
179         /* start shutdown */
180         bnode_StopProc(abnode->proc, SIGTERM);
181         abnode->waitingForShutdown = 1;
182         bnode_SetTimeout((struct bnode *)abnode, SDTIME);
183         return 0;
184     }
185     return 0;
186 }
187
188 static int
189 ez_procexit(struct bnode *bn, struct bnode_proc *aproc)
190 {
191     struct ezbnode *abnode = (struct ezbnode *)bn;
192
193     /* process has exited */
194     register afs_int32 code;
195
196     abnode->waitingForShutdown = 0;
197     abnode->running = 0;
198     abnode->killSent = 0;
199     abnode->proc = NULL;
200     bnode_SetTimeout((struct bnode *) abnode, 0);       /* clear timer */
201     if (abnode->b.goal)
202         code = ez_setstat((struct bnode *) abnode, BSTAT_NORMAL);
203     else
204         code = 0;
205     return code;
206 }
207
208 static int
209 ez_getstring(struct bnode *abnode, char *abuffer, afs_int32 alen)
210 {
211     return -1;                  /* don't have much to add */
212 }
213
214 static int
215 ez_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
216            afs_int32 alen)
217 {
218     struct ezbnode *abnode = (struct ezbnode *) bn;
219     if (aindex > 0)
220         return BZDOM;
221     strcpy(abuffer, abnode->command);
222     return 0;
223 }