]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Fix #8566 About problem with reusing Immutable volume
authorMichal Rakowski <michal.rakowski@baculasystems.com>
Thu, 23 Dec 2021 15:27:32 +0000 (16:27 +0100)
committerEric Bollengier <eric@baculasystems.com>
Thu, 14 Sep 2023 11:56:57 +0000 (13:56 +0200)
bacula/src/stored/dircmd.c
bacula/src/stored/file_dev.c
bacula/src/stored/vol_mgr.c

index 8f01a35099ad8d24d57e1e5edca95a764a399f7a..b548da82bb2e0fb0190d4015fe8aec4c1a6d2f9b 100644 (file)
@@ -1040,33 +1040,12 @@ static void label_volume_if_ok(DCR *dcr, char *oldname,
       mode = CREATE_READ_WRITE;
    }
 
-   if (dev->check_volume_protection_time(volname)) {
-      if (!dev->open_device(dcr, mode)) {
-         /* Open with 'READ_WRITE' fails if immutable flag is set, check if that's the case */
-         if (dev->check_for_immutable(volname)) {
-            Dmsg1(DT_VOLUME|50, "Volume %s has the 'Immutable' flag set, need to clear it\n", volname);
-            /* Volume has immutable flag set, we need to clear it */
-            if (dev->clear_immutable(volname)) {
-               /* It should be now possible to open the device with desired mode */
-               if (dev->open_device(dcr, mode)) {
-                  opened = true;
-               }
-            } else {
-               dir->fsend(_("3929 Unable to clear immutable flag for device: \"%s\". ERR=%s\n"),
-                     dev->print_name(), dev->bstrerror());
-            }
-         }
-      } else {
-         opened = true;
-      }
+   if (!dev->open_device(dcr, mode)) {
+      dir->fsend(_("3929 Unable to open device \"%s\": ERR=%s\n"),
+            dev->print_name(), dev->bstrerror());
+      goto bail_out;
    }
 
-      if (!opened) {
-         dir->fsend(_("3929 Unable to open device \"%s\": ERR=%s\n"),
-               dev->print_name(), dev->bstrerror());
-         goto bail_out;
-      }
-
    /* See what we have for a Volume */
    label_status = dev->read_dev_volume_label(dcr);
 
index c4b7314ecbed09efdeccfe2b250be86d904267c0..450c2af2bb3b1b27bfff0c7d68bb90d3154f09af 100644 (file)
@@ -192,17 +192,42 @@ bool file_dev::open_device(DCR *dcr, int omode)
          archive_name.c_str(), mode);
    /* Use system open() */
    if ((m_fd = ::open(archive_name.c_str(), mode|O_CLOEXEC|append, 0640)) < 0) {
-      berrno be;
-      dev_errno = errno;
-      Mmsg3(errmsg, _("Could not open(%s,%s,0640): ERR=%s\n"),
-            archive_name.c_str(), mode_to_str(omode), be.bstrerror());
-      Dmsg1(40, "open failed: %s", errmsg);
-   } else {
+      /* Open may fail if we want to write to the Immutable volume */
+      if (errno == EPERM && check_for_immutable(getVolCatName())) {
+         /* Volume has immutable flag set, we need to clear it */
+         if (!check_volume_protection_time(getVolCatName())) {
+            /* Volume cannot be reused yet */
+            MmsgD1(dbglvl, errmsg, _("Cannot open Volume %s for writing/truncating, "
+                     "because Minimum Volume Protection Time hasn't expired yet\n"),
+                  getVolCatName());
+         } else {
+            /* Flag can be cleared, volume can probably be reused */
+            if (clear_immutable(getVolCatName())) {
+               /* It should be now possible to open the device with desired mode */
+               if ((m_fd = ::open(archive_name.c_str(), mode|O_CLOEXEC|append, 0640)) < 0) {
+                  berrno be;
+                  dev_errno = errno;
+                  Mmsg3(errmsg, _("Could not open(%s,%s,0640): ERR=%s\n"),
+                        archive_name.c_str(), mode_to_str(omode), be.bstrerror());
+                  Dmsg1(40, "open failed: %s", errmsg);
+               }
+            }
+         }
+      } else {
+         /* Volume is not immutable, that should succeed */
+         berrno be;
+         dev_errno = errno;
+         Mmsg3(errmsg, _("Could not open(%s,%s,0640): ERR=%s\n"),
+               archive_name.c_str(), mode_to_str(omode), be.bstrerror());
+         Dmsg1(40, "open failed: %s", errmsg);
+      }
+   }
+
+   if (m_fd >= 0) {
       /* Open is OK, now let device get control */
       Dmsg2(40, "Did open(%s,%s,0640)\n", archive_name.c_str(), mode_to_str(omode));
       device_specific_open(dcr);
-   }
-   if (m_fd >= 0) {
+
       dev_errno = 0;
       file = 0;
       file_addr = 0;
index 0bff7e6c2f67b50e54f2c436a5620f216ea0689d..766780b08ec604b3db2a8c24c7e168d7c1d0c194 100644 (file)
@@ -834,6 +834,14 @@ bool DCR::can_i_write_volume()
       Dmsg1(100, "Found in read list; cannot write vol=%s\n", VolumeName);
       return false;
    }
+
+   if (dev->check_for_immutable(VolumeName)) {
+      MmsgD1(dbglvl, jcr->errmsg, _("Skipping writing onto Volume %s, "
+                                    "because Volume's Protection Period has not expired yet\n"),
+             VolumeName);
+      return false;
+   }
+
    return can_i_use_volume();
 }