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