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