]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/wait.c
Start adding back removed code.
[bacula/bacula] / bacula / src / stored / wait.c
index aefac5cac8b42ad7bcf4fcd1859eb4f91c9f1b0f..85555618182e13fad3af5e392d77e8f44a1132ef 100644 (file)
@@ -9,11 +9,11 @@
  *   Version $Id$
  */
 /*
  *   Version $Id$
  */
 /*
-   Copyright (C) 2000-2005 Kern Sibbald
+   Copyright (C) 2000-2006 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
-   version 2 as ammended with additional clauses defined in the
+   version 2 as amended with additional clauses defined in the
    file LICENSE in the main source directory.
 
    This program is distributed in the hope that it will be useful,
    file LICENSE in the main source directory.
 
    This program is distributed in the hope that it will be useful,
 #include "bacula.h"                   /* pull in global headers */
 #include "stored.h"                   /* pull in Storage Deamon headers */
 
 #include "bacula.h"                   /* pull in global headers */
 #include "stored.h"                   /* pull in Storage Deamon headers */
 
-static bool double_jcr_wait_time(JCR *jcr);
+//static bool double_jcr_wait_time(JCR *jcr);
 
 
 /*
  * Wait for SysOp to mount a tape on a specific device
  *
 
 
 /*
  * 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)
 {
  */
 int wait_for_sysop(DCR *dcr)
 {
@@ -48,8 +48,8 @@ int wait_for_sysop(DCR *dcr)
    JCR *jcr = dcr->jcr;
 
    P(dev->mutex);
    JCR *jcr = dcr->jcr;
 
    P(dev->mutex);
-   unmounted = (dev->dev_blocked == BST_UNMOUNTED) ||
-                (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
+   Dmsg1(100, "Enter blocked=%s\n", dev->print_blocked());
+   unmounted = is_device_unmounted(dev);
 
    dev->poll = false;
    /*
 
    dev->poll = false;
    /*
@@ -70,8 +70,9 @@ int wait_for_sysop(DCR *dcr)
    }
 
    if (!unmounted) {
    }
 
    if (!unmounted) {
+      Dmsg1(400, "blocked=%s\n", dev->print_blocked());
       dev->dev_prev_blocked = dev->dev_blocked;
       dev->dev_prev_blocked = dev->dev_blocked;
-      dev->dev_blocked = BST_WAITING_FOR_SYSOP; /* indicate waiting for mount */
+      dev->set_blocked(BST_WAITING_FOR_SYSOP); /* indicate waiting for mount */
    }
 
    for ( ; !job_canceled(jcr); ) {
    }
 
    for ( ; !job_canceled(jcr); ) {
@@ -81,12 +82,13 @@ int wait_for_sysop(DCR *dcr)
       timeout.tv_nsec = tv.tv_usec * 1000;
       timeout.tv_sec = tv.tv_sec + add_wait;
 
       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);
       start = time(NULL);
       /* Wait required time */
       stat = pthread_cond_timedwait(&dev->wait_next_vol, &dev->mutex, &timeout);
-      Dmsg1(400, "Wokeup from sleep on device stat=%d\n", stat);
+      Dmsg2(400, "Wokeup from sleep on device stat=%d blocked=%s\n", stat,
+         dev->print_blocked());
 
       now = time(NULL);
       dev->rem_wait_sec -= (now - start);
 
       now = time(NULL);
       dev->rem_wait_sec -= (now - start);
@@ -106,34 +108,55 @@ int wait_for_sysop(DCR *dcr)
          }
       }
 
          }
       }
 
-      /*
-       * Check if user unmounted the device while we were waiting
-       */
-      unmounted = (dev->dev_blocked == BST_UNMOUNTED) ||
-                   (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
-
-      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");
       if (dev->rem_wait_sec <= 0) {  /* on exceeding wait time return */
          Dmsg0(400, "Exceed wait time.\n");
+         stat = W_TIMEOUT;
          break;
       }
 
          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)) {
       if (!unmounted && dev->vol_poll_interval &&
           (now - first_start >= dev->vol_poll_interval)) {
-         Dmsg1(400, "In wait blocked=%s\n", edit_blocked_reason(dev));
+         Dmsg1(400, "In wait blocked=%s\n", dev->print_blocked());
          dev->poll = true;            /* returning a poll event */
          dev->poll = true;            /* returning a poll event */
+         stat = W_POLL;
          break;
       }
       /*
        * Check if user mounted the device while we were waiting
        */
          break;
       }
       /*
        * Check if user mounted the device while we were waiting
        */
-      if (dev->dev_blocked == BST_MOUNT) {   /* mount request ? */
-         stat = 0;
+      if (dev->get_blocked() == BST_MOUNT) {   /* mount request ? */
+         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;
       }
 
          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;
       add_wait = dev->wait_sec - (now - start);
       if (add_wait < 0) {
          add_wait = 0;
@@ -144,8 +167,10 @@ int wait_for_sysop(DCR *dcr)
    }
 
    if (!unmounted) {
    }
 
    if (!unmounted) {
-      dev->dev_blocked = dev->dev_prev_blocked;    /* restore entry state */
+      dev->set_blocked(dev->dev_prev_blocked);    /* restore entry state */
+      Dmsg1(400, "set %s\n", dev->print_blocked());
    }
    }
