]> git.sur5r.net Git - bacula/bacula/commitdiff
Add support for director monitoring.
authorNicolas Boichat <nicolas@boichat.ch>
Sun, 22 Aug 2004 22:02:45 +0000 (22:02 +0000)
committerNicolas Boichat <nicolas@boichat.ch>
Sun, 22 Aug 2004 22:02:45 +0000 (22:02 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1551 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/dird/bacula-dir.conf.in
bacula/src/tray-monitor/authenticate.c
bacula/src/tray-monitor/tray-monitor.c
bacula/src/tray-monitor/tray-monitor.conf.in
bacula/src/tray-monitor/tray-monitor.h
bacula/src/tray-monitor/tray_conf.c
bacula/src/tray-monitor/tray_conf.h
bacula/src/wx-console/TODO

index ed9b17082b685a3dce87fdc023fa64aff57aac4f..9d2cf76d49b7dfa34299dff860d380eb5aaa7fad 100644 (file)
@@ -224,7 +224,7 @@ Pool {
 # Restricted console used by tray-monitor to get the status of the director
 #
 Console {
-  Name = Monitor
+  Name = @hostname@-mon
   Password = "@mon_dir_password@"
   CommandACL = status, .status
   ClientACL = 
index acec72f5563c17f4cef5803813b8496cfafac3bc..44f5a6f82a92ddbdc5b6391976df232b272e73b7 100644 (file)
 void senditf(const char *fmt, ...);
 void sendit(const char *buf); 
 
+/* Commands sent to Director */
+static char DIRhello[]    = "Hello %s calling\n";
+
+/* Response from Director */
+static char DIROKhello[]   = "1000 OK:";
+
 /* Commands sent to Storage daemon and File daemon and received
  *  from the User Agent */
-static char hello[]    = "Hello Director %s calling\n";
+static char SDFDhello[]    = "Hello Director %s calling\n";
 
 /* Response from SD */
-static char OKhello[]   = "3000 OK Hello\n";
+static char SDOKhello[]   = "3000 OK Hello\n";
 /* Response from FD */
 static char FDOKhello[] = "2000 OK Hello\n";
 
 /* Forward referenced functions */
 
+/*
+ * Authenticate Director
+ */
+int authenticate_director(JCR *jcr, MONITOR *mon, DIRRES *director)
+{
+   BSOCK *dir = jcr->dir_bsock;
+   int ssl_need = BNET_SSL_NONE;
+   char bashed_name[MAX_NAME_LENGTH];
+   char *password;
+
+   bstrncpy(bashed_name, mon->hdr.name, sizeof(bashed_name));
+   bash_spaces(bashed_name);
+   password = mon->password;
+   
+   /* Timeout Hello after 5 mins */
+   btimer_t *tid = start_bsock_timer(dir, 60 * 5);
+   bnet_fsend(dir, DIRhello, bashed_name);
+
+   if (!cram_md5_get_auth(dir, password, ssl_need) || 
+       !cram_md5_auth(dir, password, ssl_need)) {
+      stop_bsock_timer(tid);
+      Jmsg0(jcr, M_FATAL, 0, _("Director authorization problem.\n"
+            "Most likely the passwords do not agree.\n"     
+       "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"));
+      return 0;
+   }
+
+   Dmsg1(6, ">dird: %s", dir->msg);
+   if (bnet_recv(dir) <= 0) {
+      stop_bsock_timer(tid);
+      Jmsg1(jcr, M_FATAL, 0, _("Bad response to Hello command: ERR=%s\n"),
+        bnet_strerror(dir));
+      return 0;
+   }
+   Dmsg1(10, "<dird: %s", dir->msg);
+   stop_bsock_timer(tid);
+   if (strncmp(dir->msg, DIROKhello, sizeof(DIROKhello)-1) != 0) {
+      Jmsg0(jcr, M_FATAL, 0, _("Director rejected Hello command\n"));
+      return 0;
+   } else {
+      Jmsg0(jcr, M_FATAL, 0, dir->msg);
+   }
+   return 1;
+}
+
 /*
  * Authenticate Storage daemon connection
  */
@@ -63,7 +114,7 @@ int authenticate_storage_daemon(JCR *jcr, MONITOR *monitor, STORE* store)
    bash_spaces(dirname);
    /* Timeout Hello after 5 mins */
    btimer_t *tid = start_bsock_timer(sd, 60 * 5);
-   if (!bnet_fsend(sd, hello, dirname)) {
+   if (!bnet_fsend(sd, SDFDhello, dirname)) {
       stop_bsock_timer(tid);
       Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to Storage daemon. ERR=%s\n"), bnet_strerror(sd));
       return 0;
@@ -84,7 +135,7 @@ int authenticate_storage_daemon(JCR *jcr, MONITOR *monitor, STORE* store)
    }
    Dmsg1(110, "<stored: %s", sd->msg);
    stop_bsock_timer(tid);
-   if (strncmp(sd->msg, OKhello, sizeof(OKhello)) != 0) {
+   if (strncmp(sd->msg, SDOKhello, sizeof(SDOKhello)) != 0) {
       Jmsg0(jcr, M_FATAL, 0, _("Storage daemon rejected Hello command\n"));
       return 0;
    }
@@ -107,7 +158,7 @@ int authenticate_file_daemon(JCR *jcr, MONITOR *monitor, CLIENT* client)
    bash_spaces(dirname);
    /* Timeout Hello after 5 mins */
    btimer_t *tid = start_bsock_timer(fd, 60 * 5);
-   if (!bnet_fsend(fd, hello, dirname)) {
+   if (!bnet_fsend(fd, SDFDhello, dirname)) {
       stop_bsock_timer(tid);
       Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon. ERR=%s\n"), bnet_strerror(fd));
       return 0;
index 6241ebe76037b71d73883009c60844503fa5c69f..a405504cbe94d6ba3aa2a6909a07d7a2330a30e2 100644 (file)
@@ -39,6 +39,7 @@
 #include "warn.xpm"
 
 /* Imported functions */
+int authenticate_director(JCR *jcr, MONITOR *monitor, DIRRES *director);
 int authenticate_file_daemon(JCR *jcr, MONITOR *monitor, CLIENT* client);
 int authenticate_storage_daemon(JCR *jcr, MONITOR *monitor, STORE* store);
 
@@ -57,8 +58,8 @@ static int fullitem = -1; //Item to be display in detailled status window
 static int lastupdated = -1; //Last item updated
 static monitoritem items[32];
 
-/* Data received from FD/SD */
-static char OKqstatus[]   = "2000 OK .status\n";
+/* Data received from DIR/FD/SD */
+static char OKqstatus[]   = "%c000 OK .status\n";
 static char DotStatusJob[] = "JobId=%d JobStatus=%c JobErrors=%d\n";
 
 /* UI variables and functions */
@@ -136,6 +137,7 @@ int main(int argc, char *argv[])
 {
    int ch, i;
    bool test_config = false;
+   DIRRES* dird;
    CLIENT* filed;
    STORE* stored;
 
@@ -189,6 +191,13 @@ int main(int argc, char *argv[])
    
    LockRes();
    nitems = 0;
+   foreach_res(dird, R_DIRECTOR) {
+      items[nitems].type = R_DIRECTOR;
+      items[nitems].resource = dird;
+      items[nitems].D_sock = NULL;
+      items[nitems].state = warn;
+      nitems++;
+   }
    foreach_res(filed, R_CLIENT) {
       items[nitems].type = R_CLIENT;
       items[nitems].resource = filed;
@@ -287,6 +296,10 @@ Without that I don't how to get status from the File or Storage Daemon :-(\n"),
    GString *str;   
    for (int i = 0; i < nitems; i++) {
       switch (items[i].type) {
+      case R_DIRECTOR:
+         str = g_string_new(((DIRRES*)(items[i].resource))->hdr.name);
+         g_string_append(str, _(" (DIR)"));
+         break;
       case R_CLIENT:
          str = g_string_new(((CLIENT*)(items[i].resource))->hdr.name);
          g_string_append(str, _(" (FD)"));
@@ -304,10 +317,12 @@ Without that I don't how to get status from the File or Storage Daemon :-(\n"),
       items[i].image = gtk_image_new_from_pixbuf(pixbuf);
       
       items[i].label =  gtk_label_new(_("Unknown status."));
-      
+      GtkWidget* align = gtk_alignment_new(0.0, 0.5, 0.0, 1.0);
+      gtk_container_add(GTK_CONTAINER(align), items[i].label);
+            
       gtk_table_attach_defaults(GTK_TABLE(daemon_table), label, 0, 1, (i*2)+1, (i*2)+2);
       gtk_table_attach_defaults(GTK_TABLE(daemon_table), items[i].image, 1, 2, (i*2)+1, (i*2)+2);
-      gtk_table_attach_defaults(GTK_TABLE(daemon_table), items[i].label, 2, 3, (i*2)+1, (i*2)+2);
+      gtk_table_attach_defaults(GTK_TABLE(daemon_table), align, 2, 3, (i*2)+1, (i*2)+2);
    
       GtkWidget* separator = gtk_hseparator_new();
       gtk_table_attach_defaults(GTK_TABLE(daemon_table), separator, 0, 3, (i*2)+2, (i*2)+3);
@@ -390,6 +405,9 @@ static void TrayIconExit(unsigned int activateTime, unsigned int button) {
 
 static int authenticate_daemon(monitoritem* item, JCR *jcr) {
    switch (item->type) {
+   case R_DIRECTOR:
+      return authenticate_director(jcr, monitor, (DIRRES*)item->resource);
+      break;      
    case R_CLIENT:
       return authenticate_file_daemon(jcr, monitor, (CLIENT*)item->resource);
       break;
@@ -465,19 +483,26 @@ stateenum getstatus(monitoritem* item, int current, GString** str) {
    stateenum ret = error;
    int jobid = 0, joberrors = 0;
    char jobstatus = JS_ErrorTerminated;
+   char num;
    int k;
    
    *str = g_string_sized_new(128);
    
    if (current) {
-      docmd(&items[lastupdated], ".status current", &list);
+      if (item->type == R_DIRECTOR)
+         docmd(&items[lastupdated], ".status dir current", &list);
+      else
+         docmd(&items[lastupdated], ".status current", &list);
    }
    else {
-      docmd(&items[lastupdated], ".status last", &list);
+      if (item->type == R_DIRECTOR)
+         docmd(&items[lastupdated], ".status dir last", &list);
+      else
+         docmd(&items[lastupdated], ".status last", &list);
    }
 
    it = list->next;
-   if ((it == NULL) || (strcmp(((GString*)it->data)->str, OKqstatus) != 0)) {
+   if ((it == NULL) || (sscanf(((GString*)it->data)->str, OKqstatus, &num) != 1)) {
       g_string_append_printf(*str, ".status error : %s", (it == NULL) ? "" : ((GString*)it->data)->str);
       ret = error;
    }
@@ -556,10 +581,18 @@ int docmd(monitoritem* item, const char* command, GSList** list) {
    if (!item->D_sock) {
       memset(&jcr, 0, sizeof(jcr));
       
+      DIRRES* dird;
       CLIENT* filed;
       STORE* stored;
       
       switch (item->type) {
+      case R_DIRECTOR:
+         dird = (DIRRES*)item->resource;      
+         trayMessage("Connecting to Director %s:%d\n", dird->address, dird->DIRport);
+         changeStatusMessage(item, "Connecting to Director %s:%d", dird->address, dird->DIRport);
+         item->D_sock = bnet_connect(NULL, 0, 0, "Director daemon", dird->address, NULL, dird->DIRport, 0);
+         jcr.dir_bsock = item->D_sock;
+         break;
       case R_CLIENT:
          filed = (CLIENT*)item->resource;      
          trayMessage("Connecting to Client %s:%d\n", filed->address, filed->FDport);
@@ -575,7 +608,7 @@ int docmd(monitoritem* item, const char* command, GSList** list) {
          jcr.store_bsock = item->D_sock;
          break;
       default:
-         printf("Error, currentitem is not a Client or a Storage..\n");
+         printf("Error, currentitem is not a Client, a Storage or a Director..\n");
          gtk_main_quit();
          return 0;
       }
@@ -596,9 +629,26 @@ int docmd(monitoritem* item, const char* command, GSList** list) {
          item->D_sock = NULL;
          return 0;
       }
-   
-      trayMessage("Opened connection with File daemon.\n");
-      changeStatusMessage(item, "Opened connection with File daemon.");
+      
+      switch (item->type) {
+      case R_DIRECTOR:
+         trayMessage("Opened connection with Director daemon.\n");
+         changeStatusMessage(item, "Opened connection with Director daemon.");
+         break;
+      case R_CLIENT:
+         trayMessage("Opened connection with File daemon.\n");
+         changeStatusMessage(item, "Opened connection with File daemon.");
+         break;
+      case R_STORAGE:
+         trayMessage("Opened connection with Storage daemon.\n");
+         changeStatusMessage(item, "Opened connection with Storage daemon.");
+         break;
+      default:
+         printf("Error, currentitem is not a Client, a Storage or a Director..\n");
+         gtk_main_quit();
+         return 0;
+         break;
+      }
    }
       
    writecmd(item, command);
index 3c451666f24bb60cbec03a9da18f0e961f806185..bdf17307e974909abd178b52db295b0a95c62b42 100644 (file)
@@ -4,6 +4,7 @@
 
 Monitor {
   Name = @hostname@-mon
+  Password = "@mon_dir_password@"         # password for the Directors   
 }
    
 Client {
@@ -21,9 +22,7 @@ Storage {
 }
 
 Director {
-  ConsoleName = Monitor
   Name = @hostname@-dir
   DIRport = @dir_port@
   address = @hostname@
-  Password = "@mon_dir_password@"             # password for Director
 }
\ No newline at end of file
index 8a7c27f9dd8b7f3000cbb4425a3017ad7c7d1875..10bc312afa0f61d7c0639d29a528184816393184 100644 (file)
@@ -39,8 +39,8 @@ enum stateenum {
 };
 
 struct monitoritem {
-   rescode type; /* R_CLIENT or R_STORAGE */
-   void* resource; /* CLIENT* or STORE* */
+   rescode type; /* R_DIRECTOR, R_CLIENT or R_STORAGE */
+   void* resource; /* DIRRES*, CLIENT* or STORE* */
    BSOCK *D_sock;
    stateenum state;
    GtkWidget* image;
index 8d63a6685615ea875ae8dc51089ce3b30ad97df7..81e04c8c7a3165f8df51b3a0e4770c7213ddf41b 100644 (file)
@@ -71,15 +71,26 @@ int  res_all_size = sizeof(res_all);
 *
 *   name          handler     value                 code flags    default_value
 */
-static RES_ITEM dir_items[] = {
+static RES_ITEM mon_items[] = {
    {"name",        store_name,     ITEM(res_monitor.hdr.name), 0, ITEM_REQUIRED, 0},
    {"description", store_str,      ITEM(res_monitor.hdr.desc), 0, 0, 0},
    {"requiressl",  store_yesno,    ITEM(res_monitor.require_ssl), 1, ITEM_DEFAULT, 0},
+   {"password",    store_password, ITEM(res_monitor.password), 0, ITEM_REQUIRED, 0},
    {"fdconnecttimeout", store_time,ITEM(res_monitor.FDConnectTimeout), 0, ITEM_DEFAULT, 60 * 30},
    {"sdconnecttimeout", store_time,ITEM(res_monitor.SDConnectTimeout), 0, ITEM_DEFAULT, 60 * 30},
    {NULL, NULL, NULL, 0, 0, 0}
 };
 
+/*  Director's that we can contact */
+static RES_ITEM dir_items[] = {
+   {"name",        store_name,     ITEM(res_dir.hdr.name), 0, ITEM_REQUIRED, 0},
+   {"description", store_str,      ITEM(res_dir.hdr.desc), 0, 0, 0},
+   {"dirport",     store_int,      ITEM(res_dir.DIRport),  0, ITEM_DEFAULT, 9101},
+   {"address",     store_str,      ITEM(res_dir.address),  0, 0, 0},
+   {"enablessl",   store_yesno,    ITEM(res_dir.enable_ssl), 1, ITEM_DEFAULT, 0},
+   {NULL, NULL, NULL, 0, 0, 0} 
+};
+
 /* 
 *    Client or File daemon resource
 *
@@ -124,10 +135,11 @@ static RES_ITEM store_items[] = {
 *  name             items        rcode        res_head
 */
 RES_TABLE resources[] = {
-   {"monitor",      dir_items,    R_MONITOR},
-   {"client",        cli_items,   R_CLIENT},
-   {"storage",       store_items, R_STORAGE},
-   {NULL,           NULL,        0}
+   {"monitor",      mon_items,    R_MONITOR},
+   {"director",     dir_items,    R_DIRECTOR},
+   {"client",       cli_items,    R_CLIENT},
+   {"storage",      store_items,  R_STORAGE},
+   {NULL,           NULL,         0}
 };
 
 /* Dump contents of resource */
@@ -147,11 +159,15 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm
    }
    switch (type) {
    case R_MONITOR:
-      sendit(sock, "Director: name=%s FDtimeout=%s SDtimeout=%s\n", 
+      sendit(sock, "Monitor: name=%s FDtimeout=%s SDtimeout=%s\n", 
    reshdr->name, 
    edit_uint64(res->res_monitor.FDConnectTimeout, ed1),
    edit_uint64(res->res_monitor.SDConnectTimeout, ed2));
       break;
+   case R_DIRECTOR:
+      sendit(sock, "Director: name=%s address=%s FDport=%d\n",
+   res->res_dir.hdr.name, res->res_dir.address, res->res_dir.DIRport);
+      break;
    case R_CLIENT:
       sendit(sock, "Client: name=%s address=%s FDport=%d\n",
    res->res_client.hdr.name, res->res_client.address, res->res_client.FDport);
@@ -266,6 +282,7 @@ void save_resource(int type, RES_ITEM *items, int pass)
       case R_MONITOR:
       case R_CLIENT:
       case R_STORAGE:
+      case R_DIRECTOR:
          break;
       default:
          Emsg1(M_ERROR, 0, "Unknown resource type %d in save_resource.\n", type);
@@ -293,8 +310,11 @@ void save_resource(int type, RES_ITEM *items, int pass)
    case R_MONITOR:
       size = sizeof(MONITOR);
       break;
+   case R_DIRECTOR:
+      size = sizeof(DIRRES);
+      break;
    case R_CLIENT:
-      size =sizeof(CLIENT);
+      size = sizeof(CLIENT);
       break;
    case R_STORAGE:
       size = sizeof(STORE); 
index a4ff45d5e7900b773bf804837f4e3cb1396c0d4a..6e57878216bed6cc49099f57dabf085df4b49598 100644 (file)
@@ -34,6 +34,7 @@
  */
 enum rescode {
    R_MONITOR = 1001,
+   R_DIRECTOR,
    R_CLIENT,
    R_STORAGE,
    R_FIRST = R_MONITOR,
@@ -52,6 +53,14 @@ enum {
    R_BACKUP
 };
 
+/* Director */
+struct DIRRES {
+   RES   hdr;
+   int   DIRport;                     /* UA server port */
+   char *address;                     /* UA server address */
+   int enable_ssl;                    /* Use SSL */
+};
+
 /* 
  *   Tray Monitor Resource  
  *
@@ -60,6 +69,7 @@ struct MONITOR {
    RES   hdr;
    int require_ssl;                   /* Require SSL for all connections */
    MSGS *messages;                    /* Daemon message handler */
+   char *password;                    /* UA server password */
    utime_t FDConnectTimeout;          /* timeout for connect in seconds */
    utime_t SDConnectTimeout;          /* timeout in seconds */
 };
@@ -98,6 +108,7 @@ struct STORE {
  */
 union URES {
    MONITOR    res_monitor;
+   DIRRES     res_dir;
    CLIENT     res_client;
    STORE      res_store;
    RES        hdr;
index cce06f422a3e57d51385a24cfa1e8db8e75e6d79..8839f14d806fd4317b50fa05455fed79cf1c5cc0 100644 (file)
@@ -1,4 +1,14 @@
 general : Show nice messages boxes when errors occurs.
+
+general : Bug reported by Kern:
+  I tried loading my current backup into the restore window. It
+  consisted of something like 10 jobs and was pretty big.  It was all
+  loaded, I double clicked on a directory, which was then marked, then
+  I opened it and clicked on subdirectory to unmark it, and I saw the
+  X appear on the top directory with a small check, then I'm not sure if I
+  clicked again, but my whole OS froze -- at first I could still move the
+  mouse a bit (very slowly) then after 30 seconds *everything* was dead.
+  I had to do a power off to get my system back.
    
 wxbRestorePanel : list jobs and list jobid=# will probably crash if there
    is nothing to show (db error or empty table)