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