]> andersk Git - moira.git/blobdiff - dcm/dcm.pc
fix bugs in previous commit
[moira.git] / dcm / dcm.pc
index e02103560b0683409bf196f22d3abbae73a9e54d..3024a1ca3247fd655bdb32ff601a4eb6af1a902b 100644 (file)
@@ -1,46 +1,50 @@
-/*
- * The Data Control Manager for MOIRA.
+/* $Id$
  *
- * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
- * For copying and distribution information, see the file
- * "mit-copyright.h".
+ * The Data Control Manager for Moira.
  *
- * $Source$
- * $Author$
- * $Header$
+ * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, see the file
+ * <mit-copyright.h>.
  */
 
-#ifndef lint
-static char rcsid_dcm_c[] = "$Header$";
-#endif lint
+#include <mit-copyright.h>
+#include <moira.h>
+#include <moira_site.h>
+#include <moira_schema.h>
+#include "update.h"
 
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <errno.h>
 #include <signal.h>
 #include <stdio.h>
+#include <stdlib.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();
+void sqlglm(char *, unsigned int *, unsigned int *);
+
+RCSID("$Header$");
+
+int generate_service(char *name, int force);
+void do_hosts(char *service);
+int dcm_send_file(char *service, char *host, char *target);
+int dcm_execute(char *service, char *host, char *script);
+void dbmserr(void);
 
 #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(int argc, char **argv)
 {
   int i;
   EXEC SQL BEGIN DECLARE SECTION;
-  char buf[16], *name;
+  char buf[SERVERS_NAME_SIZE], *name;
   int enable;
   EXEC SQL END DECLARE SECTION;
   struct save_queue *sq;
@@ -75,6 +79,8 @@ int main(int argc, char **argv)
       exit(1);
     }
 
+  EXEC SQL WHENEVER SQLERROR DO dbmserr();
+
   EXEC SQL CONNECT :db IDENTIFIED BY :db;
 
   EXEC SQL SELECT value INTO :enable FROM numvalues WHERE name = 'dcm_enable';
@@ -110,11 +116,11 @@ int main(int argc, char **argv)
          switch (fork())
            {
            case -1:
-             fprintf(stderr, "dcm: could not fork for service %s -- exiting",
+             com_err(whoami, errno, "forking for service %s -- exiting",
                      name);
              exit(1);
            case 0:
-             sprintf(strchr(whoami, '\0'), " (%s)", name);
+             sprintf(strchr(whoami, '\0'), " (%s:%ld)", name, (long)getpid());
              do_hosts(name);
              com_err(whoami, 0, "exiting");
              exit(0);
@@ -124,10 +130,11 @@ int main(int argc, char **argv)
        }
     }
 
-  /* wait for children */
+  com_err(whoami, 0, "All files generated. Waiting for children to exit");
   while (waitpid(0, &status, 0) > 0)
     ;
   com_err(whoami, 0, "exiting");
+  exit(0);
 }
 
 int generate_service(char *name, int force)
@@ -135,15 +142,15 @@ int generate_service(char *name, int force)
   EXEC SQL BEGIN DECLARE SECTION;
   int interval, dfcheck, status;
   time_t now;
-  char *errmsg;
+  const char *errmsg;
   EXEC SQL END DECLARE SECTION;
-  char dfgen_prog[64], dfgen_cmd[128];
+  char dfgen_prog[MAXPATHLEN], dfgen_cmd[2 * MAXPATHLEN];
   struct sigaction action, prevaction;
   int waits;
 
   EXEC SQL CONNECT :db IDENTIFIED BY :db;
 
-  EXEC SQL SELECT update_int, dfcheck  INTO :interval, :dfcheck
+  EXEC SQL SELECT update_int, dfcheck INTO :interval, :dfcheck
     FROM servers WHERE name = UPPER(:name);
   if (sqlca.sqlcode == SQL_NO_MATCH)
     {
@@ -166,8 +173,11 @@ int generate_service(char *name, int force)
       sprintf(dfgen_cmd, "exec %s %s/%s.out", dfgen_prog, DCM_DIR, name);
       com_err(whoami, 0, "running %s", dfgen_prog);
 
+      EXEC SQL WHENEVER SQLERROR GOTO gen_cleanup;
+
       EXEC SQL UPDATE servers SET inprogress = 1
        WHERE name = UPPER(:name);
+      EXEC SQL COMMIT;
 
       action.sa_flags = 0;
       sigemptyset(&action.sa_mask);
@@ -212,26 +222,35 @@ int generate_service(char *name, int force)
       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);
+         EXEC SQL UPDATE servers SET harderror = :status, errmsg = :errmsg,
+           inprogress = 0 WHERE name = UPPER(:name);
          critical_alert("DCM", "DCM building config files for %s: %s",
                         name, errmsg);
        }
     }
   EXEC SQL COMMIT RELEASE;
   return 0;
