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,
#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)
{
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;
/*
}
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 */
}
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);
}
}
- /*
- * 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;
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;
}
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);
- }
-
- /*
- * 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;
+ Jmsg(jcr, M_MOUNT, 0, _("Job %s waiting to reserve a device.\n"), jcr->Job);
}
- 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);
+ Dmsg0(100, "I'm going to wait for a device.\n");
-#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);
- }
+ /* 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
}
return true;
}
+#endif