From 334b3c15123147b0f4101e4257a7d42e660f68b4 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Fri, 11 Dec 2015 09:51:53 +0100 Subject: [PATCH] Fix truncate race bug #1382 Conflicts: bacula/src/stored/dircmd.c --- bacula/src/stored/dircmd.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 1a2e933e7a..b86c1d7f41 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -541,7 +541,7 @@ static bool do_label(JCR *jcr, int relabel) POOLMEM *newname, *oldname, *poolname, *mtype; POOL_MEM dev_name; BSOCK *dir = jcr->dir_bsock; - DCR *dcr; + DCR *dcr = NULL;; DEVICE *dev; bool ok = false; int32_t slot, drive; @@ -572,8 +572,34 @@ static bool do_label(JCR *jcr, int relabel) unbash_spaces(mtype); dcr = find_device(jcr, dev_name, mtype, drive); if (dcr) { + uint32_t max_jobs; dev = dcr->dev; + ok = true; dev->Lock(); /* Use P to avoid indefinite block */ +#ifdef DEVELOPER + if (chk_dbglvl(DT_VOLUME)) { + Dmsg0(0, "Waiting few seconds to force a bug...\n"); + bmicrosleep(30, 0); + } +#endif + max_jobs = dev->max_concurrent_jobs; + dev->max_concurrent_jobs = 1; + bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName)); + if (dcr->can_i_write_volume()) { + if (reserve_volume(dcr, newname) == NULL) { + ok = false; + } + Dmsg1(000, "Reserved volume \"%s\"\n", newname); + } else { + ok = false; + } + if (!ok) { + Dmsg2(000, "Reserve error on volume \"%s\": ERR=%s\n", newname, jcr->errmsg); + dir->fsend(_("3908 Error reserving volume: %s\n"), jcr->errmsg); + dev->max_concurrent_jobs = max_jobs; + dev->Unlock(); + goto bail_out; + } if (!dev->is_open() && !dev->is_busy()) { Dmsg1(400, "Can %slabel. Device is not open\n", relabel?"re":""); label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel); @@ -588,8 +614,9 @@ static bool do_label(JCR *jcr, int relabel) Dmsg0(400, "Can relabel. device not used\n"); label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel); } + dev->max_concurrent_jobs = max_jobs; dev->Unlock(); - free_dcr(dcr); + free_volume(dcr->dev); } else { dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), dev_name.c_str()); } @@ -598,6 +625,10 @@ static bool do_label(JCR *jcr, int relabel) pm_strcpy(jcr->errmsg, dir->msg); dir->fsend(_("3903 Error scanning label command: %s\n"), jcr->errmsg); } +bail_out: + if (dcr) { + free_dcr(dcr); + } free_memory(oldname); free_memory(newname); free_memory(poolname); -- 2.39.2