From 6c32c4f858f06f58683fd66a143146a584284356 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Wed, 29 Oct 2008 14:21:32 +0000 Subject: [PATCH] kes Rework next_vol and autoprune a bit due to failure in recycle-test. prune_volumes() now returns no status, but should prune at least one Volume, if possible. kes Modify check_if_volume_valid_or_recyclable to reject a volume with Recycle set off. kes Modify prune_volumes() to continue if volume Recycle is off or if the volume has expired. Add more debug. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@7939 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/dird/autoprune.c | 57 +++++++++++++++++++++++-------------- bacula/src/dird/next_vol.c | 53 ++++++++++++++++++---------------- bacula/src/dird/protos.h | 2 +- bacula/src/stored/device.c | 2 +- bacula/src/version.h | 4 +-- bacula/technotes-2.5 | 8 ++++++ 6 files changed, 76 insertions(+), 50 deletions(-) diff --git a/bacula/src/dird/autoprune.c b/bacula/src/dird/autoprune.c index a80386cbfd..a6c7ce5653 100644 --- a/bacula/src/dird/autoprune.c +++ b/bacula/src/dird/autoprune.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2002-2007 Free Software Foundation Europe e.V. + Copyright (C) 2002-2008 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. @@ -84,10 +84,8 @@ void do_autoprune(JCR *jcr) * catreq.c => next_vol.c when the Storage daemon is asking for another * volume and no appendable volumes are available. * - * Return: false if nothing pruned - * true if pruned, and mr is set to pruned volume */ -bool prune_volumes(JCR *jcr, bool InChanger, MEDIA_DBR *mr) +void prune_volumes(JCR *jcr, bool InChanger, MEDIA_DBR *mr) { int count; int i; @@ -95,14 +93,13 @@ bool prune_volumes(JCR *jcr, bool InChanger, MEDIA_DBR *mr) 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); + Dmsg1(100, "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; + return; } memset(&prune_list, 0, sizeof(prune_list)); @@ -126,7 +123,7 @@ bool prune_volumes(JCR *jcr, bool InChanger, MEDIA_DBR *mr) } else { ed2[0] = 0; } - Dmsg1(050, "Scratch pool=%s\n", ed2); + Dmsg1(100, "Scratch pool=%s\n", ed2); /* * ed2 ends up with scratch poolid and current poolid or * just current poolid if there is no scratch pool @@ -151,70 +148,86 @@ bool prune_volumes(JCR *jcr, bool InChanger, MEDIA_DBR *mr) Mmsg(query, select, ed1, ed2, mr->MediaType, ""); } - Dmsg1(050, "query=%s\n", query.c_str()); + Dmsg1(100, "query=%s\n", query.c_str()); if (!db_get_query_dbids(ua->jcr, ua->db, query, ids)) { Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db)); goto bail_out; } - Dmsg1(050, "num_ids=%d\n", ids.num_ids); + Dmsg1(100, "num_ids=%d\n", ids.num_ids); /* Visit each Volume and Prune it until we find one that is purged */ for (i=0; idb, &lmr)) { Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db)); continue; } + Dmsg1(100, "Examine vol=%s\n", lmr.VolumeName); /* Don't prune archived volumes */ if (lmr.Enabled == 2) { + Dmsg1(100, "Vol=%s disabled\n", lmr.VolumeName); continue; } /* Prune only Volumes with status "Full", or "Used" */ 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); + Dmsg2(100, "Add prune list MediaId=%d Volume %s\n", (int)lmr.MediaId, lmr.VolumeName); count = get_prune_list_for_volume(ua, &lmr, &prune_list); - Dmsg1(050, "Num pruned = %d\n", count); + Dmsg1(100, "Num pruned = %d\n", count); if (count != 0) { purge_job_list_from_catalog(ua, prune_list); prune_list.num_ids = 0; /* reset count */ } - ok = is_volume_purged(ua, &lmr); + if (!is_volume_purged(ua, &lmr)) { + Dmsg1(100, "Vol=%s not pruned\n", lmr.VolumeName); + continue; + } /* - * Check if this volume is available (InChanger + StorageId) + * Since we are also pruning the Scratch pool, continue + * until and check if this volume is available (InChanger + StorageId) * If not, just skip this volume and try the next one */ - if (ok && InChanger) { + if (InChanger) { if (!lmr.InChanger || (lmr.StorageId != mr->StorageId)) { - ok = false; /* skip this volume, ie not loadable */ + Dmsg1(100, "Vol=%s not inchanger or correct StoreId\n", lmr.VolumeName); + continue; /* skip this volume, ie not loadable */ } } + if (!lmr.Recycle) { + Dmsg1(100, "Vol=%s not recyclable\n", lmr.VolumeName); + continue; + } + + if (has_volume_expired(jcr, &lmr)) { + Dmsg1(100, "Vol=%s has expired\n", lmr.VolumeName); + continue; /* Volume not usable */ + } /* * 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); + if (lmr.PoolId == mr->PoolId) { + Dmsg2(100, "Got Vol=%s MediaId=%d purged.\n", lmr.VolumeName, (int)lmr.MediaId); memcpy(mr, &lmr, sizeof(lmr)); break; /* got a volume */ } - ok = false; /* clear OK, in case we fall out */ } else { - Dmsg2(050, "Nothing pruned MediaId=%d Volume=%s\n", (int)lmr.MediaId, lmr.VolumeName); + Dmsg2(100, "Nothing pruned MediaId=%d Volume=%s\n", (int)lmr.MediaId, lmr.VolumeName); } } bail_out: + Dmsg0(100, "Leave prune volumes\n"); db_unlock(jcr->db); free_ua_context(ua); if (prune_list.JobId) { free(prune_list.JobId); } - return ok; + return; } diff --git a/bacula/src/dird/next_vol.c b/bacula/src/dird/next_vol.c index b070b7777c..a675a07374 100644 --- a/bacula/src/dird/next_vol.c +++ b/bacula/src/dird/next_vol.c @@ -76,7 +76,7 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, ok = db_find_next_volume(jcr, jcr->db, index, InChanger, mr); if (!ok) { - Dmsg4(050, "after find_next_vol ok=%d index=%d InChanger=%d Vstat=%s\n", + Dmsg4(150, "after find_next_vol ok=%d index=%d InChanger=%d Vstat=%s\n", ok, index, InChanger, mr->VolStatus); /* * 2. Try finding a recycled volume @@ -94,30 +94,28 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, */ if (prune) { Dmsg0(150, "Call prune_volumes\n"); - ok = prune_volumes(jcr, InChanger, mr); + prune_volumes(jcr, InChanger, mr); } - if (!ok) { - ok = recycle_oldest_purged_volume(jcr, InChanger, mr); - if (!ok && create) { - Dmsg4(050, "after prune volumes_vol ok=%d index=%d InChanger=%d Vstat=%s\n", - ok, index, InChanger, mr->VolStatus); - /* - * 5. Try pulling a volume from the Scratch pool - */ - ok = get_scratch_volume(jcr, InChanger, mr); - Dmsg4(050, "after get scratch volume ok=%d index=%d InChanger=%d Vstat=%s\n", - ok, index, InChanger, mr->VolStatus); - } - /* - * If we are using an Autochanger and have not found - * a volume, retry looking for any volume. - */ - if (!ok && InChanger) { - InChanger = false; - continue; /* retry again accepting any volume */ - } - } - } + ok = recycle_oldest_purged_volume(jcr, InChanger, mr); + if (!ok && create) { + Dmsg4(150, "after prune volumes_vol ok=%d index=%d InChanger=%d Vstat=%s\n", + ok, index, InChanger, mr->VolStatus); + /* + * 5. Try pulling a volume from the Scratch pool + */ + ok = get_scratch_volume(jcr, InChanger, mr); + Dmsg4(150, "after get scratch volume ok=%d index=%d InChanger=%d Vstat=%s\n", + ok, index, InChanger, mr->VolStatus); + } + /* + * If we are using an Autochanger and have not found + * a volume, retry looking for any volume. + */ + if (!ok && InChanger) { + InChanger = false; + continue; /* retry again accepting any volume */ + } + } } @@ -238,11 +236,13 @@ bool has_volume_expired(JCR *jcr, MEDIA_DBR *mr) } if (expired) { /* Need to update media */ + Dmsg1(150, "Vol=%s has expired update media record\n", mr->VolumeName); if (!db_update_media_record(jcr, jcr->db, mr)) { Jmsg(jcr, M_ERROR, 0, _("Catalog error updating volume \"%s\". ERR=%s"), mr->VolumeName, db_strerror(jcr->db)); } } + Dmsg2(150, "Vol=%s expired=%d\n", mr->VolumeName, expired); return expired; } @@ -258,6 +258,11 @@ void check_if_volume_valid_or_recyclable(JCR *jcr, MEDIA_DBR *mr, const char **r *reason = NULL; + if (!mr->Recycle) { + *reason = _("volume has recycling disabled"); + return; + } + /* Check if a duration or limit has expired */ if (has_volume_expired(jcr, mr)) { *reason = _("volume has expired"); diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index 06c8660ee7..7f29af765d 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, bool InChanger, MEDIA_DBR *mr); +extern void 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/stored/device.c b/bacula/src/stored/device.c index 679a158a5f..594c5005c4 100644 --- a/bacula/src/stored/device.c +++ b/bacula/src/stored/device.c @@ -183,7 +183,7 @@ bool fixup_device_block_write_error(DCR *dcr) Dmsg0(190, "Write overflow block to dev\n"); if (!write_block_to_dev(dcr)) { berrno be; - Pmsg1(0, _("write_block_to_device overflow block failed. ERR=%s"), + Dmsg1(0, _("write_block_to_device overflow block failed. ERR=%s"), be.bstrerror(dev->dev_errno)); goto bail_out; } diff --git a/bacula/src/version.h b/bacula/src/version.h index 9cc93ba25f..99b1cb2880 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -4,8 +4,8 @@ #undef VERSION #define VERSION "2.5.17" -#define BDATE "28 October 2008" -#define LSMDATE "28Oct08" +#define BDATE "29 October 2008" +#define LSMDATE "29Oct08" #define PROG_COPYRIGHT "Copyright (C) %d-2008 Free Software Foundation Europe e.V.\n" #define BYEAR "2008" /* year for copyright messages in progs */ diff --git a/bacula/technotes-2.5 b/bacula/technotes-2.5 index a053d8de56..2b079d2bc0 100644 --- a/bacula/technotes-2.5 +++ b/bacula/technotes-2.5 @@ -10,6 +10,14 @@ filepattern (restore with regex in bsr) mixed priorities General: +29Oct08 +kes Rework next_vol and autoprune a bit due to failure in + recycle-test. prune_volumes() now returns no status, + but should prune at least one Volume, if possible. +kes Modify check_if_volume_valid_or_recyclable to reject a + volume with Recycle set off. +kes Modify prune_volumes() to continue if volume Recycle is off + or if the volume has expired. Add more debug. 28Oct08 kes Fix bug #1046 VolumeToCatalog incorrectly reports mounted filesystems as missing on the Volume. -- 2.39.5