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.
11 This patch can be applied to a fully patched 2.2.8 version with the
15 patch -p0 <2.2.8-deadlock.patch
16 ./configure <your-options>
23 Index: src/dird/jobq.c
24 ===================================================================
25 --- src/dird/jobq.c (revision 6531)
26 +++ src/dird/jobq.c (working copy)
29 if (jcr->acquired_resource_locks) {
31 - jcr->rstore->NumConcurrentJobs = 0;
32 + jcr->rstore->NumConcurrentJobs--;
33 Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
36 Index: src/stored/askdir.c
37 ===================================================================
38 --- src/stored/askdir.c (revision 6531)
39 +++ src/stored/askdir.c (working copy)
43 BSOCK *dir = jcr->dir_bsock;
46 Dmsg2(200, "dir_find_next_appendable_volume: reserved=%d Vol=%s\n",
47 dcr->reserved_device, dcr->VolumeName);
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.
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);
64 bool ok = do_get_volume_info(dcr);
66 if (!is_volume_in_use(dcr)) {
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());
76 + unlock_reservations();
79 Dmsg1(100, "Volume %s is in use.\n", dcr->VolumeName);
80 dcr->volume_in_use = true;
84 - Dmsg2(100, "No vol. index %d return false. dev=%s\n", vol_index,
85 - dcr->dev->print_name());
89 + Dmsg2(100, "No vol. index %d return false. dev=%s\n", vol_index,
90 + dcr->dev->print_name());
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());
101 - unlock_reservations();
106 dcr->VolumeName[0] = 0;
108 unlock_reservations();
109 Index: src/stored/acquire.c
110 ===================================================================
111 --- src/stored/acquire.c (revision 6531)
112 +++ src/stored/acquire.c (working copy)
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");
118 + /* Do not release if no Volume in drive */
119 + if (dev->VolHdr.VolumeName[0]) {