From 7f620f23503a82431e9d225062c7db7c08f3a530 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Fri, 6 Jul 2007 20:03:36 +0000 Subject: [PATCH] kes Rework prune_volumes() code to take account of InChanger flag, and to handle recycling volumes going to the Scratch pool and current pool because the RecyclePool directive. kes Implement a better and more efficient db_get_query_dbids() to handle creating and passing back a list of DBIds. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@5124 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/ReleaseNotes | 1 - bacula/src/dird/autoprune.c | 86 ++++++++++++++++++++++++++----------- bacula/src/dird/next_vol.c | 11 +++-- bacula/src/dird/protos.h | 2 +- bacula/src/dird/recycle.c | 21 ++++----- bacula/src/dird/ua_cmds.c | 20 +++++++++ bacula/src/dird/ua_purge.c | 2 +- bacula/src/version.h | 4 +- bacula/technotes-2.1 | 6 +++ 9 files changed, 109 insertions(+), 44 deletions(-) diff --git a/bacula/ReleaseNotes b/bacula/ReleaseNotes index b26609be33..9a1c9ceaec 100644 --- a/bacula/ReleaseNotes +++ b/bacula/ReleaseNotes @@ -25,7 +25,6 @@ Changes since Beta release 2.1.22 migration code where a job that spanned two volumes was migrated twice. - Changes since Beta release 2.1.20 - New graphs in bat - Due to a typo, I had inadvertantly turned off batch insert mode. diff --git a/bacula/src/dird/autoprune.c b/bacula/src/dird/autoprune.c index aa45757f49..75359508c0 100644 --- a/bacula/src/dird/autoprune.c +++ b/bacula/src/dird/autoprune.c @@ -87,49 +87,84 @@ void do_autoprune(JCR *jcr) * Return: false if nothing pruned * true if pruned, and mr is set to pruned volume */ -bool prune_volumes(JCR *jcr, MEDIA_DBR *mr) +bool prune_volumes(JCR *jcr, bool InChanger, MEDIA_DBR *mr) { int count; int i; - uint32_t *ids = NULL; - int num_ids = 0; - struct del_ctx del; + dbid_list ids; + struct del_ctx prune_list; + POOL_MEM query(PM_MESSAGE); UAContext *ua; bool ok = false; + char ed1[50], ed2[100], ed3[50]; + POOL_DBR spr; Dmsg1(050, "Prune volumes PoolId=%d\n", jcr->jr.PoolId); if (!jcr->job->PruneVolumes && !jcr->pool->AutoPrune) { Dmsg0(100, "AutoPrune not set in Pool.\n"); return 0; } - memset(&del, 0, sizeof(del)); - del.max_ids = 10000; - del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids); + + memset(&prune_list, 0, sizeof(prune_list)); + prune_list.max_ids = 10000; + prune_list.JobId = (JobId_t *)malloc(sizeof(JobId_t) * prune_list.max_ids); ua = new_ua_context(jcr); db_lock(jcr->db); - /* Get the List of all media ids in the current Pool */ - if (!db_get_media_ids(jcr, jcr->db, mr, &num_ids, &ids)) { + /* Edit PoolId */ + edit_int64(mr->PoolId, ed1); + /* + * Get Pool record for Scratch Pool + */ + memset(&spr, 0, sizeof(spr)); + bstrncpy(spr.Name, "Scratch", sizeof(spr.Name)); + if (db_get_pool_record(jcr, jcr->db, &spr)) { + edit_int64(spr.PoolId, ed2); + bstrncat(ed2, ",", sizeof(ed2)); + } else { + ed2[0] = 0; + } + /* + * ed2 ends up with scratch poolid and current poolid or + * just current poolid if there is no scratch pool + */ + bstrncat(ed2, ed1, sizeof(ed2)); + + /* + * Get the List of all media ids in the current Pool or whose + * RecyclePoolId is the current pool or the scratch pool + */ + const char *select = "SELECT DISTINCT MediaId,LastWritten FROM Media WHERE " + "(PoolId=%s OR RecyclePoolId IN (%s)) AND MediaType='%s' %s" + "ORDER BY LastWritten ASC,MediaId"; + + if (InChanger) { + char changer[100]; + /* Ensure it is in this autochanger */ + bsnprintf(changer, sizeof(changer), "AND InChanger=1 AND StorageId=%s ", + edit_int64(mr->StorageId, ed3)); + Mmsg(query, select, ed1, ed2, mr->MediaType, changer); + } else { + Mmsg(query, select, ed1, ed2, mr->MediaType, ""); + } + + if (!db_get_query_dbids(ua->jcr, ua->db, query, ids)) { Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db)); goto bail_out; } - /* Visit each Volume and Prune it */ - for (i=0; idb, &lmr)) { Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db)); continue; } - /* Prune only Volumes from current Pool */ - if (mr->PoolId != lmr.PoolId) { - continue; - } /* Don't prune archived volumes */ if (lmr.Enabled == 2) { continue; @@ -138,14 +173,18 @@ bool prune_volumes(JCR *jcr, MEDIA_DBR *mr) if (strcmp(lmr.VolStatus, "Full") == 0 || strcmp(lmr.VolStatus, "Used") == 0) { Dmsg2(050, "Add prune list MediaId=%d Volume %s\n", (int)lmr.MediaId, lmr.VolumeName); - count = get_prune_list_for_volume(ua, &lmr, &del); + count = get_prune_list_for_volume(ua, &lmr, &prune_list); Dmsg1(050, "Num pruned = %d\n", count); if (count != 0) { - purge_job_list_from_catalog(ua, del); - del.num_ids = 0; /* reset count */ + purge_job_list_from_catalog(ua, prune_list); + prune_list.num_ids = 0; /* reset count */ } ok = is_volume_purged(ua, &lmr); - if (ok) { + /* + * If purged and not moved to another Pool, + * then we stop pruning and take this volume. + */ + if (ok && lmr.PoolId == mr->PoolId) { Dmsg2(050, "Vol=%s MediaId=%d purged.\n", lmr.VolumeName, (int)lmr.MediaId); mr = &lmr; /* struct copy */ break; @@ -156,11 +195,8 @@ bool prune_volumes(JCR *jcr, MEDIA_DBR *mr) bail_out: db_unlock(jcr->db); free_ua_context(ua); - if (ids) { - free(ids); - } - if (del.JobId) { - free(del.JobId); + if (prune_list.JobId) { + free(prune_list.JobId); } return ok; } diff --git a/bacula/src/dird/next_vol.c b/bacula/src/dird/next_vol.c index 10299cde03..da068fc52f 100644 --- a/bacula/src/dird/next_vol.c +++ b/bacula/src/dird/next_vol.c @@ -96,7 +96,7 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, */ Dmsg0(150, "Call prune_volumes\n"); if (prune) { - prune_volumes(jcr, mr); + prune_volumes(jcr, InChanger, mr); } ok = recycle_oldest_purged_volume(jcr, InChanger, mr); if (!ok) { @@ -406,14 +406,17 @@ static bool get_scratch_volume(JCR *jcr, MEDIA_DBR *mr, bool InChanger) memcpy(mr, &smr, sizeof(MEDIA_DBR)); /* Set default parameters from current pool */ set_pool_dbr_defaults_in_media_dbr(mr, &pr); - /* set_pool_dbr_defaults_in_media_dbr set VolStatus to Append, - * we could have Recycled media */ + /* + * set_pool_dbr_defaults_in_media_dbr set VolStatus to Append, + * we could have Recycled media, + */ bstrncpy(mr->VolStatus, smr.VolStatus, sizeof(smr.VolStatus)); if (!db_update_media_record(jcr, jcr->db, mr)) { Jmsg(jcr, M_WARNING, 0, _("Unable to update Volume record: ERR=%s"), db_strerror(jcr->db)); - ok = false; + goto bail_out; } + ok = true; } } bail_out: diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index 84e8637589..480abaa3a7 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -44,7 +44,7 @@ extern int authenticate_user_agent(UAContext *ua); /* autoprune.c */ extern void do_autoprune(JCR *jcr); -extern bool prune_volumes(JCR *jcr, MEDIA_DBR *mr); +extern bool prune_volumes(JCR *jcr, bool InChanger, MEDIA_DBR *mr); /* autorecycle.c */ extern bool recycle_oldest_purged_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr); diff --git a/bacula/src/dird/recycle.c b/bacula/src/dird/recycle.c index 2c01fe3b94..d960643db6 100644 --- a/bacula/src/dird/recycle.c +++ b/bacula/src/dird/recycle.c @@ -1,16 +1,7 @@ -/* - * - * Bacula Director -- Automatic Recycling of Volumes - * Recycles Volumes that have been purged - * - * Kern Sibbald, May MMII - * - * Version $Id$ - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2002-2006 Free Software Foundation Europe e.V. + Copyright (C) 2002-2007 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. @@ -34,6 +25,16 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * + * Bacula Director -- Automatic Recycling of Volumes + * Recycles Volumes that have been purged + * + * Kern Sibbald, May MMII + * + * Version $Id$ + */ + #include "bacula.h" #include "dird.h" diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 5acc952c34..1b97b952fa 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -1695,12 +1695,32 @@ int qhelp_cmd(UAContext *ua, const char *cmd) return 1; } +#if 1 static int version_cmd(UAContext *ua, const char *cmd) { ua->send_msg(_("%s Version: %s (%s) %s %s %s\n"), my_name, VERSION, BDATE, HOST_OS, DISTNAME, DISTVER); return 1; } +#else +/* + * Test code -- turned on only for debug testing + */ +static int version_cmd(UAContext *ua, const char *cmd) +{ + dbid_list ids; + POOL_MEM query(PM_MESSAGE); + open_db(ua); + Mmsg(query, "select MediaId from Media,Pool where Pool.PoolId=Media.PoolId and Pool.Name='Full'"); + db_get_query_dbids(ua->jcr, ua->db, query, ids); + ua->send_msg("num_ids=%d max_ids=%d tot_ids=%d\n", ids.num_ids, ids.max_ids, ids.tot_ids); + for (int i=0; i < ids.num_ids; i++) { + ua->send_msg("id=%d\n", ids.DBId[i]); + } + close_db(ua); + return 1; +} +#endif /* * This call explicitly checks for a catalog=xxx and diff --git a/bacula/src/dird/ua_purge.c b/bacula/src/dird/ua_purge.c index c9174715b8..80e2783633 100644 --- a/bacula/src/dird/ua_purge.c +++ b/bacula/src/dird/ua_purge.c @@ -532,7 +532,7 @@ bool mark_media_purged(UAContext *ua, MEDIA_DBR *mr) } /* Send message to Job report, if it is a *real* job */ if (jcr && jcr->JobId > 0) { - Jmsg1(jcr, M_INFO, 0, _("All records pruned from Volume \"%s\"; marking it \"Purged\"\n"), + Jmsg(jcr, M_INFO, 0, _("All records pruned from Volume \"%s\"; marking it \"Purged\"\n"), mr->VolumeName); } return true; diff --git a/bacula/src/version.h b/bacula/src/version.h index de68915b13..7ecd5a2beb 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -4,8 +4,8 @@ #undef VERSION #define VERSION "2.1.25" -#define BDATE "03 July 2007" -#define LSMDATE "03Jul07" +#define BDATE "07 July 2007" +#define LSMDATE "07Jul07" #define PROG_COPYRIGHT "Copyright (C) %d-2007 Free Software Foundation Europe e.V.\n" #define BYEAR "2007" /* year for copyright messages in progs */ diff --git a/bacula/technotes-2.1 b/bacula/technotes-2.1 index 299e546d44..79d444adcb 100644 --- a/bacula/technotes-2.1 +++ b/bacula/technotes-2.1 @@ -1,6 +1,12 @@ Technical notes on version 2.1 General: +07Jul07 +kes Rework prune_volumes() code to take account of InChanger flag, + and to handle recycling volumes going to the Scratch pool and + current pool because the RecyclePool directive. +kes Implement a better and more efficient db_get_query_dbids() to + handle creating and passing back a list of DBIds. 03Jul07 kes Start work on new more efficient DBId subroutine. First use will be for recycling volume to Scratch inchanger. -- 2.39.5