X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Fwait.c;h=85555618182e13fad3af5e392d77e8f44a1132ef;hb=b22b260eaa7fb9f122523fff0e324dca5904b97f;hp=28d081ba10eb82929c6f3ceca74076060dab361e;hpb=16415680c8b2c30cddd68400f906d410b4d344f0;p=bacula%2Fbacula diff --git a/bacula/src/stored/wait.c b/bacula/src/stored/wait.c index 28d081ba10..8555561818 100644 --- a/bacula/src/stored/wait.c +++ b/bacula/src/stored/wait.c @@ -9,7 +9,7 @@ * 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 @@ -26,13 +26,13 @@ #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 * - * 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; @@ -166,10 +188,9 @@ bool wait_for_device(JCR *jcr, bool first) struct timeval tv; struct timezone tz; struct timespec timeout; -// time_t last_heartbeat = 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); @@ -178,77 +199,23 @@ bool wait_for_device(JCR *jcr, bool first) 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; - } - - for ( ; !job_canceled(jcr); ) { - time_t now, start; - - gettimeofday(&tv, &tz); - timeout.tv_nsec = tv.tv_usec * 1000; - timeout.tv_sec = tv.tv_sec + add_wait; - - 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); + gettimeofday(&tv, &tz); + timeout.tv_nsec = tv.tv_usec * 1000; + timeout.tv_sec = tv.tv_sec + wait_time; - 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 + Dmsg0(100, "I'm going to wait for a device.\n"); - 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, _("Job %s waiting to reserve a device.\n"), jcr->Job); - } + /* 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); - 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; } +#ifdef xxx /* * The jcr timers are used for waiting on any device * * Returns: true if time doubled @@ -267,3 +234,4 @@ static bool double_jcr_wait_time(JCR *jcr) } return true; } +#endif