]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/wait.c
This commit was manufactured by cvs2svn to create tag
[bacula/bacula] / bacula / src / stored / wait.c
index b08e80f46e562c0e6ea9bf002096e17813b3406c..a4c4351441634c96157dd3d2e36082c6b205efe2 100644 (file)
@@ -32,7 +32,7 @@
 /*
  * Wait for SysOp to mount a tape on a specific device
  *
- *   Returns: status from pthread_cond_timedwait() 
+ *   Returns: W_ERROR, W_TIMEOUT, W_POLL, W_MOUNT, or W_WAKE 
  */
 int wait_for_sysop(DCR *dcr)
 {
@@ -82,8 +82,8 @@ int wait_for_sysop(DCR *dcr)
       timeout.tv_nsec = tv.tv_usec * 1000;
       timeout.tv_sec = tv.tv_sec + add_wait;
 
-      Dmsg3(400, "I'm going to sleep on device %s. HB=%d wait=%d\n", dev->print_name(),
-         (int)me->heartbeat_interval, dev->wait_sec);
+      Dmsg4(400, "I'm going to sleep on device %s. HB=%d wait=%d add_wait=%d\n", 
+         dev->print_name(), (int)me->heartbeat_interval, dev->wait_sec, add_wait);
       start = time(NULL);
       /* Wait required time */
       stat = pthread_cond_timedwait(&dev->wait_next_vol, &dev->mutex, &timeout);
@@ -108,33 +108,55 @@ int wait_for_sysop(DCR *dcr)
          }
       }
 
-      /*
-       * Check if user unmounted the device while we were waiting
-       */
-      unmounted = is_device_unmounted(dev);
-
-      if (stat != ETIMEDOUT) {     /* we blocked the device */
-         break;                    /* on error return */
+      if (stat == EINVAL) {
+         berrno be;
+         Dmsg1(000, "pthread stat=%d\n", stat);
+         Jmsg1(jcr, M_FATAL, 0, _("pthread timedwait error. ERR=%s\n"), be.strerror(stat));
+         stat = W_ERROR;               /* error */
+         break;
       }
+
+
       if (dev->rem_wait_sec <= 0) {  /* on exceeding wait time return */
          Dmsg0(400, "Exceed wait time.\n");
+         stat = W_TIMEOUT;
          break;
       }
 
+      /*
+       * Check if user unmounted the device while we were waiting
+       */
+      unmounted = is_device_unmounted(dev);
+
       if (!unmounted && dev->vol_poll_interval &&
           (now - first_start >= dev->vol_poll_interval)) {
          Dmsg1(400, "In wait blocked=%s\n", dev->print_blocked());
          dev->poll = true;            /* returning a poll event */
+         stat = W_POLL;
          break;
       }
       /*
        * Check if user mounted the device while we were waiting
        */
       if (dev->get_blocked() == BST_MOUNT) {   /* mount request ? */
-         stat = 0;
+         stat = W_MOUNT;
          break;
       }
 
+      /*
+       * If we did not timeout, then some event happened, so
+       *   return to check if state changed.   
+       */
+      if (stat != 0) {
+         stat = W_WAKE;          /* someone woke us */
+         break;
+      }
+
+      /* 
+       * At this point, we know we woke up because of a timeout,
+       *   that was due to a heartbeat, so we just update
+       *   the wait counters and continue.
+       */
       add_wait = dev->wait_sec - (now - start);
       if (add_wait < 0) {
          add_wait = 0;
@@ -168,6 +190,7 @@ bool wait_for_device(JCR *jcr, bool first)
    struct timespec timeout;
    int stat = 0;
    bool ok = true;
+   const int wait_time = 5 * 60;        /* wait 5 minutes */
 
    Dmsg0(100, "Enter wait_for_device\n");
    P(device_release_mutex);
@@ -178,7 +201,7 @@ bool wait_for_device(JCR *jcr, bool first)
 
    gettimeofday(&tv, &tz);
    timeout.tv_nsec = tv.tv_usec * 1000;
-   timeout.tv_sec = tv.tv_sec + 120;
+   timeout.tv_sec = tv.tv_sec + wait_time;
 
    Dmsg0(100, "I'm going to wait for a device.\n");