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