]> git.sur5r.net Git - bacula/bacula/commitdiff
Misc see kes-1.30a
authorKern Sibbald <kern@sibbald.com>
Sat, 3 May 2003 16:11:58 +0000 (16:11 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 3 May 2003 16:11:58 +0000 (16:11 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@483 91ce42f0-d328-0410-95d8-f526ca767f89

17 files changed:
bacula/kernstodo
bacula/scripts/btraceback.in
bacula/src/console.glade
bacula/src/dird/job.c
bacula/src/dird/protos.h
bacula/src/dird/ua.h
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_dotcmds.c
bacula/src/dird/ua_input.c
bacula/src/dird/ua_label.c
bacula/src/dird/ua_select.c
bacula/src/filed/backup.c
bacula/src/jcr.h
bacula/src/lib/bnet.c
bacula/src/lib/protos.h
bacula/src/lib/signal.c
bacula/src/version.h

index 40ec0450ace08831225b48a1d8336f0db5882414..e9224e573aed451831cef85d0a464e57a3423ad7 100644 (file)
@@ -20,6 +20,9 @@ For 1.30a release:
 - Test multiple simultaneous Volumes
 - Document FInclude ...
 
+- Test and implement get_pint and get_yesno.
+- Implement timeout in response() when it should come quickly.
+
 - Figure out how to use ssh or stunnel to protect Bacula communications.
 
 After 1.30:
index 8d29d9469ecb74c863657610a13a0305db19ae6a..bc9d87c67b427d5b7316a2b13816e65dd1c1d68f 100755 (executable)
@@ -8,8 +8,8 @@
 #  $1 = path to executable
 #  $2 = main pid of running program to be traced back.
 #
-
-gdb -quiet -batch -x @sbindir@/btraceback.gdb $1 $2 2>&1 | mail -s "Bacula traceback" @dump_email@
+gdb -quiet -batch -x @sbindir@/btraceback.gdb $1 $2 2>&1 \
+ | @sbindir@/smtp -h @smtp_host@ -s "Bacula traceback" @dump_email@
 
 # Below is some old code that did the traceback from a core
 #  dump. However, for some odd reason, core dumps are not
index 71a9eab4dc58a3a94a1bf2a5dbd863fdd013c058..84b6eec7532403987dc7d1c62c9fada01b01558c 100644 (file)
        <widget>
          <class>GtkLabel</class>
          <name>label107</name>
-         <width>70</width>
+         <width>78</width>
          <label>Storage:</label>
          <justify>GTK_JUSTIFY_CENTER</justify>
          <wrap>False</wrap>
        <widget>
          <class>GtkLabel</class>
          <name>label109</name>
-         <width>70</width>
+         <width>78</width>
          <label>Pool:</label>
          <justify>GTK_JUSTIFY_LEFT</justify>
          <wrap>False</wrap>
        <widget>
          <class>GtkLabel</class>
          <name>label111</name>
-         <width>70</width>
+         <width>78</width>
          <label>Volume Name:</label>
          <justify>GTK_JUSTIFY_LEFT</justify>
          <wrap>False</wrap>
-         <xalign>0.18</xalign>
+         <xalign>0.17</xalign>
          <yalign>0.5</yalign>
          <xpad>0</xpad>
          <ypad>0</ypad>
        </widget>
       </widget>
 
+      <widget>
+       <class>GtkHBox</class>
+       <name>hbox48</name>
+       <border_width>5</border_width>
+       <homogeneous>False</homogeneous>
+       <spacing>0</spacing>
+       <child>
+         <padding>0</padding>
+         <expand>True</expand>
+         <fill>True</fill>
+       </child>
+
+       <widget>
+         <class>GtkLabel</class>
+         <name>slot1</name>
+         <width>93</width>
+         <label>Slot:</label>
+         <justify>GTK_JUSTIFY_LEFT</justify>
+         <wrap>False</wrap>
+         <xalign>0.09</xalign>
+         <yalign>0.5</yalign>
+         <xpad>0</xpad>
+         <ypad>0</ypad>
+         <child>
+           <padding>0</padding>
+           <expand>False</expand>
+           <fill>True</fill>
+         </child>
+       </widget>
+
+       <widget>
+         <class>GtkSpinButton</class>
+         <name>label_slot</name>
+         <can_focus>True</can_focus>
+         <climb_rate>1</climb_rate>
+         <digits>0</digits>
+         <numeric>True</numeric>
+         <update_policy>GTK_UPDATE_ALWAYS</update_policy>
+         <snap>False</snap>
+         <wrap>False</wrap>
+         <value>0</value>
+         <lower>0</lower>
+         <upper>10000</upper>
+         <step>1</step>
+         <page>10</page>
+         <page_size>10</page_size>
+         <child>
+           <padding>0</padding>
+           <expand>True</expand>
+           <fill>True</fill>
+         </child>
+       </widget>
+
+       <widget>
+         <class>Placeholder</class>
+       </widget>
+      </widget>
+
       <widget>
        <class>GtkLabel</class>
        <name>label113</name>
index 4a73ac38953e8a2ad7a6b9b654d40148341dcee2..5da55395ea782b0de297bf9f88d470004417afd5 100644 (file)
@@ -359,6 +359,7 @@ wait:
       V(mutex);
       /* Try again */
    }
+   jcr->acquired_resource_locks = 1;
 #endif
    return 1;
 }