+
+gen_cleanup:
+  EXEC SQL WHENEVER SQLERROR DO dbmserr(); 
+  EXEC SQL UPDATE servers SET inprogress = 0, harderror = MR_INTERNAL,
+    errmsg = 'DBMS Internal Error' WHERE name = UPPER(:name);
+  dbmserr();
 }
 
 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;
+  char type[SERVERS_TYPE_SIZE], host[MACHINE_NAME_SIZE], *name;
+  char target[SERVERS_TARGET_FILE_SIZE], script[SERVERS_SCRIPT_SIZE];
+  const char *errmsg;
+  int status = 0, dfgen, replicated, mid;
   time_t now;
   EXEC SQL END DECLARE SECTION;
+  struct save_queue *sq;
 
   time(&now);
-  gdb_init();
+  mr_init();
 
   EXEC SQL CONNECT :db IDENTIFIED BY :db;
 
@@ -239,70 +258,93 @@ void do_hosts(char *service)
     INTO :dfgen, :type, :target, :script
     FROM servers WHERE name = UPPER(:service);
   replicated = !strncmp(type, "REPLICAT", 8);
+  strtrim(target);
+  strtrim(script);
 
   EXEC SQL DECLARE csr_hst1 CURSOR FOR
-    SELECT m.name FROM machine m, serverhosts sh
+    SELECT m.name, m.mach_id 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;
+    AND sh.lts < :dfgen AND sh.mach_id = m.mach_id;
   EXEC SQL OPEN csr_hst1;
-
+  sq = sq_create();
   while (1)
     {
-      EXEC SQL FETCH csr_hst1 INTO :host;
+      EXEC SQL FETCH csr_hst1 INTO :host, mid;
       if (sqlca.sqlcode == SQL_NO_MATCH)
        break;
 
-      com_err(whoami, 0, "sending %s data to %s", service, strtrim(host));
+      sq_save_data(sq, strdup(strtrim(host)));
+      sq_save_data(sq, (void *)mid);
+    }
+  EXEC SQL CLOSE csr_hst1;
+
+  EXEC SQL WHENEVER SQLERROR GOTO host_cleanup;
+  while (sq_get_data(sq, &name))
+    {
+      sq_get_data(sq, &mid);
+      com_err(whoami, 0, "sending %s data to %s", service, name);
       EXEC SQL UPDATE serverhosts SET inprogress = 1
-       WHERE CURRENT OF csr_hst1;
-      status = dcm_send_file(service, host, strtrim(target));
+       WHERE service = UPPER(:service) AND mach_id = :mid;
+      EXEC SQL COMMIT;
+      status = dcm_send_file(service, name, target);
       if (status)
        {
          errmsg = error_message(status);
          EXEC SQL UPDATE serverhosts SET hosterrmsg = :errmsg,
-           inprogress = 0 WHERE CURRENT OF csr_hst1;
+           inprogress = 0, success = 0, ltt = :now
+           WHERE service = UPPER(:service) AND mach_id = :mid;
          if (!SOFT_FAIL(status))
            {
              EXEC SQL UPDATE serverhosts SET hosterror = :status
-               WHERE CURRENT OF csr_hst1;
+               WHERE service = UPPER(:service) AND mach_id = :mid;
              critical_alert("DCM", "DCM updating %s:%s: %s",
-                            service, host, errmsg);
+                            service, name, errmsg);
            }
+         EXEC SQL COMMIT;
 
          if (replicated)
            break;
        }
     }
-  EXEC SQL CLOSE csr_hst1;
+  sq_destroy(sq);
 
   if (status == MR_SUCCESS || !replicated)
     {
       EXEC SQL DECLARE csr_hst2 CURSOR FOR
-       SELECT m.name FROM machine m, serverhosts sh
+       SELECT m.name, m.mach_id 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;
+       AND sh.mach_id = m.mach_id;
       EXEC SQL OPEN csr_hst2;
+      sq = sq_create();
 
       while (1)
        {
-         EXEC SQL FETCH csr_hst2 INTO :host;
+         EXEC SQL FETCH csr_hst2 INTO :host, :mid;
          if (sqlca.sqlcode == SQL_NO_MATCH)
            break;
 
-         com_err(whoami, 0, "executing instructions on %s", strtrim(host));
-         status = dcm_execute(service, host, strtrim(script));
+         sq_save_data(sq, strdup(strtrim(host)));
+         sq_save_data(sq, (void *)mid);
+       }
+      EXEC SQL CLOSE csr_hst2;
+
+      while (sq_get_data(sq, &name))
+       {
+         sq_get_data(sq, &mid);
+
+         com_err(whoami, 0, "executing instructions on %s", name);
+         status = dcm_execute(service, name, script);
          if (status)
            {
              errmsg = error_message(status);
              EXEC SQL UPDATE serverhosts SET hosterrmsg = :errmsg,
-               inprogress = 0 WHERE CURRENT OF csr_hst2;
+               inprogress = 0, success = 0, ltt = :now
+               WHERE service = UPPER(:service) AND mach_id = :mid;
              if (!SOFT_FAIL(status))
                {
                  EXEC SQL UPDATE serverhosts SET hosterror = :status
-                   WHERE CURRENT OF csr_hst2;
+                   WHERE service = UPPER(:service) AND mach_id = :mid;
                  critical_alert("DCM", "DCM updating %s:%s: %s",
                                 service, host, errmsg);
                }
@@ -318,13 +360,16 @@ void do_hosts(char *service)
            }
          else
            {
-             EXEC SQL UPDATE serverhosts SET inprogress = 0, lts = :now
-               WHERE CURRENT OF csr_hst2;
+             EXEC SQL UPDATE serverhosts SET inprogress = 0, ltt = :now,
+               lts = :now, success = 1 WHERE service = UPPER(:service)
+               AND mach_id = :mid;
            }
+         EXEC SQL COMMIT;
        }
       EXEC SQL CLOSE csr_hst2;
     }
 
