From: Eric Bollengier Date: Tue, 13 Feb 2018 13:26:59 +0000 (+0100) Subject: Add prune option to select volumes from a/all pool(s) X-Git-Tag: Release-9.2.0~24 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e57068c66cab0f0ff33cac72596e5de4ef27f04a;p=thirdparty%2Fbacula.git Add prune option to select volumes from a/all pool(s) prune allfrompool pool=Default yes prune allpools allfrompool yes --- diff --git a/bacula/src/dird/ua_prune.c b/bacula/src/dird/ua_prune.c index 4cf0cc5b6..34bc4717d 100644 --- a/bacula/src/dird/ua_prune.c +++ b/bacula/src/dird/ua_prune.c @@ -31,6 +31,7 @@ /* Forward referenced functions */ static bool grow_del_list(struct del_ctx *del); static bool prune_expired_volumes(UAContext*); +static bool prune_selected_volumes(UAContext *ua); /* * Called here to count entries to be deleted @@ -168,19 +169,7 @@ int prunecmd(UAContext *ua, const char *cmd) if (find_arg(ua, "expired") >= 0) { return prune_expired_volumes(ua); } - - if (!select_pool_and_media_dbr(ua, &pr, &mr)) { - return false; - } - if (mr.Enabled == 2) { - ua->error_msg(_("Cannot prune Volume \"%s\" because it is archived.\n"), - mr.VolumeName); - return false; - } - if (!confirm_retention(ua, &mr.VolRetention, "Volume")) { - return false; - } - prune_volume(ua, &mr); + prune_selected_volumes(ua); return true; case 3: /* prune stats */ dir = (DIRRES *)GetNextRes(R_DIRECTOR, NULL); @@ -622,6 +611,57 @@ bail_out: return 1; } +static bool prune_selected_volumes(UAContext *ua) +{ + int nb=0; + uint32_t *results=NULL; + MEDIA_DBR mr; + POOL_DBR pr; + JCR *jcr = ua->jcr; + POOL_MEM tmp; + + mr.Recycle=1; /* Look for volumes to prune and recycle */ + + if (!scan_storage_cmd(ua, ua->cmd, false, /* fromallpool*/ + NULL /* drive */, + &mr, &pr, + NULL /* action */, + NULL /* storage */, + &nb, &results)) + { + goto bail_out; + } + for (int i = 0; i < nb; i++) { + mr.clear(); + mr.MediaId = results[i]; + if (!db_get_media_record(jcr, jcr->db, &mr)) { + ua->error_msg(_("Unable to get Media record for MediaId %d.\n"), mr.MediaId); + continue; + } + if (mr.Enabled == 2 || strcmp(mr.VolStatus, "Archive") == 0) { + ua->error_msg(_("Cannot prune Volume \"%s\" because it is archived.\n"), + mr.VolumeName); + continue; + } + if (strcmp(mr.VolStatus, "Full") != 0 && + strcmp(mr.VolStatus, "Used") != 0 ) + { + ua->error_msg(_("Cannot prune Volume \"%s\" because the volume status is \"%s\" and should be Full or Used.\n"), mr.VolumeName, mr.VolStatus); + continue; + } + Mmsg(tmp, "Volume \"%s\"", mr.VolumeName); + if (!confirm_retention(ua, &mr.VolRetention, tmp.c_str())) { + goto bail_out; + } + prune_volume(ua, &mr); + } + +bail_out: + if (results) { + free(results); + } + return true; +} /* * Prune a expired Volumes diff --git a/bacula/src/dird/ua_select.c b/bacula/src/dird/ua_select.c index c55229bbd..75cc67a3a 100644 --- a/bacula/src/dird/ua_select.c +++ b/bacula/src/dird/ua_select.c @@ -1530,10 +1530,16 @@ int scan_storage_cmd(UAContext *ua, const char *cmd, bool allpools=false, has_vol = false;; STORE *store; - *nb = 0; - *drive = 0; + *nb = 0; *results = NULL; - *storage = 0; + + /* Optional parameters */ + if (drive) { + *drive = 0; + } + if (storage) { + *storage = 0; + } /* Look at arguments */ for (int i=1; iargc; i++) { @@ -1553,7 +1559,11 @@ int scan_storage_cmd(UAContext *ua, const char *cmd, bstrncpy(mr->MediaType, ua->argv[i], sizeof(mr->MediaType)); } else if (strcasecmp(ua->argk[i], NT_("drive")) == 0 && ua->argv[i]) { - *drive = atoi(ua->argv[i]); + if (drive) { + *drive = atoi(ua->argv[i]); + } else { + ua->warning_msg(_("Invalid argument \"drive\".\n")); + } } else if (strcasecmp(ua->argk[i], NT_("action")) == 0 && is_name_valid(ua->argv[i], NULL)) { @@ -1566,12 +1576,15 @@ int scan_storage_cmd(UAContext *ua, const char *cmd, } } - /* Choose storage */ - ua->jcr->wstore = store = get_storage_resource(ua, false); - if (!store) { - goto bail_out; + if (storage) { + /* Choose storage */ + ua->jcr->wstore = store = get_storage_resource(ua, false); + if (!store) { + goto bail_out; + } + bstrncpy(storage, store->dev_name(), MAX_NAME_LENGTH); + set_storageid_in_mr(store, mr); } - bstrncpy(storage, store->dev_name(), MAX_NAME_LENGTH); if (!open_db(ua)) { Dmsg0(100, "Can't open db\n"); @@ -1582,7 +1595,6 @@ int scan_storage_cmd(UAContext *ua, const char *cmd, * Look for all volumes that are enabled */ mr->Enabled = 1; - set_storageid_in_mr(store, mr); if (allfrompool && !has_vol) { /* We need a list of volumes */ @@ -1615,12 +1627,11 @@ int scan_storage_cmd(UAContext *ua, const char *cmd, if (!select_media_dbr(ua, &mr2)) { goto bail_out; } - /* The select_media_dbr() doesn't filter on the CacheRetention */ - if (mr->CacheRetention) { - if ((mr2.CacheRetention + mr2.LastWritten) > time(NULL)) { - /* The volume cache retention is not exipred */ - goto bail_out; - } + mr->MediaId = mr2.MediaId; + mr->Recycle = mr2.Recycle; /* Should be the same to find a result */ + if (!db_get_media_ids(ua->jcr, ua->db, mr, nb, results)) { + Dmsg0(100, "No results from db_get_media_ids\n"); + goto bail_out; } *nb = 1; *results = (uint32_t *) malloc(1 * sizeof(uint32_t));