+   Dmsg1(400, "Exit blocked=%s\n", dev->print_blocked());
    V(dev->mutex);
    return stat;
 }
    V(dev->mutex);
    return stat;
 }
@@ -158,97 +183,41 @@ int wait_for_sysop(DCR *dcr)
  * Returns: true  if a device has changed state
  *          false if the total wait time has expired.
  */
  * Returns: true  if a device has changed state
  *          false if the total wait time has expired.
  */
-bool wait_for_device(JCR *jcr, const char *msg, bool first)
+bool wait_for_device(JCR *jcr, bool first)
 {
    struct timeval tv;
    struct timezone tz;
    struct timespec timeout;
 {
    struct timeval tv;
    struct timezone tz;
    struct timespec timeout;
-// time_t last_heartbeat = 0;
    int stat = 0;
    int stat = 0;
-   int add_wait;
-   bool ok = false;
+   bool ok = true;
+   const int wait_time = 5 * 60;       /* wait 5 minutes */
 
    Dmsg0(100, "Enter wait_for_device\n");
    P(device_release_mutex);
 
    if (first) {
 
    Dmsg0(100, "Enter wait_for_device\n");
    P(device_release_mutex);
 
    if (first) {
-      Jmsg(jcr, M_MOUNT, 0, msg);
+      Jmsg(jcr, M_MOUNT, 0, _("Job %s waiting to reserve a device.\n"), jcr->Job);
    }
 
    }
 
-   /*
-    * Wait requested time (dev->rem_wait_sec).  However, we also wake up every
-    *    HB_TIME seconds and send a heartbeat to the FD and the Director
-    *    to keep stateful firewalls from closing them down while waiting
-    *    for the operator.
-    */
-   add_wait = jcr->rem_wait_sec;
-   if (me->heartbeat_interval && add_wait > me->heartbeat_interval) {
-      add_wait = me->heartbeat_interval;
-   }
+   gettimeofday(&tv, &tz);
+   timeout.tv_nsec = tv.tv_usec * 1000;
+   timeout.tv_sec = tv.tv_sec + wait_time;
 
 
-   for ( ; !job_canceled(jcr); ) {
-      time_t now, start;
+   Dmsg0(100, "I'm going to wait for a device.\n");
 
 
-      gettimeofday(&tv, &tz);
-      timeout.tv_nsec = tv.tv_usec * 1000;
-      timeout.tv_sec = tv.tv_sec + add_wait;
+   /* Wait required time */
+   stat = pthread_cond_timedwait(&wait_device_release, &device_release_mutex, &timeout);
+   Dmsg1(100, "Wokeup from sleep on device stat=%d\n", stat);
 
 
-      Dmsg3(100, "I'm going to wait for a device. HB=%d wait=%d remwait=%d\n", 
-         (int)me->heartbeat_interval, jcr->wait_sec, jcr->rem_wait_sec);
-      start = time(NULL);
-      /* Wait required time */
-      stat = pthread_cond_timedwait(&wait_device_release, &device_release_mutex, &timeout);
-      Dmsg1(100, "Wokeup from sleep on device stat=%d\n", stat);
-
-      now = time(NULL);
-      jcr->rem_wait_sec -= (now - start);
-
-#ifdef needed
-      /* Note, this always triggers the first time. We want that. */
-      if (me->heartbeat_interval) {
-         if (now - last_heartbeat >= me->heartbeat_interval) {
-            /* send heartbeats */
-            if (jcr->file_bsock) {
-               bnet_sig(jcr->file_bsock, BNET_HEARTBEAT);
-               Dmsg0(400, "Send heartbeat to FD.\n");
-            }
-            if (jcr->dir_bsock) {
-               bnet_sig(jcr->dir_bsock, BNET_HEARTBEAT);
-            }
-            last_heartbeat = now;
-         }
-      }
-#endif
-
-      if (stat != ETIMEDOUT) {     /* if someone woke us up */
-         ok = true;
-         break;                    /* allow caller to examine device */
-      }
-      if (jcr->rem_wait_sec <= 0) {  /* on exceeding wait time return */
-         Dmsg0(400, "Exceed wait time.\n");
-         if (!double_jcr_wait_time(jcr)) {
-            break;                 /* give up */
-         }
-         Jmsg(jcr, M_MOUNT, 0, msg);
-      }
-
-      add_wait = jcr->wait_sec - (now - start);
-      if (add_wait < 0) {
-         add_wait = 0;
-      }
-      if (me->heartbeat_interval && add_wait > me->heartbeat_interval) {
-         add_wait = me->heartbeat_interval;
-      }
-   }
 
    V(device_release_mutex);
    Dmsg1(100, "Return from wait_device ok=%d\n", ok);
    return ok;
 }
 
 
    V(device_release_mutex);
    Dmsg1(100, "Return from wait_device ok=%d\n", ok);
    return ok;
 }
 
+#ifdef xxx
 /*
 /*
- * The jcr timers are used for waiting on any device
- *
+ * The jcr timers are used for waiting on any device *
  * Returns: true if time doubled
  *          false if max time expired
  */
  * Returns: true if time doubled
  *          false if max time expired
  */
@@ -265,3 +234,4 @@ static bool double_jcr_wait_time(JCR *jcr)
    }
    return true;
 }
    }
    return true;
 }
+#endif