From feea3833d724dbbeb5813bb7ce9281ab5112a57b Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sun, 15 Nov 2009 21:44:43 +0100 Subject: [PATCH] Add Job and File Retention to Pool --- bacula/src/dird/autoprune.c | 8 ++--- bacula/src/dird/dird_conf.c | 9 +++-- bacula/src/dird/dird_conf.h | 4 ++- bacula/src/dird/protos.h | 4 +-- bacula/src/dird/ua_dotcmds.c | 3 +- bacula/src/dird/ua_prune.c | 67 +++++++++++++++++++++++++++--------- 6 files changed, 69 insertions(+), 26 deletions(-) diff --git a/bacula/src/dird/autoprune.c b/bacula/src/dird/autoprune.c index 31f09167ac..5bd14a87d9 100644 --- a/bacula/src/dird/autoprune.c +++ b/bacula/src/dird/autoprune.c @@ -50,6 +50,7 @@ void do_autoprune(JCR *jcr) { UAContext *ua; CLIENT *client; + POOL *pool; bool pruned; if (!jcr->client) { /* temp -- remove me */ @@ -58,18 +59,17 @@ void do_autoprune(JCR *jcr) ua = new_ua_context(jcr); client = jcr->client; + pool = jcr->pool; if (jcr->job->PruneJobs || jcr->client->AutoPrune) { - Jmsg(jcr, M_INFO, 0, _("Begin pruning Jobs.\n")); - prune_jobs(ua, client, jcr->get_JobType()); + prune_jobs(ua, client, pool, jcr->get_JobType()); pruned = true; } else { pruned = false; } if (jcr->job->PruneFiles || jcr->client->AutoPrune) { - Jmsg(jcr, M_INFO, 0, _("Begin pruning Files.\n")); - prune_files(ua, client); + prune_files(ua, client, pool); pruned = true; } if (pruned) { diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index 746da36db1..56b3e76bc8 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -307,7 +307,6 @@ RES_ITEM job_items[] = { {"maxstartdelay",store_time, ITEM(res_job.MaxStartDelay), 0, 0, 0}, {"maxfullinterval", store_time, ITEM(res_job.MaxFullInterval), 0, 0, 0}, {"maxdiffinterval", store_time, ITEM(res_job.MaxDiffInterval), 0, 0, 0}, - {"jobretention", store_time, ITEM(res_job.JobRetention), 0, 0, 0}, {"prefixlinks", store_bool, ITEM(res_job.PrefixLinks), 0, ITEM_DEFAULT, false}, {"prunejobs", store_bool, ITEM(res_job.PruneJobs), 0, ITEM_DEFAULT, false}, {"prunefiles", store_bool, ITEM(res_job.PruneFiles), 0, ITEM_DEFAULT, false}, @@ -404,6 +403,9 @@ static RES_ITEM pool_items[] = { {"scratchpool", store_res, ITEM(res_pool.ScratchPool), R_POOL, 0, 0}, {"copypool", store_alist_res, ITEM(res_pool.CopyPool), R_POOL, 0, 0}, {"catalog", store_res, ITEM(res_pool.catalog), R_CATALOG, 0, 0}, + {"fileretention", store_time, ITEM(res_pool.FileRetention), 0, 0, 0}, + {"jobretention", store_time, ITEM(res_pool.JobRetention), 0, 0, 0}, + {NULL, NULL, {0}, 0, 0, 0} }; @@ -951,7 +953,7 @@ next_run: sendit(sock, _(" RecyleOldest=%d PurgeOldest=%d ActionOnPurge=%d\n"), res->res_pool.recycle_oldest_volume, res->res_pool.purge_oldest_volume, - res->res_pool.action_on_purge); + res->res_pool.action_on_purge); sendit(sock, _(" MaxVolJobs=%d MaxVolFiles=%d MaxVolBytes=%s\n"), res->res_pool.MaxVolJobs, res->res_pool.MaxVolFiles, @@ -960,6 +962,9 @@ next_run: edit_utime(res->res_pool.MigrationTime, ed1, sizeof(ed1)), edit_uint64(res->res_pool.MigrationHighBytes, ed2), edit_uint64(res->res_pool.MigrationLowBytes, ed3)); + sendit(sock, _(" JobRetention=%s FileRetention=%s\n"), + edit_utime(res->res_client.JobRetention, ed1, sizeof(ed1)), + edit_utime(res->res_client.FileRetention, ed2, sizeof(ed2))); if (res->res_pool.NextPool) { sendit(sock, _(" NextPool=%s\n"), res->res_pool.NextPool->name()); } diff --git a/bacula/src/dird/dird_conf.h b/bacula/src/dird/dird_conf.h index 75fc49f627..9f19992a99 100644 --- a/bacula/src/dird/dird_conf.h +++ b/bacula/src/dird/dird_conf.h @@ -393,7 +393,6 @@ public: utime_t MaxStartDelay; /* max start delay in seconds */ utime_t MaxRunSchedTime; /* max run time in seconds from Scheduled time*/ utime_t RescheduleInterval; /* Reschedule interval */ - utime_t JobRetention; /* job retention period in seconds */ utime_t MaxFullInterval; /* Maximum time interval between Fulls */ utime_t MaxDiffInterval; /* Maximum time interval between Diffs */ utime_t DuplicateJobProximity; /* Permitted time between duplicicates */ @@ -567,6 +566,9 @@ public: POOL *ScratchPool; /* ScratchPool source when requesting media */ alist *CopyPool; /* List of copy pools */ CAT *catalog; /* Catalog to be used */ + utime_t FileRetention; /* file retention period in seconds */ + utime_t JobRetention; /* job retention period in seconds */ + /* Methods */ char *name() const; }; diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index a19bdded4d..6d99a859d8 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -279,8 +279,8 @@ bool user_select_files_from_tree(TREE_CTX *tree); int insert_tree_handler(void *ctx, int num_fields, char **row); /* ua_prune.c */ -int prune_files(UAContext *ua, CLIENT *client); -int prune_jobs(UAContext *ua, CLIENT *client, int JobType); +int prune_files(UAContext *ua, CLIENT *client, POOL *pool); +int prune_jobs(UAContext *ua, CLIENT *client, POOL *pool, int JobType); int prune_stats(UAContext *ua, utime_t retention); bool prune_volume(UAContext *ua, MEDIA_DBR *mr); int job_delete_handler(void *ctx, int num_fields, char **row); diff --git a/bacula/src/dird/ua_dotcmds.c b/bacula/src/dird/ua_dotcmds.c index ef777e2078..0e37efc6d1 100644 --- a/bacula/src/dird/ua_dotcmds.c +++ b/bacula/src/dird/ua_dotcmds.c @@ -35,7 +35,6 @@ * * Kern Sibbald, April MMII * - * Version $Id$ */ #include "bacula.h" @@ -872,6 +871,8 @@ static bool defaultscmd(UAContext *ua, const char *cmd) ua->send_msg("max_vol_bytes=%s", edit_uint64(pool->MaxVolBytes, ed1)); ua->send_msg("auto_prune=%d", pool->AutoPrune); ua->send_msg("recycle=%d", pool->Recycle); + ua->send_msg("file_retention=%s", edit_uint64(pool->FileRetention, ed1)); + ua->send_msg("job_retention=%s", edit_uint64(pool->JobRetention, ed1)); } } return true; diff --git a/bacula/src/dird/ua_prune.c b/bacula/src/dird/ua_prune.c index 9dc98f760d..336089b9a7 100644 --- a/bacula/src/dird/ua_prune.c +++ b/bacula/src/dird/ua_prune.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2002-2008 Free Software Foundation Europe e.V. + Copyright (C) 2002-2009 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -32,7 +32,6 @@ * * Kern Sibbald, February MMII * - * Version $Id$ */ #include "bacula.h" @@ -104,8 +103,8 @@ int file_delete_handler(void *ctx, int num_fields, char **row) /* * Prune records from database * - * prune files (from) client=xxx - * prune jobs (from) client=xxx + * prune files (from) client=xxx [pool=yyy] + * prune jobs (from) client=xxx [pool=yyy] * prune volume=xxx * prune stats */ @@ -113,6 +112,7 @@ int prunecmd(UAContext *ua, const char *cmd) { DIRRES *dir; CLIENT *client; + POOL *pool; POOL_DBR pr; MEDIA_DBR mr; utime_t retention; @@ -139,18 +139,38 @@ int prunecmd(UAContext *ua, const char *cmd) switch (kw) { case 0: /* prune files */ client = get_client_resource(ua); - if (!client || !confirm_retention(ua, &client->FileRetention, "File")) { + if (find_arg_with_value(ua, "pool") >= 0) { + pool = get_pool_resource(ua); + } else { + pool = NULL; + } + /* Pool File Retention takes precedence over client File Retention */ + if (pool && pool->FileRetention > 0) { + if (!confirm_retention(ua, &pool->FileRetention, "File")) { + return false; + } + } else if (!client || !confirm_retention(ua, &client->FileRetention, "File")) { return false; } - prune_files(ua, client); + prune_files(ua, client, pool); return true; case 1: /* prune jobs */ client = get_client_resource(ua); - if (!client || !confirm_retention(ua, &client->JobRetention, "Job")) { + if (find_arg_with_value(ua, "pool") >= 0) { + pool = get_pool_resource(ua); + } else { + pool = NULL; + } + /* Pool Job Retention takes precedence over client Job Retention */ + if (pool && pool->JobRetention > 0) { + if (!confirm_retention(ua, &pool->JobRetention, "Job")) { + return false; + } + } else if (!client || !confirm_retention(ua, &client->JobRetention, "Job")) { return false; } /* ****FIXME**** allow user to select JobType */ - prune_jobs(ua, client, JT_BACKUP); + prune_jobs(ua, client, pool, JT_BACKUP); return 1; case 2: /* prune volume */ if (!select_pool_and_media_dbr(ua, &pr, &mr)) { @@ -214,8 +234,10 @@ int prune_stats(UAContext *ua, utime_t retention) * * This routine assumes you want the pruning to be done. All checking * must be done before calling this routine. + * + * Note: pool can possibly be NULL. */ -int prune_files(UAContext *ua, CLIENT *client) +int prune_files(UAContext *ua, CLIENT *client, POOL *pool) { struct del_ctx del; struct s_count_ctx cnt; @@ -227,18 +249,24 @@ int prune_files(UAContext *ua, CLIENT *client) db_lock(ua->db); memset(&cr, 0, sizeof(cr)); memset(&del, 0, sizeof(del)); - bstrncpy(cr.Name, client->hdr.name, sizeof(cr.Name)); + bstrncpy(cr.Name, client->name(), sizeof(cr.Name)); if (!db_create_client_record(ua->jcr, ua->db, &cr)) { db_unlock(ua->db); return 0; } - period = client->FileRetention; + if (pool && pool->FileRetention > 0) { + period = pool->FileRetention; + } else { + period = client->FileRetention; + } now = (utime_t)time(NULL); - /* Select Jobs -- for counting */ - Mmsg(query, count_select_job, edit_int64(now - period, ed1), - edit_int64(cr.ClientId, ed2)); + edit_utime(now-period, ed1, sizeof(ed1)); + Jmsg(ua->jcr, M_INFO, 0, _("Begin pruning Jobs older than %s secs.\n"), ed1); + /* Select Jobs -- for counting */ + edit_int64(now - period, ed1); + Mmsg(query, count_select_job, ed1, edit_int64(cr.ClientId, ed2)); Dmsg3(050, "select now=%u period=%u sql=%s\n", (uint32_t)now, (uint32_t)period, query.c_str()); cnt.count = 0; @@ -322,7 +350,7 @@ static bool create_temp_tables(UAContext *ua) * * For Restore Jobs there are no restrictions. */ -int prune_jobs(UAContext *ua, CLIENT *client, int JobType) +int prune_jobs(UAContext *ua, CLIENT *client, POOL *pool, int JobType) { struct del_ctx del; POOL_MEM query(PM_MESSAGE); @@ -340,7 +368,11 @@ int prune_jobs(UAContext *ua, CLIENT *client, int JobType) return 0; } - period = client->JobRetention; + if (pool && pool->JobRetention > 0) { + period = pool->JobRetention; + } else { + period = client->JobRetention; + } now = (utime_t)time(NULL); /* Drop any previous temporary tables still there */ @@ -351,10 +383,13 @@ int prune_jobs(UAContext *ua, CLIENT *client, int JobType) goto bail_out; } + /* * Select all files that are older than the JobRetention period * and stuff them into the "DeletionCandidates" table. */ + edit_utime(now-period, ed1, sizeof(ed1)); + Jmsg(ua->jcr, M_INFO, 0, _("Begin pruning Jobs older than %s secs.\n"), ed1); edit_int64(now - period, ed1); Mmsg(query, insert_delcand, (char)JobType, ed1, edit_int64(cr.ClientId, ed2)); -- 2.39.5