From: Alain Spineux Date: Fri, 6 Jan 2023 12:36:04 +0000 (+0100) Subject: fix Cannot free Volume XXX, because it is reserved by someone else X-Git-Tag: Beta-15.0.0~289 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f493e82b7427dbddf879230d8fb1dcb0cf685295;p=thirdparty%2Fbacula.git fix Cannot free Volume XXX, because it is reserved by someone else - when something goes wrong, sometime, the volume_unused() is not called and the volume stay stuck - always call volume_unused() in the "check_bail_out:" - load_encryption_key() can return a new error: VOL_ENC_ERROR that will trigger the call to volume_unused() --- diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index d7fcea0a3..0b5ddadc0 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -898,6 +898,7 @@ public: void mark_volume_in_error(); void mark_volume_read_only(); void mark_volume_not_inchanger(); + void volume_is_unavailable(); int try_autolabel(bool opened); bool find_a_volume(); bool is_suitable_volume_mounted(); diff --git a/bacula/src/stored/label.c b/bacula/src/stored/label.c index b1e7f7467..e0da0ea27 100644 --- a/bacula/src/stored/label.c +++ b/bacula/src/stored/label.c @@ -280,6 +280,11 @@ int DEVICE::read_dev_volume_label(DCR *dcr) } } + if (!load_encryption_key(dcr, "READ", VolHdr.VolumeName, &VolHdr.EncCypherKeySize, VolHdr.EncCypherKey, &VolHdr.MasterKeyIdSize, VolHdr.MasterKeyId)) { + stat = VOL_ENC_ERROR; + goto bail_out; /* a message is already loaded into jcr->errmsg */ + } + Dmsg1(100, "Call reserve_volume=%s\n", VolHdr.VolumeName); if (reserve_volume(dcr, VolHdr.VolumeName) == NULL) { if (!jcr->errmsg[0]) { @@ -291,11 +296,6 @@ int DEVICE::read_dev_volume_label(DCR *dcr) goto bail_out; } - if (!load_encryption_key(dcr, "READ", VolHdr.VolumeName, &VolHdr.EncCypherKeySize, VolHdr.EncCypherKey, &VolHdr.MasterKeyIdSize, VolHdr.MasterKeyId)) { - stat = VOL_LABEL_ERROR; - goto bail_out; /* a message is already loaded into jcr->errmsg */ - } - if (dcr->is_writing()) { empty_block(dcr->block); } diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index 6f8f2d8a4..8abfae889 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -541,6 +541,10 @@ int DCR::check_volume_label(bool &ask, bool &autochanger) break; } /* NOTE! Fall-through wanted. */ + case VOL_ENC_ERROR: + volume_is_unavailable(); + goto check_next_volume; + break; case VOL_NO_MEDIA: default: Dmsg0(200, "VOL_NO_MEDIA or default.\n"); @@ -569,6 +573,7 @@ check_next_volume: return check_next_vol; check_bail_out: + volume_unused(this); Leave(200); return check_error; @@ -738,6 +743,17 @@ int DCR::try_autolabel(bool opened) return try_default; } +/* + * The volume is unavailable (temporarily?) don't used it this time + */ +void DCR::volume_is_unavailable() +{ + Jmsg(jcr, M_INFO, 0, _("The Volume \"%s\" in unavailable now.\n"), + VolumeName); + volume_unused(this); + Dmsg0(50, "set_unload\n"); + dev->set_unload(); /* must get a new volume */ +} /* * Mark volume in error in catalog diff --git a/bacula/src/stored/record.h b/bacula/src/stored/record.h index 5558c1d18..2be545569 100644 --- a/bacula/src/stored/record.h +++ b/bacula/src/stored/record.h @@ -39,7 +39,8 @@ enum { VOL_VERSION_ERROR = 7, /* Bacula version error */ VOL_LABEL_ERROR = 8, /* Bad label type */ VOL_NO_MEDIA = 9, /* Hard error -- no media present */ - VOL_TYPE_ERROR = 10 /* Volume type (aligned/non-aligned) error */ + VOL_TYPE_ERROR = 10, /* Volume type (aligned/non-aligned) error */ + VOL_ENC_ERROR = 11 /* something wrong with the encryption key */ }; enum rec_state {