@@ -403,6 +404,9 @@ static void backoff_resource_locks(JCR *jcr, int count)
  */
 static void release_resource_locks(JCR *jcr)
 {
+   if (!jcr->acquired_resource_locks) {
+      return;                        /* Job canceled, no locks acquired */
+   }
 #ifdef USE_SEMAPHORE
    P(mutex);
    sem_unlock(&jcr->store->sem);
index 05ebb1d88fdec41924aecc6612e2d1ab2dc8d598..5f808e4bf66d5c74b0f7ddd34c938ff45f41d710 100644 (file)
@@ -88,6 +88,8 @@ void set_pool_dbr_defaults_in_media_dbr(MEDIA_DBR *mr, POOL_DBR *pr);
 
 /* ua_input.c */
 int get_cmd(UAContext *ua, char *prompt);
+int get_pint(UAContext *ua, char *prompt);
+int get_yesno(UAContext *ua, char *prompt);
 void parse_ua_args(UAContext *ua);
 
 /* ua_output.c */
@@ -122,6 +124,7 @@ int get_job_dbr(UAContext *ua, JOB_DBR *jr);
 
 int find_arg_keyword(UAContext *ua, char **list);
 int find_arg(UAContext *ua, char *keyword);
+int find_arg_with_value(UAContext *ua, char *keyword);
 int do_keyword_prompt(UAContext *ua, char *msg, char **list);
 int confirm_retention(UAContext *ua, utime_t *ret, char *msg);
 
index b7d33892f55ae24246f41110bddfea845e63f5eb..73aa81f9ff988fa38cbe6b339c2269053fc8df37 100644 (file)
@@ -48,6 +48,8 @@ typedef struct s_ua_context {
    int automount;                     /* if set, mount after label */
    int quit;                          /* if set, quit */
    int verbose;                       /* set for normal UA verbosity */
+   uint32_t pint32_val;               /* positive integer */
+   int32_t  int32_val;                /* positive/negative */
 } UAContext;
 
 #endif
index 3381a6063e35ca77dc10142feeba5b9487baef35..11dc32e92ba85ba4b4da897da9f28d305466876b 100644 (file)
@@ -241,11 +241,11 @@ static int addcmd(UAContext *ua, char *cmd)
    }
 getVolName:
    if (num == 0) {
-      if (!get_cmd(ua, _("Enter Volume name: ")) || ua->cmd[0] == '.') {
+      if (!get_cmd(ua, _("Enter Volume name: "))) {
         return 1;
       }
    } else {
-      if (!get_cmd(ua, _("Enter base volume name: ")) || ua->cmd[0] == '.') {
+      if (!get_cmd(ua, _("Enter base volume name: "))) {
         return 1;
       }
    }
@@ -284,7 +284,7 @@ getVolName:
    }
 
    if (store && store->autochanger) {
-      if (!get_cmd(ua, _("Enter slot (0 for none): ")) || ua->cmd[0] == '.') {
+      if (!get_cmd(ua, _("Enter slot (0 for none): "))) {
         return 1;
       }
       slot = atoi(ua->cmd);
@@ -410,10 +410,7 @@ static int cancelcmd(UAContext *ua, char *cmd)
         return 1;
       }
       if (njobs == 1) {
-         if (!get_cmd(ua, _("Confirm cancel (yes/no): "))) {
-           return 1;
-        }
-         if (strcasecmp(ua->cmd, _("yes")) != 0) {
+         if (!get_yesno(ua, _("Confirm cancel (yes/no): ")) || ua->pint32_val == 0) {
            return 1;
         }
       }
@@ -1101,11 +1098,9 @@ static int setdebugcmd(UAContext *ua, char *cmd)
    Dmsg1(120, "setdebug:%s:\n", cmd);
 
    level = -1;
-   for (i=1; i<ua->argc; i++) {
-      if (strcasecmp(ua->argk[i], _("level")) == 0 && ua->argv[i]) {
-        level = atoi(ua->argv[i]);
-        break;
-      }
+   i = find_arg_with_value(ua, _("level"));
+   if (i >= 0) {
+      level = atoi(ua->argv[i]);
    }
    if (level < 0) {
       if (!get_cmd(ua, _("Enter new debug level: "))) {
index 605def60f6f79651cd33721764033a881eede2b0..4f85e6e2efb8df3ade32f38512a0ef06a0524ee4 100644 (file)
@@ -118,7 +118,9 @@ static int diecmd(UAContext *ua, char *cmd)
    JCR *jcr = NULL;
    int a;
    
+   bsendmsg(ua, "The Director will segment fault.\n");
    a = jcr->JobId; /* ref NULL pointer */
+   jcr->JobId = 1000; /* another ref NULL pointer */
    return 0;
 }
 
index 13d7d3f6fd34e0c12c54f48c4f2ab540211fe6f1..646d34919590d9246c0816f451539d67301b4d52 100644 (file)
@@ -61,16 +61,74 @@ int get_cmd(UAContext *ua, char *prompt)
       if (strcmp(ua->cmd, ".messages") == 0) {
         qmessagescmd(ua, ua->cmd);
       }
-      /* ****FIXME**** if .command, go off and do it. For now ignore it. */
-      if (ua->cmd[0] == '.' && ua->cmd[1] != 0) {
-        continue;                    /* dot command */
+      /* Lone dot => break */
+      if (ua->cmd[0] == '.' && ua->cmd[1] == 0) {
+        return 0;
       }
-      /* Lone dot => break or actual response */
       break;
    }
    return 1;
 }
 
+/* 
+ * Get a positive integer
+ *  Returns:  0 if failure
+ *           1 if success => value in ua->pint32_val
+ */
+int get_pint(UAContext *ua, char *prompt)
+{
+   double dval;
+   ua->pint32_val = 0;
+   for (;;) {
+      if (!get_cmd(ua, prompt)) {
+        return 0;
+      }
+      if (!is_a_number(ua->cmd)) {
+         bsendmsg(ua, "Expected a positive integer, got: %s\n", ua->cmd);
+        continue;
+      }
+      errno = 0;
+      dval = strtod(ua->cmd, NULL);
+      if (errno != 0 || dval < 0) {
+         bsendmsg(ua, "Expected a positive integer, got: %s\n", ua->cmd);
+        continue;
+      }
+      ua->pint32_val = (uint32_t)dval;
+      return 1;
+   }
+}
+
+/* 
+ * Gets a yes or no response
+ *  Returns:  0 if failure
+ *           1 if success => ua->pint32_val == 1 for yes
+ *                           ua->pint32_val == 0 for no
+ */
+int get_yesno(UAContext *ua, char *prompt)
+{
+   int len;
+
+   ua->pint32_val = 0;
+   for (;;) {
+      if (!get_cmd(ua, prompt)) {
+        return 0;
+      }
+      len = strlen(ua->cmd);
+      if (len < 1 || len > 3) {
+        continue;
+      }
+      if (strncasecmp(ua->cmd, _("yes"), len) == 0) {
+        ua->pint32_val = 1;
+        return 1;
+      }
+      if (strncasecmp(ua->cmd, _("no"), len) == 0) {
+        return 1;
+      }
+      bsendmsg(ua, _("Invalid response. You must answer yes or no.\n"));
+   }
+}
+  
+
 void parse_ua_args(UAContext *ua)
 {
    return parse_command_args(ua->cmd, ua->args, &ua->argc, ua->argk, ua->argv);
index 554dc7cc33bd6c7ed4adf0c8bc4153ef7be6f038..9020445e4f59cca909c96fafa082cb7a03eaca3d 100644 (file)
@@ -225,17 +225,27 @@ checkName:
 
    /* If autochanger, request slot */
    if (store->autochanger) {
+      int first = 1;
       for ( ;; ) {
-         if (!get_cmd(ua, _("Enter slot (0 for none): ")) || ua->cmd[0] == '.') {
-           return 1;
+        if (first) {
+            i = find_arg(ua, "slot"); 
+           if (i >= 0 && ua->argv[i]) {
+              mr.Slot = atoi(ua->argv[i]);
+           }
+           first = 0;
+        } else {
+            if (!get_cmd(ua, _("Enter slot (0 for none): ")) || ua->cmd[0] == '.') {
+              return 1;
+           }
+           mr.Slot = atoi(ua->cmd);
         }
-        mr.Slot = atoi(ua->cmd);
         if (mr.Slot >= 0) {          /* OK */
            break;
         }
          bsendmsg(ua, _("Slot numbers must be positive.\n"));
       }
    }
+
    bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
 
    /* Must select Pool if not already done */
index c34ccc4657fc5eea14faa0e271f0ee630d2b0ea6..bc3eb0038dd1d9776094f5d17e130ba8fc5fd715 100644 (file)
@@ -97,6 +97,21 @@ int find_arg(UAContext *ua, char *keyword)
    return -1;
 }
 
+int find_arg_with_value(UAContext *ua, char *keyword)
+{
+   for (int i=1; i<ua->argc; i++) {
+      if (strcasecmp(keyword, ua->argk[i]) == 0) {
+        if (ua->argv[i]) {
+           return i;
+        } else {
+           return -1;
+        }
+      }
+   }
+   return -1;
+}
+
+
 
 /* 
  * Given a list of keywords, prompt the user 
@@ -459,8 +474,8 @@ int select_media_dbr(UAContext *ua, MEDIA_DBR *mr)
 
    memset(mr, 0, sizeof(MEDIA_DBR));
 
-   i = find_arg(ua, "volume");
-   if (i >= 0 && ua->argv[i]) {
+   i = find_arg_with_value(ua, "volume");
+   if (i >= 0) {
       bstrncpy(mr->VolumeName, ua->argv[i], sizeof(mr->VolumeName));
    }
    if (mr->VolumeName[0] == 0) {
@@ -520,15 +535,13 @@ POOL *get_pool_resource(UAContext *ua)
    POOL *pool = NULL;
    int i;
    
-   for (i=1; i<ua->argc; i++) {
-      if (strcasecmp(ua->argk[i], _("pool")) == 0 && ua->argv[i]) {
-        pool = (POOL *)GetResWithName(R_POOL, ua->argv[i]);
-        if (pool) {
-           return pool;
-        }
-         bsendmsg(ua, _("Error: Pool resource %s does not exist.\n"), ua->argv[i]);
-        break;
+   i = find_arg_with_value(ua, "pool");
+   if (i >= 0) {
+      pool = (POOL *)GetResWithName(R_POOL, ua->argv[i]);
+      if (pool) {
+        return pool;
       }
+      bsendmsg(ua, _("Error: Pool resource %s does not exist.\n"), ua->argv[i]);
    }
    return select_pool_resource(ua);
 }
@@ -661,7 +674,7 @@ int do_prompt(UAContext *ua, char *msg, char *prompt, int max_prompt)
          sprintf(pmsg, "%s (1-%d): ", msg, ua->num_prompts-1);
       }
       /* Either a . or an @ will get you out of the loop */
-      if (!get_cmd(ua, pmsg) || *ua->cmd == '.' || *ua->cmd == '@') {
+      if (!get_cmd(ua, pmsg) || *ua->cmd == '@') {
         item = -1;                   /* error */
          bsendmsg(ua, _("Selection aborted, nothing done.\n"));
         break;
@@ -779,8 +792,8 @@ int get_media_type(UAContext *ua, char *MediaType, int max_media)
    STORE *store;
    int i;
 
-   i = find_arg(ua, "mediatype");
-   if (i >= 0 && ua->argv[i]) {
+   i = find_arg_with_value(ua, "mediatype");
+   if (i >= 0) {
       bstrncpy(MediaType, ua->argv[i], max_media);
       return 1;
    }
index a127b0da61c9255547391f6ad6ce1e3ea95cc583..49f47a708b32b179ee7bfd8a60efbbccd4d37bac 100644 (file)
@@ -50,17 +50,19 @@ static void *heartbeat_thread(void *arg)
     *  a heartbeat, we simply send it on to the Director to
     *  keep him alive.
     */
-   for ( ;; ) {
-      n = bnet_recv(sd);
-      if (is_bnet_stop(sd)) {
-        break;
+   for ( ; !is_bnet_stop(sd); ) {
+      n = bnet_wait_data_intr(sd, 60);
+      if (n != 1) {
+        continue;
       }
+      n = bnet_recv(sd);
       if (n == BNET_SIGNAL && sd->msglen == BNET_HEARTBEAT) {
         bnet_sig(dir, BNET_HEARTBEAT);
       }
    }
    bnet_close(sd);
    bnet_close(dir);
+   jcr->duped_sd = NULL;
    return NULL;
 }
 
@@ -81,8 +83,12 @@ static void stop_heartbeat_monitor(JCR *jcr)
       bmicrosleep(0, 500);           /* avoid race */
    }
    jcr->duped_sd->timed_out = 1;      /* set timed_out to terminate read */
+   jcr->duped_sd->terminated = 1;     /* set to terminate read */
 
-   pthread_kill(hbtid, TIMEOUT_SIGNAL);  /* make heartbeat thread go away */
+   while (jcr->duped_sd) {
+      pthread_kill(hbtid, TIMEOUT_SIGNAL);  /* make heartbeat thread go away */
+      bmicrosleep(0, 20);
+   }
    pthread_join(hbtid, NULL);        /* wait for him to clean up */
 }
 
index ed4d390a5a08da3d5b773bdef107060718603539..dfd9db3d878ad69e25607dcd6cc1c6ba281059a2 100644 (file)
@@ -149,6 +149,7 @@ struct s_jcr {
    char *RestoreWhere;                /* Where to restore the files */
    POOLMEM *client_uname;             /* client uname */ 
    int replace;                       /* Replace option */
+   int acquired_resource_locks;       /* set if resource locks acquired */
 #endif /* DIRECTOR_DAEMON */
 
 
index 66aa09add0dab38e1b6b257fba05c00b95fcc514..73d1ab3a19519697443e3fa6bf006f0b817ba86c 100644 (file)
@@ -382,7 +382,7 @@ int bnet_ssl_client(BSOCK *bsock, char *password, int ssl_need)
  *          -1 if error
  */
 int 
-bnet_wait_data(BSOCK *bsock, int sec)
+bnet_wait_data(BSOCK *bsock, int sec)         
 {
    fd_set fdset;
    struct timeval tv;
@@ -409,6 +409,35 @@ bnet_wait_data(BSOCK *bsock, int sec)
    }
 }
 
+/*
+ * As above, but returns on interrupt
+ */
+int
+bnet_wait_data_intr(BSOCK *bsock, int sec)         
+{
+   fd_set fdset;
+   struct timeval tv;
+
+   FD_ZERO(&fdset);
+   FD_SET(bsock->fd, &fdset);
+   tv.tv_sec = sec;
+   tv.tv_usec = 0;
+   for ( ;; ) {
+      switch(select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
+        case 0:                         /* timeout */
+           bsock->b_errno = 0;
+           return 0;
+        case -1:
+           bsock->b_errno = errno;
+           return -1;                  /* error return */
+        default:
+           bsock->b_errno = 0;
+           return 1;
+      }
+   }
+}
+
+
 static pthread_mutex_t ip_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 /*
index aad26b6f87cccfded352d45a3cdb2798423e0bbd..93f48017154dd8c7cbabb364acd233a79f67ff98 100644 (file)
@@ -58,7 +58,6 @@ int      bnet_ssl_client       (BSOCK *bsock, char *password, int ssl_need);
 BSOCK *    bnet_connect           (void *jcr, int retry_interval,
               int max_retry_time, char *name, char *host, char *service, 
               int port, int verbose);
-int       bnet_wait_data         (BSOCK *bsock, int sec);
 void      bnet_close            (BSOCK *bsock);
 BSOCK *    init_bsock           (void *jcr, int sockfd, char *who, char *ip, int port);
 BSOCK *    dup_bsock            (BSOCK *bsock);
@@ -66,6 +65,7 @@ void     term_bsock            (BSOCK *bsock);
 char *    bnet_strerror         (BSOCK *bsock);
 char *    bnet_sig_to_ascii     (BSOCK *bsock);
 int       bnet_wait_data        (BSOCK *bsock, int sec);
+int       bnet_wait_data_intr   (BSOCK *bsock, int sec);
 int       bnet_despool          (BSOCK *bsock);
 int       is_bnet_stop          (BSOCK *bsock);
 int       is_bnet_error         (BSOCK *bsock);
index 0bbd312391af4de133b7a58b52bc9fe6fec43803..aea28d9453212b1757fbd4dfd33e1d128e829212 100644 (file)
@@ -83,17 +83,24 @@ static void signal_handler(int sig)
       static char pid_buf[20];
       static char btpath[400];
       pid_t pid;
+      int exelen = strlen(exepath);
 
       fprintf(stderr, "Kaboom! %s, %s got signal %d. Attempting traceback.\n", 
              exename, my_name, sig);
 
-      if (strlen(exepath) + 12 > (int)sizeof(btpath)) {
+      if (exelen + 12 > (int)sizeof(btpath)) {
          strcpy(btpath, "btraceback");
       } else {
         strcpy(btpath, exepath);
-         strcat(btpath, "/btraceback");
+         if (btpath[exelen-1] != '/') {
+            strcat(btpath, "/btraceback");
+        } else {
+            strcat(btpath, "btraceback");
+        }
+      }
+      if (btpath[exelen-1] != '/') {
+         strcat(exepath, "/");
       }
-      strcat(exepath, "/");
       strcat(exepath, exename);
       if (chdir(working_directory) !=0) {  /* dump in working directory */
          Pmsg2(000, "chdir to %s failed. ERR=%s\n", working_directory,  strerror(errno));
@@ -112,6 +119,7 @@ static void signal_handler(int sig)
         argv[1] = exepath;           /* path to exe */
         argv[2] = pid_buf;
         argv[3] = (char *)NULL;
+         fprintf(stderr, "Calling: %s %s %s\n", btpath, exepath, pid_buf);
         if (execv(btpath, argv) != 0) {
             printf("execv: %s failed: ERR=%s\n", btpath, strerror(errno));
         }
@@ -119,6 +127,7 @@ static void signal_handler(int sig)
       default:                       /* parent */
         break;
       }
+      /* Parent continue here, waiting for child */
       sigdefault.sa_flags = 0;
       sigdefault.sa_handler = SIG_DFL;
       sigfillset(&sigdefault.sa_mask);
index 843cd4e46752b7fcbc87e83c3deb268134ca0176..dd31484f940765212a71da3d1a4ffc463b5c9baa 100644 (file)
@@ -11,7 +11,7 @@
 #define TRACE_FILE 1  
 
 /* Turn this on if you want to try the new Job semaphore code */
-/* #define USE_SEMAPHORE */
+#define USE_SEMAPHORE
 
 /* IF you undefine this, Bacula will run 10X slower */
 #define NO_POLL_TEST 1