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
);