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