]> andersk Git - moira.git/commitdiff
New DCM using embedded SQL instead of libmrglue
authordanw <danw>
Fri, 5 Sep 1997 20:15:09 +0000 (20:15 +0000)
committerdanw <danw>
Fri, 5 Sep 1997 20:15:09 +0000 (20:15 +0000)
dcm/Imakefile
dcm/dcm.c [deleted file]
dcm/dcm.pc [new file with mode: 0644]
dcm/utils.c [deleted file]

index 826c0fd37ca263756b5cbc9c8582abc65a4ddd80..48643eff2ee4508b04ecde6bd3ed321eab158186 100644 (file)
@@ -8,9 +8,12 @@
 # Imakefile for moira dcm.
 
 SRCDIR = $(SRCTOP)/dcm
-SRCS= startdcm.c dcm.c utils.c
-CODE=$(SRCS)
-OBJS=dcm.o utils.o
+SRCS= startdcm.c dcm.c
+CODE= startdcm.c dcm.pc
+OBJS=dcm.o
+sqlrule()
 
 program(dcm, $(OBJS),,../update/moira_update.o $(CLIBS) $(SQL_LIB), ${PROGDIR})
 program(startdcm, startdcm.o,,,${PROGDIR})
+
+sqlfile(dcm)
diff --git a/dcm/dcm.c b/dcm/dcm.c
deleted file mode 100644 (file)
index 054ae0b..0000000
--- a/dcm/dcm.c
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * The Data Control Manager for MOIRA.
- *
- * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
- * For copying and distribution information, see the file
- * "mit-copyright.h".
- *
- * $Source$
- * $Author$
- * $Header$
- */
-
-#ifndef lint
-static char rcsid_dcm_c[] = "$Header$";
-#endif lint
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <update.h>
-#include <sys/file.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <ctype.h>
-#include <moira.h>
-#include <moira_site.h>
-#include "dcm.h"
-#include "mit-copyright.h"
-#include <unistd.h>
-#include <com_err.h>
-
-extern int log_flags, errno;
-int gqval();
-char *whoami;
-
-/* declared global so that we can get the current time from different places. */
-struct timeval tv;
-
-
-main(argc, argv)
-int argc;
-char *argv[];
-{
-       int i;
-       char **arg = argv;
-       char *qargv[3];
-       char *s;
-       int status;
-
-       whoami = argv[0];
-       s = getenv("DEBUG");
-       dbg = s ? atoi(s) : 0;
-       umask(UMASK);
-       log_flags = 0;
-
-       setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
-       setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
-       
-       while(++arg - argv < argc) {
-           if (**arg == '-')
-               switch((*arg)[1]) {
-               case 'd':
-                   dbg =  atoi((*arg)[2]? *arg+2: *++arg);
-                   break;
-               }
-       }
-       set_com_err_hook(dcm_com_err_hook);
-       
-       /* if /etc/nodcm exists, punt quietly. */
-       if (!access(NODCMFILE, F_OK)) {
-               exit(1);
-       } 
-
-       if (status = mr_connect("")) {
-           com_err(whoami, status, " on mr_connect");
-           leave("connect failed");
-       }
-
-       if (status = mr_auth("dcm")) {
-           com_err(whoami, status, " on \"authenticate\"");
-           leave("auth failed");
-       }
-
-       /* if DCM is not enabled, exit after logging */
-       qargv[0] = "dcm_enable";
-       if (status = mr_query("get_value", 1, qargv, gqval, &i)) {
-           com_err(whoami, status, " check dcm_enable");
-           leave("query failed");
-       }
-       if (i == 0) {
-           errno = 0;
-           leave("dcm_enable not set");
-       } 
-
-       /* do it! */
-       do_services();
-       errno = 0;
-       leave("");
-}
-
-
-/* Used by the get_value query when checking for dcm_enable. */
-
-gqval(argc, argv, hint)
-int argc;
-char **argv;
-int *hint;
-{
-    *hint = atoi(argv[0]);
-    return(UPCALL_STOP);
-}
-
-
-/* Used by qualified_get_server to make a list of servers to check */
-
-qgetsv(argc, argv, sq)
-int argc;
-char **argv;
-struct save_queue *sq;
-{
-    sq_save_data(sq, strsave(argv[0]));
-    return(UPCALL_CONT);
-}
-
-
-/* Used by get_server_info to record all of the returned information */
-
-getsvinfo(argc, argv, sserv)
-int argc;
-char **argv;
-struct service *sserv;
-{
-    sserv->service = strsave(argv[0]);
-    sserv->interval = atoi(argv[1]);
-    sserv->target = strsave(argv[2]);
-    sserv->script = strsave(argv[3]);
-    sserv->dfgen = atoi(argv[4]);
-    sserv->dfcheck = atoi(argv[5]);
-    sserv->type = strsave(argv[6]);
-    sserv->enable = atoi(argv[7]);
-    sserv->inprogress = atoi(argv[8]);
-    sserv->harderror = atoi(argv[9]);
-    sserv->errmsg = strsave(argv[10]);
-    return(UPCALL_STOP);
-}
-
-
-/* Scan the services and process any that need it. */
-
-do_services()
-{
-    char *qargv[6];
-    struct save_queue *sq, *sq_create();
-    char *service, dfgen_prog[64], dfgen_cmd[128];
-    struct service svc;
-    int status, lock_fd, ex, (*cstat)();
-    struct timezone tz;
-    register char *p;
-    int waits;
-    struct sigaction action, prevaction;
-
-    if (dbg & DBG_VERBOSE)
-       com_err(whoami, 0, "starting pass over services");
-
-    qargv[0] = "true";
-    qargv[1] = "dontcare";
-    qargv[2] = "false";
-    sq = sq_create();
-    if (status = mr_query("qualified_get_server", 3, qargv, qgetsv, sq)) {
-       com_err(whoami, status, " getting services");
-       leave("query failed");
-    }
-    while (sq_get_data(sq, &service)) {
-       for (p = service; *p; p++)
-         if (isupper(*p))
-           *p = tolower(*p);
-       com_err(whoami, 0, "checking %s...", service);
-       qargv[0] = service;
-       sprintf(dfgen_prog, "%s/%s.gen", BIN_DIR, service);
-       if (!file_exists(dfgen_prog)) {
-           com_err(whoami, 0, "prog %s doesn't exist\n", dfgen_prog);
-           free(service);
-           continue;
-       }
-       sprintf(dfgen_cmd, "exec %s %s/%s.out",
-               dfgen_prog, DCM_DIR, service);
-       gettimeofday(&tv, &tz);
-       if (status = mr_query("get_server_info", 1, qargv, getsvinfo, &svc)) {
-           com_err(whoami, status, " getting service %s info, skipping to next service", service);
-           continue;
-       }
-       svc.service = strsave(service);
-       qargv[0] = strsave(service);
-       qargv[1] = itoa(svc.dfgen);
-       qargv[2] = itoa(svc.dfcheck);
-       qargv[3] = strsave("0");
-       qargv[4] = itoa(svc.harderror);
-       qargv[5] = strsave(svc.errmsg);
-       if (svc.interval != 0) {
-           if (svc.interval * 60 + svc.dfcheck < tv.tv_sec) {
-               lock_fd = maybe_lock_update("@db@", service, 1);
-               if (lock_fd < 0)
-                 goto free_service;
-               free(qargv[3]);
-               free(qargv[4]);
-               free(qargv[5]);
-               qargv[3] = strsave("1");
-               qargv[4] = strsave("0");
-               qargv[5] = strsave("");
-               status = mr_query("set_server_internal_flags", 6,
-                                 qargv, scream, NULL);
-               if (status != MR_SUCCESS) {
-                   com_err(whoami, status, " setting server state");
-                   goto free_service;
-               }
-           
-               com_err(whoami, status, " running %s", dfgen_prog);
-
-               action.sa_flags = 0;
-               sigemptyset(&action.sa_mask);
-               action.sa_handler = SIG_DFL;
-               sigaction(SIGCHLD, &action, &prevaction);
-               waits = system(dfgen_cmd);
-               sigaction(SIGCHLD, &prevaction, NULL);
-               if (WIFSIGNALED(waits)) {
-                   status = MR_COREDUMP;
-                   com_err(whoami, status, " %s exited on signal %d",
-                           dfgen_prog, WTERMSIG(waits));
-               } else if (WEXITSTATUS(waits)) {
-                   /* extract the process's exit value */
-                   status = WEXITSTATUS(waits) + ERROR_TABLE_BASE_sms;
-                   com_err(whoami, status, " %s exited", dfgen_prog);
-               }
-
-               if (SOFT_FAIL(status)) {
-                   free(qargv[5]);
-                   qargv[5] = strsave(error_message(status));
-               } else if (status == MR_NO_CHANGE) {
-                   free(qargv[2]);
-                   qargv[2] = itoa(tv.tv_sec);
-                   svc.dfcheck = tv.tv_sec;
-               } else if (status == MR_SUCCESS) {
-                   free(qargv[1]);
-                   free(qargv[2]);
-                   qargv[1] = itoa(tv.tv_sec);
-                   qargv[2] = strsave(qargv[1]);
-                   svc.dfcheck = svc.dfgen = tv.tv_sec;
-               } else { /* HARD_FAIL(status) */
-                   free(qargv[2]);
-                   free(qargv[4]);
-                   free(qargv[5]);
-                   qargv[2] = itoa(tv.tv_sec); 
-                   svc.dfcheck = tv.tv_sec;
-                   qargv[4] = itoa(status);
-                   qargv[5] = strsave(error_message(status));
-                   critical_alert("DCM","DCM building config files for %s: %s",
-                                 service, qargv[5]);
-               }
-           free_service:
-               free(qargv[3]);
-               qargv[3] = strsave("0");
-               status = mr_query("set_server_internal_flags", 6,
-                                 qargv, scream, NULL);
-               if (status)
-                 com_err(whoami, status, " setting service state");
-               close(lock_fd);
-               free(qargv[0]);
-               free(qargv[1]);
-               free(qargv[2]);
-               free(qargv[3]);
-               free(qargv[4]);
-               free(qargv[5]);
-           }
-           if (!strcmp(svc.type, "REPLICAT"))
-             ex = 1;
-           else
-             ex = 0;
-           lock_fd = maybe_lock_update("@db@", service, ex);
-           if (lock_fd >= 0) {
-               do_hosts(&svc);
-               close(lock_fd);
-           }
-       }
-       free(svc.service);
-       free(svc.target);
-       free(svc.script);
-       free(svc.type);
-       free(svc.errmsg);
-       free(service);
-    }
-    sq_destroy(sq);
-}
-
-
-/* Used by qualified_get_server_host to make a list of hosts to check */
-
-qgethost(argc, argv, sq)
-int argc;
-char **argv;
-struct save_queue *sq;
-{
-    sq_save_data(sq, strsave(argv[1]));
-    return(UPCALL_CONT);
-}
-
-
-/* Used by get_server_host_info to store all of the info about a host */
-
-gethostinfo(argc, argv, shost)
-int argc;
-char **argv;
-struct svrhost *shost;
-{
-    shost->service = strsave(argv[0]);
-    shost->machine = strsave(argv[1]);
-    shost->enable = atoi(argv[2]);
-    shost->override = atoi(argv[3]);
-    shost->success = atoi(argv[4]);
-    shost->inprogress = atoi(argv[5]);
-    shost->hosterror = atoi(argv[6]);
-    shost->errmsg = strsave(argv[7]);
-    shost->lasttry = atoi(argv[8]);
-    shost->lastsuccess = atoi(argv[9]);
-    shost->value1 = atoi(argv[10]);
-    shost->value2 = atoi(argv[11]);
-    shost->value3 = strsave(argv[12]);
-    return(UPCALL_STOP);
-}
-
-
-/* Scans all of the hosts for a particular service, and processes them. */
-
-do_hosts(svc)
-struct service *svc;
-{
-    char *argv[9], *machine;
-    int status, lock_fd;
-    struct save_queue *sq;
-    struct svrhost shost;
-
-    sq = sq_create();
-    argv[0] = svc->service;
-    argv[1] = "TRUE";
-    argv[2] = argv[3] = argv[4] = "DONTCARE";
-    argv[5] = "FALSE";
-    status = mr_query("qualified_get_server_host", 6, argv, qgethost, sq);
-    if (status == MR_NO_MATCH) {
-       return;
-    } else if (status) {
-       com_err(whoami, status, " getting server_hosts for  %s", svc->service);
-       return;
-    }
-    while (sq_get_data(sq, &machine)) {
-       if (dbg & DBG_TRACE)
-         com_err(whoami, 0, "checking %s...", machine);
-       argv[1] = machine;
-       status = mr_query("get_server_host_info", 2, argv,
-                         gethostinfo, &shost);
-       if (status) {
-           com_err(whoami,status, " getting server_host_info for %s", machine);
-           goto free_mach;
-       }
-       if (!shost.enable || shost.hosterror ||
-           (shost.success && !shost.override &&
-            shost.lastsuccess >= svc->dfgen)) {
-           if (dbg & DBG_TRACE)
-             com_err(whoami, 0, "not updating %s:%s", svc->service, machine);
-           goto free_mach;
-       }
-
-       lock_fd = maybe_lock_update(machine, svc->service, 1);
-       if (lock_fd < 0)
-         goto free_mach;
-       argv[0] = svc->service;
-       argv[1] = machine;
-       argv[2] = argv[3] = argv[5] = "0";
-       argv[4] = "1";
-       argv[6] = strsave("");
-       argv[7] = itoa(tv.tv_sec);
-       argv[8] = itoa(shost.lastsuccess);
-       status = mr_query("set_server_host_internal", 9, argv, scream, NULL);
-       if (status != MR_SUCCESS) {
-           com_err(whoami,status," while setting internal state for %s:%s",
-                   svc->service, machine);
-           goto free_mach;
-       }
-       status = mr_update_server(svc->service, machine, svc->target,
-                                  svc->script);
-       if (status == MR_SUCCESS) {
-           argv[2] = argv[4] = "0";
-           argv[3] = "1";
-           free(argv[8]);
-           argv[8] = itoa(tv.tv_sec);
-       } else if (SOFT_FAIL(status)) {
-           argv[4] = "0";
-           free(argv[6]);
-           argv[6] = strsave(error_message(status));
-       } else { /* HARD_FAIL */
-           argv[2] = itoa(shost.override);
-           argv[4] = "0";
-           argv[5] = itoa(status);
-           free(argv[6]);
-           argv[6] = strsave(error_message(status));
-           critical_alert("DCM", "DCM updating %s:%s: %s",
-                          machine, svc->service, argv[6]);
-           if (!strcmp(svc->type, "REPLICAT")) {
-               char *qargv[6];
-
-               svc->harderror = status;
-               svc->errmsg = strsave(argv[6]);
-               qargv[0] = strsave(svc->service);
-               qargv[1] = itoa(svc->dfgen);
-               qargv[2] = itoa(svc->dfcheck);
-               qargv[3] = strsave("0");
-               qargv[4] = itoa(svc->harderror);
-               qargv[5] = strsave(svc->errmsg);
-               status = mr_query("set_server_internal_flags",
-                                 6, qargv, scream, NULL);
-               if (status)
-                 com_err(whoami, status, " setting service state again");
-               free(qargv[0]);
-               free(qargv[1]);
-               free(qargv[2]);
-               free(qargv[3]);
-               free(qargv[4]);
-               free(qargv[5]);
-               close(lock_fd);
-               status = mr_query("set_server_host_internal",
-                                 9, argv,scream,NULL);
-               free(argv[2]);
-               free(argv[5]);
-               if (status)
-                 com_err(whoami, status, " setting host state again");
-               return(-1);
-           }
-       }
-       close(lock_fd);
-       status = mr_query("set_server_host_internal", 9, argv, scream, NULL);
-       if (status)
-         com_err(whoami, status, " setting host state again");
-/*     free(argv[2]);
-       free(argv[5]); */
-    free_mach:
-       free(machine);
-       close(lock_fd);
-    }
-    return(0);
-}
diff --git a/dcm/dcm.pc b/dcm/dcm.pc
new file mode 100644 (file)
index 0000000..17bf2c4
--- /dev/null
@@ -0,0 +1,382 @@
+/*
+ * The Data Control Manager for MOIRA.
+ *
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, see the file
+ * "mit-copyright.h".
+ *
+ * $Source$
+ * $Author$
+ * $Header$
+ */
+
+#ifndef lint
+static char rcsid_dcm_c[] = "$Header$";
+#endif lint
+
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/wait.h>
+
+#include <com_err.h>
+#include <gdb.h>
+#include <moira.h>
+#include <moira_site.h>
+
+EXEC SQL INCLUDE sqlca;
+EXEC SQL WHENEVER SQLERROR DO dbmserr();
+
+#define SQL_NO_MATCH 1403
+#define SOFT_FAIL(x)   (((x) == MR_NO_MEM) || ((x) == MR_CANT_CONNECT) || ((x) == MR_CCONFIG) || ((x) == MR_DEADLOCK) || ((x) == MR_BUSY) || ((x) == MR_ABORT))
+
+char whobuf[256], *whoami=whobuf, *db="moira";
+extern CONNECTION conn;
+
+int main(argc, argv)
+int argc;
+char *argv[];
+{
+    int i;
+    EXEC SQL BEGIN DECLARE SECTION;
+    char buf[16], *name;
+    int enable;
+    EXEC SQL END DECLARE SECTION;
+    struct save_queue *sq;
+    int status;
+    
+    if (strchr(argv[0], '/')) strcpy(whoami, strrchr(argv[0], '/')+1);
+    else strcpy(whoami, argv[0]);
+    umask(7);
+    
+    setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
+    setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
+    
+    initialize_sms_error_table();
+    initialize_krb_error_table();
+
+    /* if services were specified on the command line, do just those ones */
+    if (argc > 1) {
+       for (i = 1; i < argc; i++) {
+           if (generate_service(argv[i], 1))
+               do_hosts(argv[i]);
+       }
+       exit(0);
+    }
+
+    /* if DCM is not enabled, exit after logging */
+    if (!access(NODCMFILE, F_OK)) {
+       printf("/etc/nodcm exists -- exiting\n");
+       exit(1);
+    }
+    
+    EXEC SQL CONNECT :db IDENTIFIED BY :db;
+
+    EXEC SQL SELECT value INTO :enable FROM numvalues
+       WHERE name='dcm_enable';
+    if (enable == 0) {
+       printf("dcm_enable not set -- exiting\n");
+       exit(1);
+    }
+    
+    /* fetch list of services */
+    EXEC SQL DECLARE csr_svc CURSOR FOR SELECT LOWER(name) FROM servers
+       WHERE enable=1 AND harderror=0 AND update_int>0;
+    EXEC SQL OPEN csr_svc;
+    sq = sq_create();
+    while(1) {
+       EXEC SQL FETCH csr_svc INTO :buf;
+       if (sqlca.sqlcode) break;
+
+       sq_save_data(sq, strdup(strtrim(buf)));
+    }
+    EXEC SQL CLOSE csr_svc;
+    /* we will repeatedly open and close the db since it seems to get
+       upset if you keep it open across a fork */
+    EXEC SQL COMMIT RELEASE;
+
+    /* Now run through list */
+    while (sq_get_data(sq, &name)) {
+       if (generate_service(name, 0)) {
+           switch (fork()) {
+               case -1:
+                   fprintf(stderr,
+                           "dcm: could not fork to for service %s -- exiting",
+                           name);
+                   exit(1);
+               case 0:
+                   sprintf(strchr(whoami, '\0'), " (%s)", name);
+                   do_hosts(name);
+                   com_err(whoami, 0, "exiting");
+                   exit(0);
+               default:
+                   break;
+           }
+       }
+    }
+    
+    /* wait for children */
+    while (waitpid(0, &status, 0) > 0) ;
+    com_err(whoami, 0, "exiting");
+}
+
+int generate_service(char *name, int force)
+{
+    EXEC SQL BEGIN DECLARE SECTION;
+    int interval, dfcheck, status;
+    time_t now;
+    char *errmsg;
+    EXEC SQL END DECLARE SECTION;
+    char dfgen_prog[64], dfgen_cmd[128];
+    struct sigaction action, prevaction;
+    int waits;
+
+    EXEC SQL CONNECT :db IDENTIFIED BY :db;
+
+    EXEC SQL SELECT update_int, dfcheck        INTO :interval, :dfcheck
+       FROM servers WHERE name=UPPER(:name);
+    if (sqlca.sqlcode == SQL_NO_MATCH) {
+       com_err(whoami, 0, "No such service `%s'", name);
+       EXEC SQL COMMIT RELEASE;
+       return 0;
+    }
+    
+    time(&now);
+    
+    if ((interval * 60 + dfcheck < now) || force) {
+       sprintf(dfgen_prog, "%s/%s.gen", BIN_DIR, name);
+       if (access(dfgen_prog, F_OK) != 0) {
+           com_err(whoami, 0, "prog %s doesn't exist", dfgen_prog);
+           EXEC SQL COMMIT RELEASE;
+           return 0;
+       }
+       sprintf(dfgen_cmd, "exec %s %s/%s.out", dfgen_prog, DCM_DIR, name);
+       com_err(whoami, 0, "running %s", dfgen_prog);
+
+       EXEC SQL UPDATE servers SET inprogress=1
+           WHERE name=UPPER(:name);
+       
+       action.sa_flags = 0;
+       sigemptyset(&action.sa_mask);
+       action.sa_handler = SIG_DFL;
+       sigaction(SIGCHLD, &action, &prevaction);
+       waits = system(dfgen_cmd);
+       sigaction(SIGCHLD, &prevaction, NULL);
+       if (WIFSIGNALED(waits)) {
+           status = MR_COREDUMP;
+           com_err(whoami, status, " %s exited on signal %d",
+                   dfgen_prog, WTERMSIG(waits));
+       } else if (WEXITSTATUS(waits)) {
+           /* extract the process's exit value */
+           status = WEXITSTATUS(waits) + ERROR_TABLE_BASE_sms;
+           if (status != MR_NO_CHANGE)
+               com_err(whoami, status, "in %s", dfgen_prog);
+       } else status = MR_SUCCESS;
+       
+       if (status == MR_SUCCESS) {
+           EXEC SQL UPDATE servers SET dfgen = :now, dfcheck = :now,
+               inprogress = 0 WHERE name=UPPER(:name);
+           EXEC SQL COMMIT RELEASE;
+           return 1;
+       } else if (status == MR_NO_CHANGE) {
+           EXEC SQL UPDATE servers SET dfcheck = :now, inprogress = 0
+               WHERE name=UPPER(:name);
+       } else if (SOFT_FAIL(status)) {
+           errmsg = error_message(status);
+           EXEC SQL UPDATE servers SET errmsg = :errmsg, inprogress = 0
+               WHERE name=UPPER(:name);
+       } else { /* HARD_FAIL(status) */
+           errmsg = error_message(status);
+           EXEC SQL UPDATE servers SET dfcheck = :now, harderror = :status,
+               errmsg = :errmsg, inprogress = 0 WHERE name=UPPER(:name);
+#if 0
+           critical_alert("DCM","DCM building config files for %s: %s",
+                          name, errmsg);
+#endif
+       }
+    }
+    EXEC SQL COMMIT RELEASE;
+    return 0;
+}
+
+void do_hosts(char *service)
+{
+    EXEC SQL BEGIN DECLARE SECTION;
+    char type[16], host[73], target[64], script[128], *errmsg;
+    int status = 0, mid, dfgen, replicated;
+    time_t now;
+    EXEC SQL END DECLARE SECTION;
+
+    time(&now);
+    gdb_init();
+
+    EXEC SQL CONNECT :db IDENTIFIED BY :db;
+
+    EXEC SQL SELECT dfgen, type, target_file, script
+       INTO :dfgen, :type, :target, :script
+       FROM servers WHERE name=UPPER(:service);
+    replicated = !strncmp(type, "REPLICAT", 8);
+
+    EXEC SQL DECLARE csr_hst1 CURSOR FOR
+       SELECT m.name FROM machine m, serverhosts sh
+       WHERE sh.service=UPPER(:service) AND sh.enable=1 AND sh.hosterror=0
+       AND sh.lts<:dfgen AND sh.mach_id=m.mach_id
+       FOR UPDATE OF sh.inprogress, sh.hosterror, sh.hosterrmsg;
+    EXEC SQL OPEN csr_hst1;
+
+    while (1) {
+       EXEC SQL FETCH csr_hst1 INTO :host;
+       if (sqlca.sqlcode == SQL_NO_MATCH) break;
+
+       com_err(whoami, 0, "sending %s data to %s", service, strtrim(host));
+       EXEC SQL UPDATE serverhosts SET inprogress = 1
+           WHERE CURRENT OF csr_hst1;
+       status = dcm_send_file(service, host, strtrim(target));
+       if (status) {
+           errmsg = error_message(status);
+           EXEC SQL UPDATE serverhosts SET hosterrmsg = :errmsg,
+               inprogress = 0 WHERE CURRENT OF csr_hst1;
+           if (!SOFT_FAIL(status)) {
+               EXEC SQL UPDATE serverhosts SET hosterror = :status
+                   WHERE CURRENT OF csr_hst1;
+#if 0
+               critical_alert("DCM", "DCM updating %s:%s: %s",
+                              service, host, errmsg);
+#endif
+           }
+           
+           if (replicated) break;
+       }
+    }
+    EXEC SQL CLOSE csr_hst1;
+
+    if (status == MR_SUCCESS || !replicated) {
+       EXEC SQL DECLARE csr_hst2 CURSOR FOR
+           SELECT m.name FROM machine m, serverhosts sh
+           WHERE sh.service=UPPER(:service) AND sh.inprogress=1
+           AND sh.mach_id=m.mach_id
+           FOR UPDATE OF sh.hosterror, sh.hosterrmsg, sh.inprogress;
+       EXEC SQL OPEN csr_hst2;
+
+       while (1) {
+           EXEC SQL FETCH csr_hst2 INTO :host;
+           if (sqlca.sqlcode == SQL_NO_MATCH) break;
+           
+           com_err(whoami, 0, "executing instructions on %s", strtrim(host));
+           status = dcm_execute(service, host, strtrim(script));
+           if (status) {
+               errmsg = error_message(status);
+               EXEC SQL UPDATE serverhosts SET hosterrmsg = :errmsg,
+                   inprogress = 0 WHERE CURRENT OF csr_hst2;
+               if (!SOFT_FAIL(status)) {
+                   EXEC SQL UPDATE serverhosts SET hosterror = :status
+                       WHERE CURRENT OF csr_hst2;
+#if 0
+                   critical_alert("DCM", "DCM updating %s:%s: %s",
+                                  service, host, errmsg);
+#endif
+               }
+               
+               if (replicated) {
+                   /* We're giving up, so clear the inprogress flag on
+                      any hosts in this service we haven't gotten to yet */
+                   EXEC SQL UPDATE serverhosts SET inprogress = 0
+                       WHERE service=UPPER(:service);
+                   break;
+               }
+           } else {
+               EXEC SQL UPDATE serverhosts SET inprogress=0, lts=:now
+                   WHERE CURRENT OF csr_hst2;
+           }
+       }
+       EXEC SQL CLOSE csr_hst2;
+    }
+
+    if (status && replicated) {
+       EXEC SQL UPDATE servers SET harderror = :status, errmsg = :errmsg
+           WHERE name = UPPER(:service);
+    }
+
+    EXEC SQL COMMIT RELEASE;
+}
+
+int dcm_send_file(char *service, char *host, char *target)
+{
+    char addr[256], data[MAXPATHLEN];
+    int code;
+
+    sprintf(addr, "%s:moira_update", host);
+    conn = start_server_connection(addr, "");
+    if (!conn || (connection_status(conn) == CON_STOPPED)) {
+       com_err(whoami, connection_errno(conn), "can't connect to %s", addr);
+       return MR_CANT_CONNECT;
+    }
+
+    code = send_auth(host);
+    if (code) {
+       com_err(whoami, code, "authenticating to %s", host);
+       goto done;
+    }
+
+    sprintf(data, "%s/%s.out", DCM_DIR, service);
+    code = send_file(data, target, 1);
+    if (code == MR_UNKNOWN_PROC) code = send_file(data, target, 0);
+    if (code) com_err(whoami, code, "sending data to %s", host);
+
+done:
+    send_quit();
+    sever_connection(conn);
+    return(code);
+}
+
+int dcm_execute(char *service, char *host, char *script)
+{
+    char addr[256], inst[MAXPATHLEN];
+    int code;
+
+    sprintf(addr, "%s:moira_update", host);
+    conn = start_server_connection(addr, "");
+    if (!conn || (connection_status(conn) == CON_STOPPED)) {
+       com_err(whoami, connection_errno(conn), "can't connect to %s", addr);
+       return MR_CANT_CONNECT;
+    }
+
+    code = send_auth(host);
+    if (code) {
+       com_err(whoami, code, "authenticating to %s", host);
+       goto done;
+    }
+
+    sprintf(inst, "/tmp/moira-update.XXXXXX");
+    mktemp(inst);
+    code = send_file(script, inst, 0);
+    if (code) {
+       com_err(whoami, code, "sending instructions to %s", host);
+       goto done;
+    }
+
+    code = execute(inst);
+    if (code) com_err(whoami, code, "executing instructions on %s", host);
+
+done:
+    send_quit();
+    sever_connection(conn);
+    return(code);
+}    
+
+void dbmserr(void)
+{
+    EXEC SQL BEGIN DECLARE SECTION; 
+    char err_msg[256];
+    EXEC SQL END DECLARE SECTION;
+    int bufsize=256, msglength=0;
+
+    sqlglm(err_msg, &bufsize, &msglength);
+    err_msg[msglength]=0;
+    com_err(whoami, 0, "Encountered SQL error:\n%s", err_msg);
+    com_err(whoami, 0, "exiting");
+    exit(1);
+}
diff --git a/dcm/utils.c b/dcm/utils.c
deleted file mode 100644 (file)
index c0c4501..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- *     $Source$
- *     $Author$
- *     $Header$
- *
- * 
- *     Utility functions used by the DCM.
- *
- *  (c) Copyright 1987, 1988 by the Massachusetts Institute of Technology.
- *  For copying and distribution information, please see the file
- *  <mit-copyright.h>.
- */
-
-#ifndef lint
-static char *rcsid_utils_c = "$Header$";
-#endif lint
-
-#include <mit-copyright.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <varargs.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <moira.h>
-#include <moira_site.h>
-#include "dcm.h"
-
-
-int dbg = 0;
-int log_flags;
-
-extern char *strsave();
-
-void dcm_com_err_hook(whoami, code, fmt, pvar)
-       char *whoami;
-       int code;
-       char *fmt;
-       caddr_t pvar;
-{
-       if (whoami) {
-               fputs(whoami, stderr);
-               fputs(": ", stderr);
-       }
-       if (code) {
-               fputs(error_message(code), stderr);
-       }
-       if (fmt) {
-               _doprnt(fmt, pvar, stderr);
-       }
-       putc('\n', stderr);
-       fflush(stderr);
-}
-               
-void leave(s)
-char *s;
-{
-    extern int errno;
-
-    if (*s)
-      com_err(whoami, errno, "%s: exiting", s);
-    else
-      com_err(whoami, errno, "exiting");
-
-    exit(errno);
-}
-
-void scream(argc, argv, hint)
-int argc;
-char **argv;
-int hint;
-{
-    leave("Programmer botch");
-}
-
-
-char *itoa(i)
-int i;
-{
-    char buf[20];
-
-    sprintf(buf, "%d", i);
-    return(strsave(buf));
-}
-
-
-char *tkt_string()
-{
-    return("/tmp/tkt_dcm");
-}
-
-
-int maybe_lock_update(host, service, exclusive)
-char *host, *service;
-int exclusive;
-{
-    char lock[BUFSIZ];
-    int fd;
-    flock_t fl;
-
-    sprintf(lock, "%s/%s.%s", LOCK_DIR, host, service);
-    fl.l_type = exclusive ? F_WRLCK : F_RDLCK;
-    fl.l_whence = fl.l_start = fl.l_len = 0;
-    if ((fd = open(lock, O_TRUNC |  O_CREAT | O_RDWR, 0)) < 0)
-      com_err(whoami, errno, ": maybe_lock_update: opening %s", lock);
-    else if (fcntl(fd, F_SETLK, &fl) != 0) {
-       if (errno != EAGAIN) 
-         com_err(whoami, errno, ": maybe_lock_update: flock");
-       else if (dbg & DBG_VERBOSE)
-         com_err(whoami, 0, "%s already locked\n", lock);
-       close(fd);
-       return -1;
-    } else if (dbg & DBG_VERBOSE) 
-      com_err(whoami, 0, "%s now locked\n", lock);
-    return fd;
-}
This page took 0.072055 seconds and 5 git commands to generate.