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