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