+  EXEC SQL WHENEVER SQLERROR DO dbmserr();
   if (status && replicated)
     {
       EXEC SQL UPDATE servers SET harderror = :status, errmsg = :errmsg
@@ -332,22 +377,32 @@ void do_hosts(char *service)
     }
 
   EXEC SQL COMMIT RELEASE;
+  return;
+
+host_cleanup:
+  EXEC SQL UPDATE serverhosts SET inprogress = 0, success = 0, ltt = :now,
+    hosterror = MR_INTERNAL, hosterrmsg = 'DBMS Internal Error'
+    WHERE service = UPPER(:service) AND mach_id = :mid;
+  if (replicated)
+    {
+      EXEC SQL UPDATE servers SET harderror = MR_INTERNAL,
+       errmsg = 'DBMS Internal Error' WHERE name = UPPER(:service);
+    }
 }
 
 int dcm_send_file(char *service, char *host, char *target)
 {
-  char addr[256], data[MAXPATHLEN];
-  int code;
+  char data[MAXPATHLEN];
+  int code, conn;
 
-  sprintf(addr, "%s:moira_update", host);
-  conn = start_server_connection(addr, "");
-  if (!conn || (connection_status(conn) == CON_STOPPED))
+  conn = mr_connect_internal(host, "moira_update");
+  if (!conn)
     {
-      com_err(whoami, connection_errno(conn), "can't connect to %s", addr);
+      com_err(whoami, errno, "can't connect to %s", host);
       return MR_CANT_CONNECT;
     }
 
-  code = send_auth(host);
+  code = send_auth(conn, host);
   if (code)
     {
       com_err(whoami, code, "authenticating to %s", host);
@@ -355,32 +410,29 @@ int dcm_send_file(char *service, char *host, char *target)
     }
 
   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);
+  code = send_file(conn, data, target, 0);
   if (code)
     com_err(whoami, code, "sending data to %s", host);
 
 done:
-  send_quit();
-  sever_connection(conn);
+  send_quit(conn);
+  close(conn);
   return code;
 }
 
 int dcm_execute(char *service, char *host, char *script)
 {
-  char addr[256], inst[MAXPATHLEN];
-  int code;
+  char inst[MAXPATHLEN];
+  int code, conn;
 
-  sprintf(addr, "%s:moira_update", host);
-  conn = start_server_connection(addr, "");
-  if (!conn || (connection_status(conn) == CON_STOPPED))
+  conn = mr_connect_internal(host, "moira_update");
+  if (!conn)
     {
-      com_err(whoami, connection_errno(conn), "can't connect to %s", addr);
+      com_err(whoami, errno, "can't connect to %s", host);
       return MR_CANT_CONNECT;
     }
 
-  code = send_auth(host);
+  code = send_auth(conn, host);
   if (code)
     {
       com_err(whoami, code, "authenticating to %s", host);
@@ -389,20 +441,20 @@ int dcm_execute(char *service, char *host, char *script)
 
   sprintf(inst, "/tmp/moira-update.XXXXXX");
   mktemp(inst);
-  code = send_file(script, inst, 0);
+  code = send_file(conn, script, inst, 0);
   if (code)
     {
       com_err(whoami, code, "sending instructions to %s", host);
       goto done;
     }
 
-  code = execute(inst);
+  code = execute(conn, inst);
   if (code)
     com_err(whoami, code, "executing instructions on %s", host);
 
 done:
-  send_quit();
-  sever_connection(conn);
+  send_quit(conn);
+  close(conn);
   return code;
 }
 
This page took 0.087383 seconds and 4 git commands to generate.