From: Eric Bollengier Date: Thu, 2 Sep 2010 13:52:23 +0000 (+0200) Subject: Fix bug #1601 where prune client pool=xx apply pool retention for all volumes. X-Git-Tag: Release-5.2.1~1136 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=6b67f953ed9d47382b457e0ce322fd1feba10ac1;p=bacula%2Fbacula Fix bug #1601 where prune client pool=xx apply pool retention for all volumes. --- diff --git a/bacula/src/baconfig.h b/bacula/src/baconfig.h index f704fbe69d..9ab945a4eb 100644 --- a/bacula/src/baconfig.h +++ b/bacula/src/baconfig.h @@ -166,6 +166,9 @@ void InitWinAPIWrapper(); /* Maximum Name length including EOS */ #define MAX_NAME_LENGTH 128 +/* Maximum escaped Name lenght including EOS 2*MAX_NAME_LENGTH+1 */ +#define MAX_ESCAPE_NAME_LENGTH 257 + /* Maximume number of user entered command args */ #define MAX_CMD_ARGS 30 diff --git a/bacula/src/dird/ua_prune.c b/bacula/src/dird/ua_prune.c index edef66ded0..ef5131d5dd 100644 --- a/bacula/src/dird/ua_prune.c +++ b/bacula/src/dird/ua_prune.c @@ -215,6 +215,46 @@ int prune_stats(UAContext *ua, utime_t retention) return true; } +/* + * Use pool and client specified by user to select jobs to prune + * returns add_from string to add in FROM clause + * add_where string to add in WHERE clause + */ +bool prune_set_filter(UAContext *ua, CLIENT *client, POOL *pool, utime_t period, + POOL_MEM *add_from, POOL_MEM *add_where) +{ + utime_t now; + char ed1[50], ed2[MAX_ESCAPE_NAME_LENGTH]; + POOL_MEM tmp(PM_MESSAGE); + + now = (utime_t)time(NULL); + edit_int64(now - period, ed1); + Dmsg3(150, "now=%lld period=%lld JobTDate=%s\n", now, period, ed1); + Mmsg(tmp, " AND JobTDate < %s ", ed1); + pm_strcat(*add_where, tmp.c_str()); + + db_lock(ua->db); + if (client) { + db_escape_string(ua->jcr, ua->db, ed2, + client->name(), strlen(client->name())); + Mmsg(tmp, " AND Client.Name = '%s' ", ed2); + pm_strcat(*add_where, tmp.c_str()); + pm_strcat(*add_from, " JOIN Client USING (ClientId) "); + } + + if (pool) { + db_escape_string(ua->jcr, ua->db, ed2, + pool->name(), strlen(pool->name())); + Mmsg(tmp, " AND Pool.Name = '%s' ", ed2); + pm_strcat(*add_where, tmp.c_str()); + /* Use ON() instead of USING for some old SQLite */ + pm_strcat(*add_from, " JOIN Pool ON (Job.PoolId = Pool.PoolId) "); + } + Dmsg2(150, "f=%s w=%s\n", add_from->c_str(), add_where->c_str()); + db_unlock(ua->db); + return true; +} + /* * Prune File records from the database. For any Job which * is older than the retention period, we unconditionally delete @@ -226,41 +266,44 @@ 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. + * Note: client or pool can possibly be NULL (not both). */ int prune_files(UAContext *ua, CLIENT *client, POOL *pool) { struct del_ctx del; struct s_count_ctx cnt; POOL_MEM query(PM_MESSAGE); - utime_t now, period; - CLIENT_DBR cr; - char ed1[50], ed2[50]; - - db_lock(ua->db); - memset(&cr, 0, sizeof(cr)); + POOL_MEM sql_where(PM_MESSAGE); + POOL_MEM sql_from(PM_MESSAGE); + utime_t period; + char ed1[50]; + memset(&del, 0, sizeof(del)); - bstrncpy(cr.Name, client->name(), sizeof(cr.Name)); - if (!db_create_client_record(ua->jcr, ua->db, &cr)) { - db_unlock(ua->db); - return 0; - } if (pool && pool->FileRetention > 0) { period = pool->FileRetention; - } else { + + } else if (client) { period = client->FileRetention; + + } else { /* should specify at least pool or client */ + return false; + } + + db_lock(ua->db); + /* Specify JobTDate and Pool.Name= and/or Client.Name= in the query */ + if (!prune_set_filter(ua, client, pool, period, &sql_from, &sql_where)) { + goto bail_out; } - now = (utime_t)time(NULL); // edit_utime(now-period, ed1, sizeof(ed1)); // Jmsg(ua->jcr, M_INFO, 0, _("Begin pruning Jobs older than %s secs.\n"), ed1); Jmsg(ua->jcr, M_INFO, 0, _("Begin pruning Jobs.\n")); /* 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()); + Mmsg(query, + "SELECT COUNT(1) FROM Job %s WHERE PurgedFiles=0 %s", + sql_from.c_str(), sql_where.c_str()); + Dmsg1(050, "select sql=%s\n", query.c_str()); cnt.count = 0; if (!db_sql_query(ua->db, query.c_str(), del_count_handler, (void *)&cnt)) { ua->error_msg("%s", db_strerror(ua->db)); @@ -285,8 +328,9 @@ int prune_files(UAContext *ua, CLIENT *client, POOL *pool) del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids); /* Now process same set but making a delete list */ - Mmsg(query, select_job, edit_int64(now - period, ed1), - edit_int64(cr.ClientId, ed2)); + Mmsg(query, "SELECT JobId FROM Job %s WHERE PurgedFiles=0 %s", + sql_from.c_str(), sql_where.c_str()); + Dmsg1(050, "select sql=%s\n", query.c_str()); db_sql_query(ua->db, query.c_str(), file_delete_handler, (void *)&del); purge_files_from_job_list(ua, del); @@ -398,31 +442,32 @@ static int job_select_handler(void *ctx, int num_fields, char **row) */ int prune_jobs(UAContext *ua, CLIENT *client, POOL *pool, int JobType) { - struct del_ctx del; POOL_MEM query(PM_MESSAGE); - utime_t now, period; - CLIENT_DBR cr ; - char ed1[50], ed2[50]; + POOL_MEM sql_where(PM_MESSAGE); + POOL_MEM sql_from(PM_MESSAGE); + utime_t period; + char ed1[50]; alist *jobids_check=NULL; struct accurate_check_ctx *elt; db_list_ctx jobids, tempids; JOB_DBR jr; - - db_lock(ua->db); - memset(&cr, 0, sizeof(cr)); - - bstrncpy(cr.Name, client->name(), sizeof(cr.Name)); - if (!db_create_client_record(ua->jcr, ua->db, &cr)) { - db_unlock(ua->db); - return 0; - } + struct del_ctx del; + memset(&del, 0, sizeof(del)); if (pool && pool->JobRetention > 0) { period = pool->JobRetention; - } else { + + } else if (client) { period = client->JobRetention; + + } else { /* should specify at least pool or client */ + return false; + } + + db_lock(ua->db); + if (!prune_set_filter(ua, client, pool, period, &sql_from, &sql_where)) { + goto bail_out; } - now = (utime_t)time(NULL); /* Drop any previous temporary tables still there */ drop_temp_tables(ua); @@ -435,10 +480,6 @@ int prune_jobs(UAContext *ua, CLIENT *client, POOL *pool, int JobType) edit_utime(period, ed1, sizeof(ed1)); Jmsg(ua->jcr, M_INFO, 0, _("Begin pruning Jobs older than %s.\n"), ed1); - edit_int64(now - period, ed1); /* Jobs older than ed1 are good candidates */ - edit_int64(cr.ClientId, ed2); - - memset(&del, 0, sizeof(del)); del.max_ids = 100; del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids); del.PurgedFiles = (char *)malloc(del.max_ids); @@ -450,11 +491,12 @@ int prune_jobs(UAContext *ua, CLIENT *client, POOL *pool, int JobType) Mmsg(query, "INSERT INTO DelCandidates " "SELECT JobId,PurgedFiles,FileSetId,JobFiles,JobStatus " - "FROM Job " + "FROM Job %s " /* JOIN Pool/Client */ "WHERE Type IN ('B', 'C', 'M', 'V', 'D', 'R', 'c', 'm', 'g') " - "AND JobTDate<%s AND ClientId=%s", - ed1, ed2); + " %s ", /* Pool/Client + JobTDate */ + sql_from.c_str(), sql_where.c_str()); + Dmsg1(050, "select sql=%s\n", query.c_str()); if (!db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL)) { if (ua->verbose) { ua->error_msg("%s", db_strerror(ua->db)); @@ -505,11 +547,11 @@ int prune_jobs(UAContext *ua, CLIENT *client, POOL *pool, int JobType) */ Mmsg(query, "SELECT JobId, JobTDate " - "FROM Job " - "WHERE JobTDate<%s AND ClientId=%s " - "AND Type='V' AND Level='V' " + "FROM Job %s " /* JOIN Client/Pool */ + "WHERE Type='V' AND Level='V' " + " %s " /* Pool, JobTDate, Client */ "ORDER BY JobTDate DESC LIMIT 1", - ed1, ed2); + sql_from.c_str(), sql_where.c_str()); if (!db_sql_query(ua->db, query.c_str(), db_list_handler, &jobids)) { ua->error_msg("%s", db_strerror(ua->db));