]> andersk Git - moira.git/blame - dcm/dcm.c
Make a half-hearted attempt at returning a useful exit status, instead
[moira.git] / dcm / dcm.c
CommitLineData
846841f4 1/*
2ce085d2 2 * The Data Control Manager for MOIRA.
846841f4 3 *
4 * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
5 * For copying and distribution information, see the file
6 * "mit-copyright.h".
7 *
8 * $Source$
9 * $Author$
10 * $Header$
11 */
12
13#ifndef lint
14static char rcsid_dcm_c[] = "$Header$";
15#endif lint
16
17#include <stdio.h>
b91fbc27 18#include <stdlib.h>
846841f4 19#include <update.h>
20#include <sys/file.h>
21#include <sys/time.h>
22#include <sys/wait.h>
15fa49b5 23#include <sys/stat.h>
b91fbc27 24#include <time.h>
15fa49b5 25#include <fcntl.h>
a1a0dadf 26#include <signal.h>
846841f4 27#include <ctype.h>
2ce085d2 28#include <moira.h>
29#include <moira_site.h>
846841f4 30#include "dcm.h"
31#include "mit-copyright.h"
15fa49b5 32#include <unistd.h>
b91fbc27 33#include <com_err.h>
846841f4 34
b91fbc27 35extern int log_flags, errno;
846841f4 36int gqval();
846841f4 37
38
39/* declared global so that we can get the current time from different places. */
40struct timeval tv;
41
42
43main(argc, argv)
44int argc;
45char *argv[];
46{
47 int i;
48 char **arg = argv;
49 char *qargv[3];
fe83b772 50 char *s;
846841f4 51 int status;
52
53 whoami = argv[0];
fe83b772 54 s = getenv("DEBUG");
55 dbg = s ? atoi(s) : 0;
846841f4 56 umask(UMASK);
57 log_flags = 0;
15fa49b5 58
59 setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
60 setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
846841f4 61
62 while(++arg - argv < argc) {
63 if (**arg == '-')
64 switch((*arg)[1]) {
65 case 'd':
66 dbg = atoi((*arg)[2]? *arg+2: *++arg);
67 break;
68 }
69 }
70 set_com_err_hook(dcm_com_err_hook);
71
72 /* if /etc/nodcm exists, punt quietly. */
185f76ce 73 if (!access(NODCMFILE, F_OK)) {
846841f4 74 exit(1);
75 }
76
2ce085d2 77 if (status = mr_connect("")) {
78 com_err(whoami, status, " on mr_connect");
846841f4 79 leave("connect failed");
80 }
81
2ce085d2 82 if (status = mr_auth("dcm")) {
846841f4 83 com_err(whoami, status, " on \"authenticate\"");
84 leave("auth failed");
85 }
86
87 /* if DCM is not enabled, exit after logging */
88 qargv[0] = "dcm_enable";
2ce085d2 89 if (status = mr_query("get_value", 1, qargv, gqval, &i)) {
846841f4 90 com_err(whoami, status, " check dcm_enable");
91 leave("query failed");
92 }
93 if (i == 0) {
94 errno = 0;
95 leave("dcm_enable not set");
96 }
97
98 /* do it! */
846841f4 99 do_services();
100 errno = 0;
101 leave("");
102}
103
104
105/* Used by the get_value query when checking for dcm_enable. */
106
107gqval(argc, argv, hint)
108int argc;
109char **argv;
110int *hint;
111{
112 *hint = atoi(argv[0]);
113 return(UPCALL_STOP);
114}
115
116
117/* Used by qualified_get_server to make a list of servers to check */
118
119qgetsv(argc, argv, sq)
120int argc;
121char **argv;
122struct save_queue *sq;
123{
124 sq_save_data(sq, strsave(argv[0]));
125 return(UPCALL_CONT);
126}
127
128
129/* Used by get_server_info to record all of the returned information */
130
131getsvinfo(argc, argv, sserv)
132int argc;
133char **argv;
134struct service *sserv;
135{
136 sserv->service = strsave(argv[0]);
137 sserv->interval = atoi(argv[1]);
138 sserv->target = strsave(argv[2]);
139 sserv->script = strsave(argv[3]);
140 sserv->dfgen = atoi(argv[4]);
141 sserv->dfcheck = atoi(argv[5]);
142 sserv->type = strsave(argv[6]);
143 sserv->enable = atoi(argv[7]);
144 sserv->inprogress = atoi(argv[8]);
145 sserv->harderror = atoi(argv[9]);
146 sserv->errmsg = strsave(argv[10]);
147 return(UPCALL_STOP);
148}
149
150
151/* Scan the services and process any that need it. */
152
153do_services()
154{
155 char *qargv[6];
156 struct save_queue *sq, *sq_create();
157 char *service, dfgen_prog[64], dfgen_cmd[128];
158 struct service svc;
a1a0dadf 159 int status, lock_fd, ex, (*cstat)();
846841f4 160 struct timezone tz;
161 register char *p;
15fa49b5 162 int waits;
163 struct sigaction action, prevaction;
846841f4 164
165 if (dbg & DBG_VERBOSE)
166 com_err(whoami, 0, "starting pass over services");
167
168 qargv[0] = "true";
169 qargv[1] = "dontcare";
170 qargv[2] = "false";
171 sq = sq_create();
2ce085d2 172 if (status = mr_query_with_retry("qualified_get_server", 3, qargv,
0967ae03 173 qgetsv, sq)) {
846841f4 174 com_err(whoami, status, " getting services");
175 leave("query failed");
176 }
177 while (sq_get_data(sq, &service)) {
178 for (p = service; *p; p++)
179 if (isupper(*p))
180 *p = tolower(*p);
181 com_err(whoami, 0, "checking %s...", service);
182 qargv[0] = service;
185f76ce 183 sprintf(dfgen_prog, "%s/%s.gen", BIN_DIR, service);
846841f4 184 if (!file_exists(dfgen_prog)) {
185 com_err(whoami, 0, "prog %s doesn't exist\n", dfgen_prog);
186 free(service);
187 continue;
188 }
185f76ce 189 sprintf(dfgen_cmd, "exec %s %s/%s.out",
190 dfgen_prog, DCM_DIR, service);
846841f4 191 gettimeofday(&tv, &tz);
2ce085d2 192 if (status = mr_query_with_retry("get_server_info", 1, qargv,
0967ae03 193 getsvinfo, &svc)) {
4e5690ff 194 com_err(whoami, status, " getting service %s info, skipping to next service", service);
195 continue;
846841f4 196 }
197 svc.service = strsave(service);
198 qargv[0] = strsave(service);
199 qargv[1] = itoa(svc.dfgen);
200 qargv[2] = itoa(svc.dfcheck);
201 qargv[3] = strsave("0");
202 qargv[4] = itoa(svc.harderror);
203 qargv[5] = strsave(svc.errmsg);
204 if (svc.interval != 0) {
205 if (svc.interval * 60 + svc.dfcheck < tv.tv_sec) {
185f76ce 206 lock_fd = maybe_lock_update("@db@", service, 1);
846841f4 207 if (lock_fd < 0)
208 goto free_service;
209 free(qargv[3]);
210 free(qargv[4]);
211 free(qargv[5]);
212 qargv[3] = strsave("1");
213 qargv[4] = strsave("0");
214 qargv[5] = strsave("");
2ce085d2 215 status = mr_query_with_retry("set_server_internal_flags", 6,
0967ae03 216 qargv, scream, NULL);
2ce085d2 217 if (status != MR_SUCCESS) {
846841f4 218 com_err(whoami, status, " setting server state");
219 goto free_service;
220 }
221
222 com_err(whoami, status, " running %s", dfgen_prog);
15fa49b5 223
224 action.sa_flags = 0;
225 sigemptyset(&action.sa_mask);
226 action.sa_handler = SIG_DFL;
227 sigaction(SIGCHLD, &action, &prevaction);
228 waits = system(dfgen_cmd);
229 sigaction(SIGCHLD, &prevaction, NULL);
230 if (WIFSIGNALED(waits)) {
95d47b7a 231 status = MR_COREDUMP;
c9c95b8a 232 com_err(whoami, status, " %s exited on signal %d",
15fa49b5 233 dfgen_prog, WTERMSIG(waits));
234 } else if (WEXITSTATUS(waits)) {
c9c95b8a 235 /* extract the process's exit value */
15fa49b5 236 status = WEXITSTATUS(waits) + ERROR_TABLE_BASE_sms;
846841f4 237 com_err(whoami, status, " %s exited", dfgen_prog);
238 }
15fa49b5 239
846841f4 240 if (SOFT_FAIL(status)) {
241 free(qargv[5]);
242 qargv[5] = strsave(error_message(status));
2ce085d2 243 } else if (status == MR_NO_CHANGE) {
846841f4 244 free(qargv[2]);
245 qargv[2] = itoa(tv.tv_sec);
246 svc.dfcheck = tv.tv_sec;
2ce085d2 247 } else if (status == MR_SUCCESS) {
846841f4 248 free(qargv[1]);
249 free(qargv[2]);
250 qargv[1] = itoa(tv.tv_sec);
251 qargv[2] = strsave(qargv[1]);
252 svc.dfcheck = svc.dfgen = tv.tv_sec;
253 } else { /* HARD_FAIL(status) */
254 free(qargv[2]);
255 free(qargv[4]);
256 free(qargv[5]);
257 qargv[2] = itoa(tv.tv_sec);
258 svc.dfcheck = tv.tv_sec;
259 qargv[4] = itoa(status);
260 qargv[5] = strsave(error_message(status));
261 critical_alert("DCM","DCM building config files for %s: %s",
262 service, qargv[5]);
263 }
264 free_service:
265 free(qargv[3]);
266 qargv[3] = strsave("0");
2ce085d2 267 status = mr_query_with_retry("set_server_internal_flags", 6,
0967ae03 268 qargv, scream, NULL);
269 if (status)
270 com_err(whoami, status, " setting service state");
846841f4 271 close(lock_fd);
272 free(qargv[0]);
273 free(qargv[1]);
274 free(qargv[2]);
275 free(qargv[3]);
276 free(qargv[4]);
277 free(qargv[5]);
278 }
279 if (!strcmp(svc.type, "REPLICAT"))
280 ex = 1;
281 else
282 ex = 0;
185f76ce 283 lock_fd = maybe_lock_update("@db@", service, ex);
846841f4 284 if (lock_fd >= 0) {
285 do_hosts(&svc);
286 close(lock_fd);
287 }
288 }
289 free(svc.service);
290 free(svc.target);
291 free(svc.script);
292 free(svc.type);
293 free(svc.errmsg);
294 free(service);
295 }
296 sq_destroy(sq);
297}
298
299
300/* Used by qualified_get_server_host to make a list of hosts to check */
301
302qgethost(argc, argv, sq)
303int argc;
304char **argv;
305struct save_queue *sq;
306{
307 sq_save_data(sq, strsave(argv[1]));
308 return(UPCALL_CONT);
309}
310
311
312/* Used by get_server_host_info to store all of the info about a host */
313
314gethostinfo(argc, argv, shost)
315int argc;
316char **argv;
317struct svrhost *shost;
318{
319 shost->service = strsave(argv[0]);
320 shost->machine = strsave(argv[1]);
321 shost->enable = atoi(argv[2]);
322 shost->override = atoi(argv[3]);
323 shost->success = atoi(argv[4]);
324 shost->inprogress = atoi(argv[5]);
325 shost->hosterror = atoi(argv[6]);
326 shost->errmsg = strsave(argv[7]);
327 shost->lasttry = atoi(argv[8]);
328 shost->lastsuccess = atoi(argv[9]);
329 shost->value1 = atoi(argv[10]);
330 shost->value2 = atoi(argv[11]);
331 shost->value3 = strsave(argv[12]);
332 return(UPCALL_STOP);
333}
334
335
336/* Scans all of the hosts for a particular service, and processes them. */
337
338do_hosts(svc)
339struct service *svc;
340{
341 char *argv[9], *machine;
342 int status, lock_fd;
343 struct save_queue *sq;
344 struct svrhost shost;
345
346 sq = sq_create();
347 argv[0] = svc->service;
348 argv[1] = "TRUE";
349 argv[2] = argv[3] = argv[4] = "DONTCARE";
350 argv[5] = "FALSE";
2ce085d2 351 status = mr_query_with_retry("qualified_get_server_host", 6, argv,
0967ae03 352 qgethost, sq);
2ce085d2 353 if (status == MR_NO_MATCH) {
846841f4 354 return;
355 } else if (status) {
356 com_err(whoami, status, " getting server_hosts for %s", svc->service);
357 return;
358 }
359 while (sq_get_data(sq, &machine)) {
360 if (dbg & DBG_TRACE)
361 com_err(whoami, 0, "checking %s...", machine);
362 argv[1] = machine;
2ce085d2 363 status = mr_query_with_retry("get_server_host_info", 2, argv,
0967ae03 364 gethostinfo, &shost);
846841f4 365 if (status) {
366 com_err(whoami,status, " getting server_host_info for %s", machine);
367 goto free_mach;
368 }
369 if (!shost.enable || shost.hosterror ||
4112693b 370 (shost.success && !shost.override &&
6899dfbe 371 shost.lastsuccess >= svc->dfgen)) {
846841f4 372 if (dbg & DBG_TRACE)
373 com_err(whoami, 0, "not updating %s:%s", svc->service, machine);
374 goto free_mach;
375 }
062079b1 376
185f76ce 377 lock_fd = maybe_lock_update(machine, svc->service, 1);
062079b1 378 if (lock_fd < 0)
379 goto free_mach;
380 argv[0] = svc->service;
381 argv[1] = machine;
382 argv[2] = argv[3] = argv[5] = "0";
383 argv[4] = "1";
384 argv[6] = strsave("");
385 argv[7] = itoa(tv.tv_sec);
386 argv[8] = itoa(shost.lastsuccess);
2ce085d2 387 status = mr_query_with_retry("set_server_host_internal", 9, argv,
0967ae03 388 scream, NULL);
2ce085d2 389 if (status != MR_SUCCESS) {
062079b1 390 com_err(whoami,status," while setting internal state for %s:%s",
391 svc->service, machine);
392 goto free_mach;
393 }
2ce085d2 394 status = mr_update_server(svc->service, machine, svc->target,
062079b1 395 svc->script);
2ce085d2 396 if (status == MR_SUCCESS) {
67852ff1 397 argv[2] = argv[4] = "0";
062079b1 398 argv[3] = "1";
399 free(argv[8]);
400 argv[8] = itoa(tv.tv_sec);
401 } else if (SOFT_FAIL(status)) {
67852ff1 402 argv[4] = "0";
062079b1 403 free(argv[6]);
404 argv[6] = strsave(error_message(status));
405 } else { /* HARD_FAIL */
406 argv[2] = itoa(shost.override);
67852ff1 407 argv[4] = "0";
062079b1 408 argv[5] = itoa(status);
409 free(argv[6]);
410 argv[6] = strsave(error_message(status));
411 critical_alert("DCM", "DCM updating %s:%s: %s",
412 machine, svc->service, argv[6]);
413 if (!strcmp(svc->type, "REPLICAT")) {
414 char *qargv[6];
415
416 svc->harderror = status;
417 svc->errmsg = strsave(argv[6]);
418 qargv[0] = strsave(svc->service);
419 qargv[1] = itoa(svc->dfgen);
420 qargv[2] = itoa(svc->dfcheck);
421 qargv[3] = strsave("0");
422 qargv[4] = itoa(svc->harderror);
423 qargv[5] = strsave(svc->errmsg);
2ce085d2 424 status = mr_query_with_retry("set_server_internal_flags",
0967ae03 425 6, qargv, scream, NULL);
426 if (status)
427 com_err(whoami, status, " setting service state again");
062079b1 428 free(qargv[0]);
429 free(qargv[1]);
430 free(qargv[2]);
431 free(qargv[3]);
432 free(qargv[4]);
433 free(qargv[5]);
434 close(lock_fd);
2ce085d2 435 status = mr_query_with_retry("set_server_host_internal",
0967ae03 436 9, argv,scream,NULL);
67852ff1 437 free(argv[2]);
438 free(argv[5]);
0967ae03 439 if (status)
440 com_err(whoami, status, " setting host state again");
062079b1 441 return(-1);
846841f4 442 }
846841f4 443 }
062079b1 444 close(lock_fd);
2ce085d2 445 status = mr_query_with_retry("set_server_host_internal", 9, argv,
0967ae03 446 scream, NULL);
447 if (status)
448 com_err(whoami, status, " setting host state again");
67852ff1 449/* free(argv[2]);
450 free(argv[5]); */
846841f4 451 free_mach:
452 free(machine);
453 close(lock_fd);
454 }
455 return(0);
456}
This page took 0.161644 seconds and 5 git commands to generate.