]> git.sur5r.net Git - bacula/bacula/blob - bacula/patches/2.2.8-deadlock.patch
ebl Change VersionId from 10 to 11
[bacula/bacula] / bacula / patches / 2.2.8-deadlock.patch
1
2  This patch fixes two deadlock conditions that occur in Bacula.
3  The first is caused by running simultaneous backup and restore jobs
4  with an autochanger, and leads to use counts getting out of sync causing
5  jobs in the Director to wait on resources.  
6  The second is a condition where the SD is unable to use a Volume that
7  is currently mounted because it keeps wanting a different Volume. This
8  condition seems to be relatively rare unless you are using
9  "Prefer Mounted Volumes = no" in which case it occurs much more often.
10
11  This patch can be applied to a fully patched 2.2.8 version with the
12  following:
13
14  cd <bacula-source>
15  patch -p0 <2.2.8-deadlock.patch
16  ./configure <your-options>
17  make
18  ...
19  make install
20
21
22
23 Index: src/dird/jobq.c
24 ===================================================================
25 --- src/dird/jobq.c     (revision 6531)
26 +++ src/dird/jobq.c     (working copy)
27 @@ -478,7 +478,7 @@
28            */
29           if (jcr->acquired_resource_locks) {
30              if (jcr->rstore) {
31 -               jcr->rstore->NumConcurrentJobs = 0;
32 +               jcr->rstore->NumConcurrentJobs--;
33                 Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
34              }
35              if (jcr->wstore) {
36 Index: src/stored/askdir.c
37 ===================================================================
38 --- src/stored/askdir.c (revision 6531)
39 +++ src/stored/askdir.c (working copy)
40 @@ -252,20 +252,19 @@
41  {
42      JCR *jcr = dcr->jcr;
43      BSOCK *dir = jcr->dir_bsock;
44 -    bool found = false;
45  
46      Dmsg2(200, "dir_find_next_appendable_volume: reserved=%d Vol=%s\n", 
47         dcr->reserved_device, dcr->VolumeName);
48  
49      /*
50 -     * Try the twenty oldest or most available volumes.  Note,
51 +     * Try the fourty oldest or most available volumes.  Note,
52       *   the most available could already be mounted on another
53       *   drive, so we continue looking for a not in use Volume.
54       */
55      lock_reservations();
56      P(vol_info_mutex);
57      dcr->volume_in_use = false;
58 -    for (int vol_index=1;  vol_index < 20; vol_index++) {
59 +    for (int vol_index=1;  vol_index < 40; vol_index++) {
60         bash_spaces(dcr->media_type);
61         bash_spaces(dcr->pool_name);
62         dir->fsend(Find_media, jcr->Job, vol_index, dcr->pool_name, dcr->media_type);
63 @@ -275,33 +274,26 @@
64         bool ok = do_get_volume_info(dcr);
65         if (ok) {
66            if (!is_volume_in_use(dcr)) {
67 -             found = true;
68 -             break;
69 +             Dmsg0(400, "dir_find_next_appendable_volume return true\n");
70 +             if (reserve_volume(dcr, dcr->VolumeName) == 0) {
71 +                Dmsg2(100, "Could not reserve volume %s on %s\n", dcr->VolumeName,
72 +                    dcr->dev->print_name());
73 +                continue;
74 +             }
75 +             V(vol_info_mutex);
76 +             unlock_reservations();
77 +             return true;
78            } else {
79               Dmsg1(100, "Volume %s is in use.\n", dcr->VolumeName);
80               dcr->volume_in_use = true;
81               continue;
82            }
83 -       } else {
84 -          Dmsg2(100, "No vol. index %d return false. dev=%s\n", vol_index,
85 -             dcr->dev->print_name());
86 -          found = false;
87 -          break;
88         }
89 +       Dmsg2(100, "No vol. index %d return false. dev=%s\n", vol_index,
90 +          dcr->dev->print_name());
91 +       break;
92      }
93 -    if (found) {
94 -       Dmsg0(400, "dir_find_next_appendable_volume return true\n");
95 -       if (reserve_volume(dcr, dcr->VolumeName) == 0) {
96 -          Dmsg2(100, "Could not reserve volume %s on %s\n", dcr->VolumeName,
97 -              dcr->dev->print_name());
98 -          goto bail_out;
99 -       }
100 -       V(vol_info_mutex);
101 -       unlock_reservations();
102 -       return true;
103 -    }
104  
105 -bail_out:
106      dcr->VolumeName[0] = 0;
107      V(vol_info_mutex);
108      unlock_reservations();
109 Index: src/stored/acquire.c
110 ===================================================================
111 --- src/stored/acquire.c        (revision 6531)
112 +++ src/stored/acquire.c        (working copy)
113 @@ -362,7 +362,10 @@
114              strcmp(dev->VolHdr.VolumeName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
115           /* Wrong tape mounted, release it, then fall through to get correct one */
116           Dmsg0(50, "Wrong tape mounted, release and try mount.\n");
117 -         release = true;
118 +         /* Do not release if no Volume in drive */
119 +         if (dev->VolHdr.VolumeName[0]) {
120 +            release = true;
121 +         }
122           do_mount = true;
123        } else {
124           /*