From: Eric Bollengier Date: Tue, 26 Sep 2023 15:06:37 +0000 (+0200) Subject: Fix #10401 About issue when truncating immutable volume X-Git-Tag: Beta-15.0.1~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b6c79821026de3c031d5662ec25c93fefa94dbfa;p=thirdparty%2Fbacula.git Fix #10401 About issue when truncating immutable volume - The protection time was not set in with the immutability flag - The information message for immutability has now the retention time - The errno checked in open_device was ACCESS instead of PERM --- diff --git a/bacula/src/stored/block_util.c b/bacula/src/stored/block_util.c index 3879474c2..1f50854a6 100644 --- a/bacula/src/stored/block_util.c +++ b/bacula/src/stored/block_util.c @@ -839,47 +839,47 @@ bool terminate_writing_volume(DCR *dcr) if (bstrcmp(dev->VolCatInfo.VolCatStatus, "Append")) { dev->setVolCatStatus("Full"); } - - if (dev->device->set_vol_read_only) { - btime_t now = time(NULL); + char buf[128], buf2[128]; + if (dev->device->set_vol_immutable || dev->device->set_vol_read_only) { uint32_t when = MAX(dev->device->min_volume_protection_time, dev->VolCatInfo.VolRetention); - dev->VolCatInfo.UseProtect = 1; - /* Set volume as immutable/read only */ - if (dev->set_atime(dev->m_fd, dev->getVolCatName(), now + when) < 0) { - Jmsg(dcr->jcr, M_WARNING, 0, _("Failed to set the volume %s on device %s in atime retention, ERR=%s.\n"), + btime_t now = time(NULL); + if (dev->set_atime(-1, dev->getVolCatName(), now + when) < 0) { + Jmsg(dcr->jcr, M_WARNING, 0, _(" Failed to set the volume %s on device %s in atime retention, ERR=%s.\n"), dev->getVolCatName(), dev->print_name(), dev->errmsg); } + bstrftime(buf2, sizeof(buf2), now+when); + strip_trailing_junk(edit_utime(when, buf, sizeof(buf))); + dev->VolCatInfo.UseProtect = 1; + } + + if (dev->device->set_vol_read_only) { + /* Set volume as immutable/read only */ if (dev->set_readonly(dev->m_fd, dev->getVolCatName()) < 0) { berrno be; /* We may proceed with that but warn the user */ Jmsg(dcr->jcr, M_WARNING, 0, _("Failed to set the volume %s on device %s in read-only, ERR=%s.\n"), dev->getVolCatName(), dev->print_name(), be.bstrerror()); } else { - char buf[128], buf2[128]; - strip_trailing_junk(edit_utime(when, buf, sizeof(buf))); - bstrftime(buf2, sizeof(buf2), now+when); - Jmsg(dcr->jcr, M_INFO, 0, _("Marking Volume \"%s\" as read-only. Retention set to %s (%s).\n"), dev->getVolCatName(), buf2, buf); dev->VolCatInfo.Protected = 1; events_send_msg(dcr->jcr, "SJ0003", EVENTS_TYPE_VOLUME, me->hdr.name, (intptr_t)dcr->jcr, - "Mark Volume \"%s\" as read-only. retention %s.", dev->getVolCatName(), buf);; + "Mark Volume \"%s\" as read-only. Retention set to %s (%s).", dev->getVolCatName(), buf2, buf); } } if (dev->device->set_vol_immutable) { - dev->VolCatInfo.UseProtect = 1; /* Set volume as immutable */ if (!dev->set_immutable(dev->getVolCatName(), &dev->errmsg)) { /* We may proceed with that but warn the user */ Jmsg(dcr->jcr, M_WARNING, 0, _("Failed to set the volume %s on device %s as immutable, ERR=%s.\n"), dev->getVolCatName(), dev->print_name(), dev->errmsg); } else { - Jmsg(dcr->jcr, M_INFO, 0, _("Marking Volume \"%s\" as immutable\n"), - dev->getVolCatName()); + Jmsg(dcr->jcr, M_INFO, 0, _("Marking Volume \"%s\" as immutable. Retention set to %s (%s).\n"), + dev->getVolCatName(), buf2, buf); events_send_msg(dcr->jcr, "SJ0003", EVENTS_TYPE_VOLUME, me->hdr.name, (intptr_t)dcr->jcr, - "Mark Volume \"%s\" as immutable", dev->getVolCatName());; + "Mark Volume \"%s\" as immutable. Retention set to %s (%s).", dev->getVolCatName(), buf2, buf);; dev->VolCatInfo.Protected = 1; } } diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index d9bea49d9..ebbcec0cb 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -1360,6 +1360,19 @@ static bool volumeprotect_cmd(JCR *jcr) /* Everything can be done without a lock because we don't touch anything * inside the device structure */ + char buf[128], buf2[128]; + if (dev->device->set_vol_immutable || dev->device->set_vol_read_only) { + uint32_t when = MAX(dev->device->min_volume_protection_time, retention); + btime_t now = time(NULL); + if (dev->set_atime(-1, volume, now + when) < 0) { + berrno be; + Mmsg(tmp, _(" Failed to set the volume %s on device %s in atime retention, ERR=%s.\n"), + volume, dev->print_name(), be.bstrerror()); + } + pm_strcpy(tmp, ""); + bstrftime(buf2, sizeof(buf2), now+when); + strip_trailing_junk(edit_utime(when, buf, sizeof(buf))); + } if (dev->device->set_vol_immutable) { /* Set volume as immutable */ if (!dev->set_immutable(volume, tmp.handle())) { @@ -1367,32 +1380,21 @@ static bool volumeprotect_cmd(JCR *jcr) dir->fsend(_("3900 Unable to set immutable flag %s\n"), tmp.c_str()); } else { - dir->fsend(_("3000 Mark volume \"%s\" as immutable\n"), volume); + dir->fsend(_("3000 Mark volume \"%s\" as immutable. Retention set to %s (%s).\n"), volume, buf2, buf); events_send_msg(jcr, "SJ0003", EVENTS_TYPE_VOLUME, me->hdr.name, (intptr_t)jcr, - "Mark volume \"%s\" as immutable", volume); + "Mark volume \"%s\" as immutable, retention %s (%s)", volume, buf2, buf); } } else if (dev->device->set_vol_read_only) { /* Set volume as immutable/read only */ - pm_strcpy(tmp, ""); - uint32_t when = MAX(dev->device->min_volume_protection_time, retention); - btime_t now = time(NULL); - if (dev->set_atime(-1, volume, now + when) < 0) { - berrno be; - Mmsg(tmp, _(" Failed to set the volume %s on device %s in atime retention, ERR=%s.\n"), - volume, dev->print_name(), be.bstrerror()); - } if (dev->set_readonly(-1, volume) < 0) { berrno be; /* We may proceed with that but warn the user */ dir->fsend(_("3900 Failed to set the volume %s on device %s in read-only, ERR=%s.%s\n"), volume, dev->print_name(), be.bstrerror(), tmp.c_str()); } else { - char buf[128], buf2[128]; dir->fsend(_("3000 Marking volume \"%s\" as read-only. Retention set to %s (%s).\n"), - volume, - bstrftime(buf2, sizeof(buf2), now+when), - strip_trailing_junk(edit_utime(when, buf, sizeof(buf)))); + volume,buf2, buf); events_send_msg(jcr, "SJ0003", EVENTS_TYPE_VOLUME, me->hdr.name, (intptr_t)jcr, "Mark volume \"%s\" as read-only, retention %s (%s)", volume, buf2, buf); } diff --git a/bacula/src/stored/file_dev.c b/bacula/src/stored/file_dev.c index ef749b520..892de4f9a 100644 --- a/bacula/src/stored/file_dev.c +++ b/bacula/src/stored/file_dev.c @@ -202,7 +202,7 @@ bool file_dev::open_device(DCR *dcr, int omode) /* Use system open() */ if ((m_fd = ::open(archive_name.c_str(), mode|O_CLOEXEC|append, 0640)) < 0) { /* Open may fail if we want to write to the Immutable volume */ - if (errno == EACCES && use_protect()) { + if ((errno == EACCES || errno == EPERM) && use_protect()) { bool immutable = check_for_immutable(getVolCatName()); bool readonly = check_for_read_only(-1, getVolCatName()); Dmsg3(DT_VOLUME|40, "volume=%s immutable=%d readonly=%d\n", getVolCatName(), immutable, readonly);