2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include <afs/param.h>
13 #include <afs/procmgmt.h>
19 #include <afs/afsutil.h>
20 #include <opr/queue.h>
23 #include "bnode_internal.h"
24 #include "bosprototypes.h"
26 extern char *DoPidFiles;
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);
40 #define SDTIME 60 /* time in seconds given to a process to evaporate */
41 #define ERROR_RESET_TIME 60 /* time in seconds to wait before resetting error count state */
43 struct bnode_ops ezbnode_ops = {
58 ez_hascore(struct bnode *abnode)
62 bnode_CoreName(abnode, NULL, tbuffer);
63 if (access(tbuffer, 0) == 0)
70 ez_restartp(struct bnode *bn)
72 struct ezbnode *abnode = (struct ezbnode *)bn;
73 struct bnode_token *tt;
77 code = bnode_ParseLine(abnode->command, &tt);
82 code = stat(tt->key, &tstat);
87 if (tstat.st_ctime > abnode->lastStart)
96 ez_delete(struct bnode *bn)
98 struct ezbnode *abnode = (struct ezbnode *)bn;
100 free(abnode->command);
106 ez_create(char *ainstance, char *acommand, char *unused1, char *unused2,
107 char *unused3, char *unused4)
112 if (ConstructLocalBinPath(acommand, &cmdpath)) {
113 bozo_Log("BNODE: command path invalid '%s'\n", acommand);
117 te = calloc(1, sizeof(struct ezbnode));
118 if (bnode_InitBnode((struct bnode *)te, &ezbnode_ops, ainstance) != 0) {
122 te->command = cmdpath;
123 return (struct bnode *)te;
126 /* called to SIGKILL a process if it doesn't terminate normally
127 * or to retry start after an error stop. */
129 ez_timeout(struct bnode *bn)
131 struct ezbnode *abnode = (struct ezbnode *)bn;
133 if (abnode->waitingForShutdown) {
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 } else if (!abnode->running && abnode->b.flags & BNODE_ERRORSTOP) {
139 /* was stopped for too many errors, retrying */
140 /* reset error count after running for a bit */
141 bnode_SetTimeout(bn, ERROR_RESET_TIME);
142 bnode_SetStat(bn, BSTAT_NORMAL);
144 bnode_SetTimeout(bn, 0); /* one shot timer */
145 bnode_ResetErrorCount(bn);
151 ez_getstat(struct bnode *bn, afs_int32 * astatus)
153 struct ezbnode *abnode = (struct ezbnode *)bn;
156 if (abnode->waitingForShutdown)
157 temp = BSTAT_SHUTTINGDOWN;
158 else if (abnode->running)
160 else if (abnode->b.flags & BNODE_ERRORSTOP)
161 temp = BSTAT_STARTINGUP;
163 temp = BSTAT_SHUTDOWN;
169 ez_setstat(struct bnode *bn, afs_int32 astatus)
171 struct ezbnode *abnode = (struct ezbnode *)bn;
173 struct bnode_proc *tp;
176 if (abnode->waitingForShutdown)
178 if (astatus == BSTAT_NORMAL && !abnode->running) {
180 abnode->lastStart = FT_ApproxTime();
181 code = bnode_NewProc((struct bnode *)abnode, abnode->command, NULL, &tp);
187 } else if (astatus == BSTAT_SHUTDOWN && abnode->running) {
189 bnode_StopProc(abnode->proc, SIGTERM);
190 abnode->waitingForShutdown = 1;
191 bnode_SetTimeout((struct bnode *)abnode, SDTIME);
198 ez_procstarted(struct bnode *bn, struct bnode_proc *aproc)
203 code = bozo_CreatePidFile(bn->name, NULL, aproc->pid);
209 ez_procexit(struct bnode *bn, struct bnode_proc *aproc)
211 struct ezbnode *abnode = (struct ezbnode *)bn;
213 /* process has exited */
217 bozo_DeletePidFile(bn->name, NULL);
220 abnode->waitingForShutdown = 0;
222 abnode->killSent = 0;
224 bnode_SetTimeout((struct bnode *) abnode, 0); /* clear timer */
226 code = ez_setstat((struct bnode *) abnode, BSTAT_NORMAL);
227 else if (abnode->b.flags & BNODE_ERRORSTOP && abnode->b.errorStopDelay) {
228 bozo_Log("%s will retry start in %d seconds\n", abnode->b.name,
229 abnode->b.errorStopDelay);
230 bnode_SetTimeout(bn, abnode->b.errorStopDelay);
236 ez_getstring(struct bnode *abnode, char *abuffer, afs_int32 alen)
238 return -1; /* don't have much to add */
242 ez_getparm(struct bnode *bn, afs_int32 aindex, char *abuffer,
245 struct ezbnode *abnode = (struct ezbnode *) bn;
248 strcpy(abuffer, abnode->command);