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