X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Fwait.c;h=32804e98778bd7098cec2dad21b9e6acf2ebf62b;hb=90e04dd4f4c1bcad214b4ac5dd4ffbc55bbe0763;hp=d95f3852e260a0f69a751a8d26185a138aa53d8b;hpb=e819bdff189d3487c18134f4c4dfba956b208fec;p=bacula%2Fbacula diff --git a/bacula/src/stored/wait.c b/bacula/src/stored/wait.c index d95f3852e2..32804e9877 100644 --- a/bacula/src/stored/wait.c +++ b/bacula/src/stored/wait.c @@ -9,30 +9,44 @@ * Version $Id$ */ /* - Copyright (C) 2000-2005 Kern Sibbald + Bacula® - The Network Backup Solution - 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 - file LICENSE in the main source directory. + Copyright (C) 2000-2006 Free Software Foundation Europe e.V. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - the file LICENSE for additional details. + The main author of Bacula is Kern Sibbald, with contributions from + many others, a complete list can be found in the file AUTHORS. + This program is Free Software; you can redistribute it and/or + modify it under the terms of version two of the GNU General Public + License as published by the Free Software Foundation plus additions + that are listed in the file LICENSE. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + + Bacula® is a registered trademark of John Walker. + The licensor of Bacula is the Free Software Foundation Europe + (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, + Switzerland, email:ftf@fsfeurope.org. +*/ - */ #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) { @@ -48,8 +62,8 @@ int wait_for_sysop(DCR *dcr) 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; /* @@ -70,6 +84,7 @@ int wait_for_sysop(DCR *dcr) } if (!unmounted) { + Dmsg1(400, "blocked=%s\n", dev->print_blocked()); dev->dev_prev_blocked = dev->dev_blocked; dev->set_blocked(BST_WAITING_FOR_SYSOP); /* indicate waiting for mount */ } @@ -81,12 +96,13 @@ 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); - 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); @@ -106,34 +122,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"); + 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", edit_blocked_reason(dev)); + 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->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; + } + + /* + * 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; @@ -145,7 +182,9 @@ int wait_for_sysop(DCR *dcr) if (!unmounted) { 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; } @@ -163,89 +202,34 @@ 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); if (first) { - Jmsg(jcr, M_MOUNT, 0, _("Job %s waiting to obtain a device.\n"), jcr->Job); + 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; + gettimeofday(&tv, &tz); + timeout.tv_nsec = tv.tv_usec * 1000; + timeout.tv_sec = tv.tv_sec + wait_time; - 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); + Dmsg0(100, "I'm going to wait for a device.\n"); - now = time(NULL); - jcr->rem_wait_sec -= (now - start); + /* 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); -#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, _("Job %s waiting to obtain a device.\n"), jcr->Job); - } - - 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 @@ -264,3 +248,4 @@ static bool double_jcr_wait_time(JCR *jcr) } return true; } +#endif