" VolWriteTime=%s EndFile=%u EndBlock=%u VolType=%u LabelType=%d"
" MediaId=%s ScratchPoolId=%s VolParts=%d VolCloudParts=%d"
" LastPartBytes=%lld Enabled=%d MaxPoolBytes=%s PoolBytes=%s Recycle=%d"
- " Protected=%d UseProtect=%d VolEncrypted=%d\n";
+ " Protected=%d UseProtect=%d VolEncrypted=%d VolRetention=%u\n";
static char OK_create[] = "1000 OK CreateJobMedia\n";
mr->Enabled,
edit_uint64(pr.MaxPoolBytes, ed11),
edit_uint64(pr.PoolBytes, ed12),
- mr->Recycle, mr->Protected, mr->UseProtect, mr->VolEncrypted);
+ mr->Recycle, mr->Protected, mr->UseProtect, mr->VolEncrypted, mr->VolRetention);
unbash_spaces(mr->VolumeName);
Dmsg2(100, "Vol Info for %s: %s", jcr->Job, sd->msg);
return stat;
char volname[MAX_NAME_LENGTH];
char storage[MAX_NAME_LENGTH];
char mediatype[MAX_NAME_LENGTH];
+ uint32_t retention;
};
/*
{
alist *val = (alist *)ctx;
- if (row[0] && row[1] && row[2] && row[3]) {
+ if (row[0] && row[1] && row[2] && row[3] && row[4]) {
struct media_protect *a = (struct media_protect *)malloc(sizeof(struct media_protect));
a->id = str_to_uint64(row[0]);
bstrncpy(a->mediatype, row[1], sizeof(a->mediatype));
bstrncpy(a->volname, row[2], sizeof(a->volname));
bstrncpy(a->storage, row[3], sizeof(a->storage));
+ a->retention = str_to_uint64(row[4]);
val->append(a);
}
return 0;
}
- Mmsg(tmp, "SELECT Media.MediaId, Media.MediaType, Media.VolumeName, Storage.Name "
- "FROM Media JOIN Storage USING (StorageId) JOIN Pool USING (PoolId) "
- "WHERE UseProtect=1 AND Protected=0 AND VolStatus IN ('Used', 'Full') %s "
- "ORDER BY Storage.Name", filter.c_str());
+ db_lock(ua->db);
+ const char *where_pool = ua->db->get_acls(DB_ACL_BIT(DB_ACL_POOL), false);
+ /* We use DISTINCT because when looking with JobId, we can get multiple time the same record */
+ Mmsg(tmp, "SELECT DISTINCT Media.MediaId, Media.MediaType, Media.VolumeName, Storage.Name, Media.VolRetention "
+ "FROM Media JOIN Storage USING (StorageId) JOIN Pool USING (PoolId) %s "
+ "WHERE UseProtect=1 AND Protected=0 AND VolStatus IN ('Used', 'Full') %s %s "
+ "ORDER BY Storage.Name", join_job, filter.c_str(), where_pool);
+ db_unlock(ua->db);
db_sql_query(ua->db, tmp.c_str(),
media_protect_list_handler, &list);
bash_spaces(selected_dev_name);
bash_spaces(elt->volname);
- sd->fsend("volumeprotect mediatype=%s device=%s volume=%s drive=%d\n",
- elt->mediatype, selected_dev_name, elt->volname, drive);
+ sd->fsend("volumeprotect mediatype=%s device=%s volume=%s drive=%d retention=%u\n",
+ elt->mediatype, selected_dev_name, elt->volname, drive, elt->retention);
unbash_spaces(elt->mediatype);
unbash_spaces(selected_dev_name);
" VolReadTime=%lld VolWriteTime=%lld EndFile=%lu EndBlock=%lu"
" VolType=%lu LabelType=%ld MediaId=%lld ScratchPoolId=%lld"
" VolParts=%d VolCloudParts=%d LastPartBytes=%lld Enabled=%d MaxPoolBytes=%lld PoolBytes=%lld Recycle=%d"
- " Protected=%d UseProtect=%d VolEncrypted=%d\n";
+ " Protected=%d UseProtect=%d VolEncrypted=%d VolRetention=%u\n";
static char OK_create[] = "1000 OK CreateJobMedia\n";
&vol.LabelType, &vol.VolMediaId, &vol.VolScratchPoolId,
&vol.VolCatParts, &vol.VolCatCloudParts,
&vol.VolLastPartBytes, &Enabled, &vol.MaxPoolBytes,
- &vol.PoolBytes, &Recycle, &Protected, &UseProtect, &VolEncrypted);
+ &vol.PoolBytes, &Recycle, &Protected, &UseProtect, &VolEncrypted, &vol.VolRetention);
Dmsg2(dbglvl, "<dird n=%d %s", n, dir->msg);
- if (n != 36) {
+ if (n != 37) {
Dmsg1(dbglvl, "get_volume_info failed: ERR=%s", dir->msg);
/*
* Note, we can get an error here either because there is
dev->getVolCatName());
}
- 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 {
- if (!quiet) {
- Jmsg(dcr->jcr, M_INFO, 0, _("Marking Volume \"%s\" as immutable\n"),
- dev->getVolCatName());
- }
- events_send_msg(dcr->jcr, "SJ0003", EVENTS_TYPE_VOLUME, me->hdr.name, (intptr_t)dcr->jcr,
- "Mark Volume \"%s\" as immutable", dev->getVolCatName());;
- dev->VolCatInfo.Protected = 1;
- }
- }
-
if (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(), time(NULL) + dev->device->min_volume_protection_time) < 0) {
+ if (dev->set_atime(dev->m_fd, dev->getVolCatName(), time(NULL) + 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);
}
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];
+ edit_utime(when, buf, sizeof(buf));
if (!quiet) {
- Jmsg(dcr->jcr, M_INFO, 0, _("Marking Volume \"%s\" as read-only\n"),
+ Jmsg(dcr->jcr, M_INFO, 0, _("Marking Volume \"%s\" as read-only. Retention set to %s.\n"), buf,
dev->getVolCatName());
}
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", dev->getVolCatName());;
+ "Mark Volume \"%s\" as read-only. retention %s.", dev->getVolCatName(), 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 {
+ if (!quiet) {
+ Jmsg(dcr->jcr, M_INFO, 0, _("Marking Volume \"%s\" as immutable\n"),
+ dev->getVolCatName());
+ }
+ events_send_msg(dcr->jcr, "SJ0003", EVENTS_TYPE_VOLUME, me->hdr.name, (intptr_t)dcr->jcr,
+ "Mark Volume \"%s\" as immutable", dev->getVolCatName());;
+ dev->VolCatInfo.Protected = 1;
+ }
+ }
Dmsg4(100, "Maximum volume size %s exceeded Vol=%s device=%s.\n"
"Marking Volume \"%s\" as Full.\n",
edit_uint64_with_commas(max_size, ed1), dev->getVolCatName(),
uint32_t VolCatRecycles; /* Number of recycles this volume */
uint32_t EndFile; /* Last file number */
uint32_t EndBlock; /* Last block number */
-
+ uint32_t VolRetention; /* Volume Retention */
+
int32_t LabelType; /* Bacula/ANSI/IBM */
int32_t Slot; /* >0=Slot loaded, 0=nothing, -1=unknown */
uint32_t VolCatMaxJobs; /* Maximum Jobs to write to volume */
char mediatype[MAX_NAME_LENGTH];
char volume[MAX_NAME_LENGTH];
POOL_MEM device, tmp;
+ uint32_t retention;
int32_t drive;
bool ok;
- ok = sscanf(dir->msg, "volumeprotect mediatype=%127s device=%127s volume=%127s drive=%d",
- mediatype, device.c_str(), volume, &drive) == 4;
+ ok = sscanf(dir->msg, "volumeprotect mediatype=%127s device=%127s volume=%127s drive=%d retention=%u",
+ mediatype, device.c_str(), volume, &drive, &retention) == 5;
if (ok) {
unbash_spaces(mediatype);
unbash_spaces(device.c_str());
} else if (dev->device->set_vol_read_only) {
/* Set volume as immutable/read only */
pm_strcpy(tmp, "");
- if (dev->set_atime(-1, volume, time(NULL) + dev->device->min_volume_protection_time) < 0) {
+ uint32_t when = MAX(dev->device->min_volume_protection_time, retention);
+ if (dev->set_atime(-1, volume, time(NULL) + 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());
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 {
- dir->fsend(_("3000 Marking volume \"%s\" as read-only.\n"), volume);
+ char buf[128];
+ dir->fsend(_("3000 Marking volume \"%s\" as read-only. Retention set to %s.\n"),
+ volume, edit_utime(when, buf, sizeof(buf)));
events_send_msg(jcr, "SJ0003", EVENTS_TYPE_VOLUME, me->hdr.name, (intptr_t)jcr,
- "Mark volume \"%s\" as read-only", volume);
+ "Mark volume \"%s\" as read-only, retention %s", volume, buf);
}
} else {
dir->fsend(_("3900 Device %s not configured for ReadOnly or Immutable\n"), dev->device->hdr.name);