]> git.sur5r.net Git - bacula/bacula/blob - bacula/patches/2.2.x/2.2.5-hb.patch
Added preliminary AFS acl support. The code may need some testing on a real AFS enabl...
[bacula/bacula] / bacula / patches / 2.2.x / 2.2.5-hb.patch
1
2  This patch fixes bug #947 where a large number of emails were generated
3  because the heartbeat interval was small and the tape in the drive did
4  not correspond to the one wanted by Bacula.
5
6  Apply the patch to version 2.2.5 (and probably any 2.2.x version) with:
7
8  cd <bacula-source>
9  ./configure <your options>
10  patch -p0 <2.2.5-hb.patch
11  make
12  ...
13  make install
14
15
16 Index: src/stored/wait.c
17 ===================================================================
18 --- src/stored/wait.c   (revision 5814)
19 +++ src/stored/wait.c   (working copy)
20 @@ -40,9 +40,8 @@
21  #include "bacula.h"                   /* pull in global headers */
22  #include "stored.h"                   /* pull in Storage Deamon headers */
23  
24 -//static bool double_jcr_wait_time(JCR *jcr);
25 +const int dbglvl = 400;
26  
27 -
28  /*
29   * Wait for SysOp to mount a tape on a specific device
30   *
31 @@ -62,7 +61,7 @@
32     JCR *jcr = dcr->jcr;
33  
34     dev->dlock();  
35 -   Dmsg1(100, "Enter blocked=%s\n", dev->print_blocked());
36 +   Dmsg1(dbglvl, "Enter blocked=%s\n", dev->print_blocked());
37     unmounted = is_device_unmounted(dev);
38  
39     dev->poll = false;
40 @@ -84,27 +83,28 @@
41     }
42  
43     if (!unmounted) {
44 -      Dmsg1(400, "blocked=%s\n", dev->print_blocked());
45 +      Dmsg1(dbglvl, "blocked=%s\n", dev->print_blocked());
46        dev->dev_prev_blocked = dev->blocked();
47        dev->set_blocked(BST_WAITING_FOR_SYSOP); /* indicate waiting for mount */
48     }
49  
50     for ( ; !job_canceled(jcr); ) {
51 -      time_t now, start;
52 +      time_t now, start, total_waited;
53  
54        gettimeofday(&tv, &tz);
55        timeout.tv_nsec = tv.tv_usec * 1000;
56        timeout.tv_sec = tv.tv_sec + add_wait;
57  
58 -      Dmsg4(400, "I'm going to sleep on device %s. HB=%d wait=%d add_wait=%d\n", 
59 -         dev->print_name(), (int)me->heartbeat_interval, dev->wait_sec, add_wait);
60 +      Dmsg4(dbglvl, "I'm going to sleep on device %s. HB=%d rem_wait=%d add_wait=%d\n", 
61 +         dev->print_name(), (int)me->heartbeat_interval, dev->rem_wait_sec, add_wait);
62        start = time(NULL);
63        /* Wait required time */
64        stat = pthread_cond_timedwait(&dev->wait_next_vol, &dev->m_mutex, &timeout);
65 -      Dmsg2(400, "Wokeup from sleep on device stat=%d blocked=%s\n", stat,
66 +      Dmsg2(dbglvl, "Wokeup from sleep on device stat=%d blocked=%s\n", stat,
67           dev->print_blocked());
68  
69        now = time(NULL);
70 +      total_waited = now - first_start;
71        dev->rem_wait_sec -= (now - start);
72  
73        /* Note, this always triggers the first time. We want that. */
74 @@ -113,7 +113,7 @@
75              /* send heartbeats */
76              if (jcr->file_bsock) {
77                 jcr->file_bsock->signal(BNET_HEARTBEAT);
78 -               Dmsg0(400, "Send heartbeat to FD.\n");
79 +               Dmsg0(dbglvl, "Send heartbeat to FD.\n");
80              }
81              if (jcr->dir_bsock) {
82                 jcr->dir_bsock->signal(BNET_HEARTBEAT);
83 @@ -131,7 +131,7 @@
84  
85  
86        if (dev->rem_wait_sec <= 0) {  /* on exceeding wait time return */
87 -         Dmsg0(400, "Exceed wait time.\n");
88 +         Dmsg0(dbglvl, "Exceed wait time.\n");
89           stat = W_TIMEOUT;
90           break;
91        }
92 @@ -142,8 +142,8 @@
93        unmounted = is_device_unmounted(dev);
94  
95        if (!unmounted && dev->vol_poll_interval &&
96 -          (now - first_start >= dev->vol_poll_interval)) {
97 -         Dmsg1(400, "In wait blocked=%s\n", dev->print_blocked());
98 +          (total_waited >= dev->vol_poll_interval)) {
99 +         Dmsg1(dbglvl, "poll return in wait blocked=%s\n", dev->print_blocked());
100           dev->poll = true;            /* returning a poll event */
101           stat = W_POLL;
102           break;
103 @@ -152,6 +152,7 @@
104         * Check if user mounted the device while we were waiting
105         */
106        if (dev->blocked() == BST_MOUNT) {   /* mount request ? */
107 +         Dmsg0(dbglvl, "Mounted return.\n");
108           stat = W_MOUNT;
109           break;
110        }
111 @@ -160,30 +161,39 @@
112         * If we did not timeout, then some event happened, so
113         *   return to check if state changed.   
114         */
115 -      if (stat != 0) {
116 +      if (stat != ETIMEDOUT) {
117 +         berrno be;
118 +         Dmsg2(dbglvl, "Wake return. stat=%d. ERR=%s\n", stat, be.bstrerror(stat));
119           stat = W_WAKE;          /* someone woke us */
120           break;
121        }
122  
123        /* 
124         * At this point, we know we woke up because of a timeout,
125 -       *   that was due to a heartbeat, so we just update
126 -       *   the wait counters and continue.
127 +       *   that was due to a heartbeat, because any other reason would
128 +       *   have caused us to return, so update the wait counters and continue.
129         */
130 -      add_wait = dev->wait_sec - (now - start);
131 +      add_wait = dev->rem_wait_sec;
132 +      if (me->heartbeat_interval && add_wait > me->heartbeat_interval) {
133 +         add_wait = me->heartbeat_interval;
134 +      }
135 +      /* If the user did not unmount the tape and we are polling, ensure
136 +       *  that we poll at the correct interval.
137 +       */
138 +      if (!unmounted && dev->vol_poll_interval && 
139 +           add_wait > dev->vol_poll_interval - total_waited) {
140 +         add_wait = dev->vol_poll_interval - total_waited;
141 +      }
142        if (add_wait < 0) {
143           add_wait = 0;
144        }
145 -      if (me->heartbeat_interval && add_wait > me->heartbeat_interval) {
146 -         add_wait = me->heartbeat_interval;
147 -      }
148     }
149  
150     if (!unmounted) {
151        dev->set_blocked(dev->dev_prev_blocked);    /* restore entry state */
152 -      Dmsg1(400, "set %s\n", dev->print_blocked());
153 +      Dmsg1(dbglvl, "set %s\n", dev->print_blocked());
154     }
155 -   Dmsg1(400, "Exit blocked=%s\n", dev->print_blocked());
156 +   Dmsg1(dbglvl, "Exit blocked=%s\n", dev->print_blocked());
157     dev->dunlock();
158     return stat;
159  }
160 @@ -209,7 +219,7 @@
161     const int max_wait_time = 1 * 60;       /* wait 1 minute */
162     char ed1[50];
163  
164 -   Dmsg0(100, "Enter wait_for_device\n");
165 +   Dmsg0(dbglvl, "Enter wait_for_device\n");
166     P(device_release_mutex);
167  
168     if (++retries % 5 == 0) {
169 @@ -222,14 +232,14 @@
170     timeout.tv_nsec = tv.tv_usec * 1000;
171     timeout.tv_sec = tv.tv_sec + max_wait_time;
172  
173 -   Dmsg1(100, "JobId=%u going to wait for a device.\n", (uint32_t)jcr->JobId);
174 +   Dmsg0(dbglvl, "Going to wait for a device.\n");
175  
176     /* Wait required time */
177     stat = pthread_cond_timedwait(&wait_device_release, &device_release_mutex, &timeout);
178 -   Dmsg2(100, "JobId=%u wokeup from sleep on device stat=%d\n", (uint32_t)jcr->JobId, stat);
179 +   Dmsg1(dbglvl, "Wokeup from sleep on device stat=%d\n", stat);
180  
181     V(device_release_mutex);
182 -   Dmsg2(100, "JobId=%u return from wait_device ok=%d\n", (uint32_t)jcr->JobId, ok);
183 +   Dmsg1(dbglvl, "Return from wait_device ok=%d\n", ok);
184     return ok;
185  }
186