]> andersk Git - moira.git/blob - dcm/dcm.c
Don't log a critical error if the user ^Cs a DCM build. Just print a
[moira.git] / dcm / dcm.c
1 /*
2  * The Data Control Manager for MOIRA.
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
14 static char rcsid_dcm_c[] = "$Header$";
15 #endif lint
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <update.h>
20 #include <sys/file.h>
21 #include <sys/time.h>
22 #include <sys/wait.h>
23 #include <sys/stat.h>
24 #include <time.h>
25 #include <fcntl.h>
26 #include <signal.h>
27 #include <ctype.h>
28 #include <moira.h>
29 #include <moira_site.h>
30 #include "dcm.h"
31 #include "mit-copyright.h"
32 #include <unistd.h>
33 #include <com_err.h>
34
35 extern int log_flags, errno;
36 int gqval();
37 char *whoami;
38
39 /* declared global so that we can get the current time from different places. */
40 struct timeval tv;
41
42
43 main(argc, argv)
44 int argc;
45 char *argv[];
46 {
47         int i;
48         char **arg = argv;
49         char *qargv[3];
50         char *s;
51         int status;
52
53         whoami = argv[0];
54         s = getenv("DEBUG");
55         dbg = s ? atoi(s) : 0;
56         umask(UMASK);
57         log_flags = 0;
58
59         setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
60         setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
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. */
73         if (!access(NODCMFILE, F_OK)) {
74                 exit(1);
75         } 
76
77         if (status = mr_connect("")) {
78             com_err(whoami, status, " on mr_connect");
79             leave("connect failed");
80         }
81
82         if (status = mr_auth("dcm")) {
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";
89         if (status = mr_query("get_value", 1, qargv, gqval, &i)) {
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! */
99         do_services();
100         errno = 0;
101         leave("");
102 }
103
104
105 /* Used by the get_value query when checking for dcm_enable. */
106
107 gqval(argc, argv, hint)
108 int argc;
109 char **argv;
110 int *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
119 qgetsv(argc, argv, sq)
120 int argc;
121 char **argv;
122 struct 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
131 getsvinfo(argc, argv, sserv)
132 int argc;
133 char **argv;
134 struct 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
153 do_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;
159     int status, lock_fd, ex, (*cstat)();
160     struct timezone tz;
161     register char *p;
162     int waits;
163     struct sigaction action, prevaction;
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();
172     if (status = mr_query("qualified_get_server", 3, qargv, qgetsv, sq)) {
173         com_err(whoami, status, " getting services");
174         leave("query failed");
175     }
176     while (sq_get_data(sq, &service)) {
177         for (p = service; *p; p++)
178           if (isupper(*p))
179             *p = tolower(*p);
180         com_err(whoami, 0, "checking %s...", service);
181         qargv[0] = service;
182         sprintf(dfgen_prog, "%s/%s.gen", BIN_DIR, service);
183         if (!file_exists(dfgen_prog)) {
184             com_err(whoami, 0, "prog %s doesn't exist\n", dfgen_prog);
185             free(service);
186             continue;
187         }
188         sprintf(dfgen_cmd, "exec %s %s/%s.out",
189                 dfgen_prog, DCM_DIR, service);
190         gettimeofday(&tv, &tz);
191         if (status = mr_query("get_server_info", 1, qargv, getsvinfo, &svc)) {
192             com_err(whoami, status, " getting service %s info, skipping to next service", service);
193             continue;
194         }
195         svc.service = strsave(service);
196         qargv[0] = strsave(service);
197         qargv[1] = itoa(svc.dfgen);
198         qargv[2] = itoa(svc.dfcheck);
199         qargv[3] = strsave("0");
200         qargv[4] = itoa(svc.harderror);
201         qargv[5] = strsave(svc.errmsg);
202         if (svc.interval != 0) {
203             if (svc.interval * 60 + svc.dfcheck < tv.tv_sec) {
204                 lock_fd = maybe_lock_update("@db@", service, 1);
205                 if (lock_fd < 0)
206                   goto free_service;
207                 free(qargv[3]);
208                 free(qargv[4]);
209                 free(qargv[5]);
210                 qargv[3] = strsave("1");
211                 qargv[4] = strsave("0");
212                 qargv[5] = strsave("");
213                 status = mr_query("set_server_internal_flags", 6,
214                                   qargv, scream, NULL);
215                 if (status != MR_SUCCESS) {
216                     com_err(whoami, status, " setting server state");
217                     goto free_service;
218                 }
219             
220                 com_err(whoami, status, " running %s", dfgen_prog);
221
222                 action.sa_flags = 0;
223                 sigemptyset(&action.sa_mask);
224                 action.sa_handler = SIG_DFL;
225                 sigaction(SIGCHLD, &action, &prevaction);
226                 waits = system(dfgen_cmd);
227                 sigaction(SIGCHLD, &prevaction, NULL);
228                 if (WIFSIGNALED(waits)) {
229                     status = MR_COREDUMP;
230                     com_err(whoami, status, " %s exited on signal %d",
231                             dfgen_prog, WTERMSIG(waits));
232                 } else if (WEXITSTATUS(waits)) {
233                     /* extract the process's exit value */
234                     status = WEXITSTATUS(waits) + ERROR_TABLE_BASE_sms;
235                     com_err(whoami, status, " %s exited", dfgen_prog);
236                 }
237
238                 if (SOFT_FAIL(status)) {
239                     free(qargv[5]);
240                     qargv[5] = strsave(error_message(status));
241                 } else if (status == MR_NO_CHANGE) {
242                     free(qargv[2]);
243                     qargv[2] = itoa(tv.tv_sec);
244                     svc.dfcheck = tv.tv_sec;
245                 } else if (status == MR_SUCCESS) {
246                     free(qargv[1]);
247                     free(qargv[2]);
248                     qargv[1] = itoa(tv.tv_sec);
249                     qargv[2] = strsave(qargv[1]);
250                     svc.dfcheck = svc.dfgen = tv.tv_sec;
251                 } else { /* HARD_FAIL(status) */
252                     free(qargv[2]);
253                     free(qargv[4]);
254                     free(qargv[5]);
255                     qargv[2] = itoa(tv.tv_sec); 
256                     svc.dfcheck = tv.tv_sec;
257                     qargv[4] = itoa(status);
258                     qargv[5] = strsave(error_message(status));
259                     critical_alert("DCM","DCM building config files for %s: %s",
260                                   service, qargv[5]);
261                 }
262             free_service:
263                 free(qargv[3]);
264                 qargv[3] = strsave("0");
265                 status = mr_query("set_server_internal_flags", 6,
266                                   qargv, scream, NULL);
267                 if (status)
268                   com_err(whoami, status, " setting service state");
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("@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
300 qgethost(argc, argv, sq)
301 int argc;
302 char **argv;
303 struct 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
312 gethostinfo(argc, argv, shost)
313 int argc;
314 char **argv;
315 struct 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
336 do_hosts(svc)
337 struct 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 = mr_query("qualified_get_server_host", 6, argv, qgethost, sq);
350     if (status == MR_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 = mr_query("get_server_host_info", 2, argv,
361                           gethostinfo, &shost);
362         if (status) {
363             com_err(whoami,status, " getting server_host_info for %s", machine);
364             goto free_mach;
365         }
366         if (!shost.enable || shost.hosterror ||
367             (shost.success && !shost.override &&
368              shost.lastsuccess >= svc->dfgen)) {
369             if (dbg & DBG_TRACE)
370               com_err(whoami, 0, "not updating %s:%s", svc->service, machine);
371             goto free_mach;
372         }
373
374         lock_fd = maybe_lock_update(machine, svc->service, 1);
375         if (lock_fd < 0)
376           goto free_mach;
377         argv[0] = svc->service;
378         argv[1] = machine;
379         argv[2] = argv[3] = argv[5] = "0";
380         argv[4] = "1";
381         argv[6] = strsave("");
382         argv[7] = itoa(tv.tv_sec);
383         argv[8] = itoa(shost.lastsuccess);
384         status = mr_query("set_server_host_internal", 9, argv, scream, NULL);
385         if (status != MR_SUCCESS) {
386             com_err(whoami,status," while setting internal state for %s:%s",
387                     svc->service, machine);
388             goto free_mach;
389         }
390         status = mr_update_server(svc->service, machine, svc->target,
391                                    svc->script);
392         if (status == MR_SUCCESS) {
393             argv[2] = argv[4] = "0";
394             argv[3] = "1";
395             free(argv[8]);
396             argv[8] = itoa(tv.tv_sec);
397         } else if (SOFT_FAIL(status)) {
398             argv[4] = "0";
399             free(argv[6]);
400             argv[6] = strsave(error_message(status));
401         } else { /* HARD_FAIL */
402             argv[2] = itoa(shost.override);
403             argv[4] = "0";
404             argv[5] = itoa(status);
405             free(argv[6]);
406             argv[6] = strsave(error_message(status));
407             critical_alert("DCM", "DCM updating %s:%s: %s",
408                            machine, svc->service, argv[6]);
409             if (!strcmp(svc->type, "REPLICAT")) {
410                 char *qargv[6];
411
412                 svc->harderror = status;
413                 svc->errmsg = strsave(argv[6]);
414                 qargv[0] = strsave(svc->service);
415                 qargv[1] = itoa(svc->dfgen);
416                 qargv[2] = itoa(svc->dfcheck);
417                 qargv[3] = strsave("0");
418                 qargv[4] = itoa(svc->harderror);
419                 qargv[5] = strsave(svc->errmsg);
420                 status = mr_query("set_server_internal_flags",
421                                   6, qargv, scream, NULL);
422                 if (status)
423                   com_err(whoami, status, " setting service state again");
424                 free(qargv[0]);
425                 free(qargv[1]);
426                 free(qargv[2]);
427                 free(qargv[3]);
428                 free(qargv[4]);
429                 free(qargv[5]);
430                 close(lock_fd);
431                 status = mr_query("set_server_host_internal",
432                                   9, argv,scream,NULL);
433                 free(argv[2]);
434                 free(argv[5]);
435                 if (status)
436                   com_err(whoami, status, " setting host state again");
437                 return(-1);
438             }
439         }
440         close(lock_fd);
441         status = mr_query("set_server_host_internal", 9, argv, scream, NULL);
442         if (status)
443           com_err(whoami, status, " setting host state again");
444 /*      free(argv[2]);
445         free(argv[5]); */
446     free_mach:
447         free(machine);
448         close(lock_fd);
449     }
450     return(0);
451 }
This page took 0.074186 seconds and 5 git commands to generate.