From f2ce4efdaef6afbb08f0e5553628c917dc54c352 Mon Sep 17 00:00:00 2001 From: Eric Bollengier Date: Wed, 28 Jan 2009 10:47:21 +0000 Subject: [PATCH] ebl Add new ScratchPool directive to Pool. Thanks to Graham git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@8407 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/cats/cats.h | 1 + bacula/src/cats/sql_create.c | 10 ++++++---- bacula/src/cats/sql_get.c | 6 +++--- bacula/src/cats/sql_update.c | 8 ++++---- bacula/src/dird/autoprune.c | 9 ++++++++- bacula/src/dird/catreq.c | 1 + bacula/src/dird/dird.c | 2 +- bacula/src/dird/dird_conf.c | 5 +++++ bacula/src/dird/dird_conf.h | 1 + bacula/src/dird/next_vol.c | 5 +++++ bacula/src/dird/protos.h | 4 ++-- bacula/src/dird/ua_cmds.c | 32 ++++++++++++++++++++++++++------ bacula/src/dird/ua_output.c | 1 + bacula/src/dird/ua_status.c | 1 + bacula/src/dird/ua_update.c | 2 +- bacula/technotes-2.5 | 1 + 16 files changed, 67 insertions(+), 22 deletions(-) diff --git a/bacula/src/cats/cats.h b/bacula/src/cats/cats.h index 60c470876f..baf8517b58 100644 --- a/bacula/src/cats/cats.h +++ b/bacula/src/cats/cats.h @@ -898,6 +898,7 @@ struct POOL_DBR { uint32_t MaxVolFiles; /* Max files on Volume */ uint64_t MaxVolBytes; /* Max bytes on Volume */ DBId_t RecyclePoolId; /* RecyclePool destination when media is purged */ + DBId_t ScratchPoolId; /* ScratchPool source when media is needed */ char PoolType[MAX_NAME_LENGTH]; char LabelFormat[MAX_NAME_LENGTH]; /* Extra stuff not in DB */ diff --git a/bacula/src/cats/sql_create.c b/bacula/src/cats/sql_create.c index 998ccc6bf2..422a0a6b42 100644 --- a/bacula/src/cats/sql_create.c +++ b/bacula/src/cats/sql_create.c @@ -170,7 +170,7 @@ bool db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr) { bool stat; - char ed1[30], ed2[30], ed3[50], ed4[50]; + char ed1[30], ed2[30], ed3[50], ed4[50], ed5[50]; Dmsg0(200, "In create pool\n"); db_lock(mdb); @@ -192,8 +192,9 @@ db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr) Mmsg(mdb->cmd, "INSERT INTO Pool (Name,NumVols,MaxVols,UseOnce,UseCatalog," "AcceptAnyVolume,AutoPrune,Recycle,VolRetention,VolUseDuration," -"MaxVolJobs,MaxVolFiles,MaxVolBytes,PoolType,LabelType,LabelFormat,RecyclePoolId) " -"VALUES ('%s',%u,%u,%d,%d,%d,%d,%d,%s,%s,%u,%u,%s,'%s',%d,'%s',%s)", +"MaxVolJobs,MaxVolFiles,MaxVolBytes,PoolType,LabelType,LabelFormat," +"RecyclePoolId,ScratchPoolId) " +"VALUES ('%s',%u,%u,%d,%d,%d,%d,%d,%s,%s,%u,%u,%s,'%s',%d,'%s',%s,%s)", pr->Name, pr->NumVols, pr->MaxVols, pr->UseOnce, pr->UseCatalog, @@ -204,7 +205,8 @@ db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr) pr->MaxVolJobs, pr->MaxVolFiles, edit_uint64(pr->MaxVolBytes, ed3), pr->PoolType, pr->LabelType, pr->LabelFormat, - edit_int64(pr->RecyclePoolId,ed4)); + edit_int64(pr->RecyclePoolId,ed4), + edit_int64(pr->ScratchPoolId,ed5)); Dmsg1(200, "Create Pool: %s\n", mdb->cmd); if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"), diff --git a/bacula/src/cats/sql_get.c b/bacula/src/cats/sql_get.c index 4983ddedf5..dd6a29acfc 100644 --- a/bacula/src/cats/sql_get.c +++ b/bacula/src/cats/sql_get.c @@ -607,16 +607,15 @@ bool db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr) Mmsg(mdb->cmd, "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog,AcceptAnyVolume," "AutoPrune,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles," -"MaxVolBytes,PoolType,LabelType,LabelFormat,RecyclePoolId FROM Pool WHERE Pool.PoolId=%s", +"MaxVolBytes,PoolType,LabelType,LabelFormat,RecyclePoolId,ScratchPoolId FROM Pool WHERE Pool.PoolId=%s", edit_int64(pdbr->PoolId, ed1)); } else { /* find by name */ Mmsg(mdb->cmd, "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog,AcceptAnyVolume," "AutoPrune,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles," -"MaxVolBytes,PoolType,LabelType,LabelFormat,RecyclePoolId FROM Pool WHERE Pool.Name='%s'", +"MaxVolBytes,PoolType,LabelType,LabelFormat,RecyclePoolId,ScratchPoolId FROM Pool WHERE Pool.Name='%s'", pdbr->Name); } - if (QUERY_DB(jcr, mdb, mdb->cmd)) { mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 1) { @@ -647,6 +646,7 @@ bool db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr) pdbr->LabelType = str_to_int64(row[15]); bstrncpy(pdbr->LabelFormat, row[16]!=NULL?row[16]:"", sizeof(pdbr->LabelFormat)); pdbr->RecyclePoolId = str_to_int64(row[17]); + pdbr->ScratchPoolId = str_to_int64(row[18]); ok = true; } } diff --git a/bacula/src/cats/sql_update.c b/bacula/src/cats/sql_update.c index 535dbd1173..8c713aa70f 100644 --- a/bacula/src/cats/sql_update.c +++ b/bacula/src/cats/sql_update.c @@ -260,7 +260,7 @@ int db_update_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr) int db_update_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr) { int stat; - char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50]; + char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50]; db_lock(mdb); Mmsg(mdb->cmd, "SELECT count(*) from Media WHERE PoolId=%s", @@ -272,7 +272,8 @@ int db_update_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr) "UPDATE Pool SET NumVols=%u,MaxVols=%u,UseOnce=%d,UseCatalog=%d," "AcceptAnyVolume=%d,VolRetention='%s',VolUseDuration='%s'," "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s,Recycle=%d," -"AutoPrune=%d,LabelType=%d,LabelFormat='%s',RecyclePoolId=%s WHERE PoolId=%s", +"AutoPrune=%d,LabelType=%d,LabelFormat='%s',RecyclePoolId=%s," +"ScratchPoolId=%s WHERE PoolId=%s", pr->NumVols, pr->MaxVols, pr->UseOnce, pr->UseCatalog, pr->AcceptAnyVolume, edit_uint64(pr->VolRetention, ed1), edit_uint64(pr->VolUseDuration, ed2), @@ -280,8 +281,7 @@ int db_update_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr) edit_uint64(pr->MaxVolBytes, ed3), pr->Recycle, pr->AutoPrune, pr->LabelType, pr->LabelFormat, edit_int64(pr->RecyclePoolId,ed5), - ed4); - + edit_int64(pr->ScratchPoolId,ed6),ed4); stat = UPDATE_DB(jcr, mdb, mdb->cmd); db_unlock(mdb); return stat; diff --git a/bacula/src/dird/autoprune.c b/bacula/src/dird/autoprune.c index 9632aeb3a5..31f09167ac 100644 --- a/bacula/src/dird/autoprune.c +++ b/bacula/src/dird/autoprune.c @@ -122,7 +122,14 @@ void prune_volumes(JCR *jcr, bool InChanger, MEDIA_DBR *mr) } else { ed2[0] = 0; } - Dmsg1(100, "Scratch pool=%s\n", ed2); + + if(mr->ScratchPoolId) { + edit_int64(mr->ScratchPoolId, ed3); + bstrncat(ed2, ed3, sizeof(ed2)); + bstrncat(ed2, ",", sizeof(ed2)); + } + + Dmsg1(100, "Scratch pool(s)=%s\n", ed2); /* * ed2 ends up with scratch poolid and current poolid or * just current poolid if there is no scratch pool diff --git a/bacula/src/dird/catreq.c b/bacula/src/dird/catreq.c index 69f9488eec..aac92cf8fa 100644 --- a/bacula/src/dird/catreq.c +++ b/bacula/src/dird/catreq.c @@ -143,6 +143,7 @@ void catalog_request(JCR *jcr, BSOCK *bs) if (ok) { mr.PoolId = pr.PoolId; mr.StorageId = jcr->wstore->StorageId; + mr.ScratchPoolId = pr.ScratchPoolId; ok = find_next_volume_for_append(jcr, &mr, index, fnv_create_vol, fnv_prune); Dmsg3(050, "find_media ok=%d idx=%d vol=%s\n", ok, index, mr.VolumeName); } diff --git a/bacula/src/dird/dird.c b/bacula/src/dird/dird.c index da5361b753..edf4a650be 100644 --- a/bacula/src/dird/dird.c +++ b/bacula/src/dird/dird.c @@ -957,7 +957,7 @@ static bool check_catalog() * in that catalog. */ if (!pool->catalog || pool->catalog == catalog) { - update_pool_recyclepool(NULL, db, pool); + update_pool_references(NULL, db, pool); } } diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index 077ff4c707..5afe768a6d 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -397,6 +397,7 @@ static RES_ITEM pool_items[] = { {"autoprune", store_bool, ITEM(res_pool.AutoPrune), 0, ITEM_DEFAULT, true}, {"recycle", store_bool, ITEM(res_pool.Recycle), 0, ITEM_DEFAULT, true}, {"recyclepool", store_res, ITEM(res_pool.RecyclePool), R_POOL, 0, 0}, + {"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}, {NULL, NULL, {0}, 0, 0, 0} @@ -951,6 +952,9 @@ next_run: if (res->res_pool.RecyclePool) { sendit(sock, _(" RecyclePool=%s\n"), res->res_pool.RecyclePool->name()); } + if (res->res_pool.ScratchPool) { + sendit(sock, _(" ScratchPool=%s\n"), res->res_pool.ScratchPool->name()); + } if (res->res_pool.catalog) { sendit(sock, _(" Catalog=%s\n"), res->res_pool.catalog->name()); } @@ -1385,6 +1389,7 @@ void save_resource(int type, RES_ITEM *items, int pass) /* Explicitly copy resource pointers from this pass (res_all) */ res->res_pool.NextPool = res_all.res_pool.NextPool; res->res_pool.RecyclePool = res_all.res_pool.RecyclePool; + res->res_pool.ScratchPool = res_all.res_pool.ScratchPool; res->res_pool.storage = res_all.res_pool.storage; res->res_pool.catalog = res_all.res_pool.catalog; break; diff --git a/bacula/src/dird/dird_conf.h b/bacula/src/dird/dird_conf.h index 222afb9b7e..fea4ee029e 100644 --- a/bacula/src/dird/dird_conf.h +++ b/bacula/src/dird/dird_conf.h @@ -562,6 +562,7 @@ public: bool AutoPrune; /* default for pool auto prune */ bool Recycle; /* default for media recycle yes/no */ POOL *RecyclePool; /* RecyclePool destination when media is purged */ + POOL *ScratchPool; /* ScratchPool source when requesting media */ alist *CopyPool; /* List of copy pools */ CAT *catalog; /* Catalog to be used */ /* Methods */ diff --git a/bacula/src/dird/next_vol.c b/bacula/src/dird/next_vol.c index 904f4cf0ca..462d455023 100644 --- a/bacula/src/dird/next_vol.c +++ b/bacula/src/dird/next_vol.c @@ -43,6 +43,7 @@ * Items needed: * mr.PoolId must be set * mr.StorageId should also be set + * mr.ScratchPoolId could be set (used if create==true) * jcr->wstore * jcr->db * jcr->pool @@ -347,9 +348,13 @@ bool get_scratch_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr) P(mutex); /* * Get Pool record for Scratch Pool + * choose between ScratchPoolId and Scratch + * db_get_pool_record will first try ScratchPoolId, + * and then try the pool named Scratch */ memset(&spr, 0, sizeof(spr)); bstrncpy(spr.Name, "Scratch", sizeof(spr.Name)); + spr.PoolId = mr->ScratchPoolId; if (db_get_pool_record(jcr, jcr->db, &spr)) { memset(&smr, 0, sizeof(smr)); smr.PoolId = spr.PoolId; diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index 7fa5ebfe44..26e5d71944 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -197,9 +197,9 @@ enum e_pool_op { }; int create_pool(JCR *jcr, B_DB *db, POOL *pool, e_pool_op op); void set_pool_dbr_defaults_in_media_dbr(MEDIA_DBR *mr, POOL_DBR *pr); -bool set_pooldbr_recyclepoolid(JCR *jcr, B_DB *db, POOL_DBR *pr, POOL *pool); +bool set_pooldbr_references(JCR *jcr, B_DB *db, POOL_DBR *pr, POOL *pool); void set_pooldbr_from_poolres(POOL_DBR *pr, POOL *pool, e_pool_op op); -int update_pool_recyclepool(JCR *jcr, B_DB *db, POOL *pool); +int update_pool_references(JCR *jcr, B_DB *db, POOL *pool); /* ua_input.c */ int get_cmd(UAContext *ua, const char *prompt); diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 818e3dac7f..4371fe05a2 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -565,12 +565,12 @@ void set_pooldbr_from_poolres(POOL_DBR *pr, POOL *pool, e_pool_op op) } } -/* set/update Pool.RecyclePoolId in Catalog */ -int update_pool_recyclepool(JCR *jcr, B_DB *db, POOL *pool) +/* set/update Pool.RecyclePoolId and Pool.ScratchPoolId in Catalog */ +int update_pool_references(JCR *jcr, B_DB *db, POOL *pool) { POOL_DBR pr; - if (!pool->RecyclePool) { + if (!pool->RecyclePool && !pool->ScratchPool) { return 1; } @@ -583,7 +583,7 @@ int update_pool_recyclepool(JCR *jcr, B_DB *db, POOL *pool) set_pooldbr_from_poolres(&pr, pool, POOL_OP_UPDATE); - if (!set_pooldbr_recyclepoolid(jcr, db, &pr, pool)) { + if (!set_pooldbr_references(jcr, db, &pr, pool)) { return -1; /* error */ } @@ -593,10 +593,10 @@ int update_pool_recyclepool(JCR *jcr, B_DB *db, POOL *pool) return 1; } -/* set POOL_DBR.RecyclePoolId from Pool resource +/* set POOL_DBR.RecyclePoolId and POOL_DBR.ScratchPoolId from Pool resource * works with set_pooldbr_from_poolres */ -bool set_pooldbr_recyclepoolid(JCR *jcr, B_DB *db, POOL_DBR *pr, POOL *pool) +bool set_pooldbr_references(JCR *jcr, B_DB *db, POOL_DBR *pr, POOL *pool) { POOL_DBR rpool; bool ret = true; @@ -618,6 +618,24 @@ bool set_pooldbr_recyclepoolid(JCR *jcr, B_DB *db, POOL_DBR *pr, POOL *pool) } else { /* no RecyclePool used, set it to 0 */ pr->RecyclePoolId = 0; } + + if (pool->ScratchPool) { + memset(&rpool, 0, sizeof(POOL_DBR)); + + bstrncpy(rpool.Name, pool->ScratchPool->name(), sizeof(rpool.Name)); + if (db_get_pool_record(jcr, db, &rpool)) { + pr->ScratchPoolId = rpool.PoolId; + } else { + Jmsg(jcr, M_WARNING, 0, + _("Can't set %s ScratchPool to %s, %s is not in database.\n" \ + "Try to update it with 'update pool=%s'\n"), + pool->name(), rpool.Name, rpool.Name,pool->name()); + ret = false; + } + } else { /* no ScratchPool used, set it to 0 */ + pr->ScratchPoolId = 0; + } + return ret; } @@ -642,12 +660,14 @@ int create_pool(JCR *jcr, B_DB *db, POOL *pool, e_pool_op op) /* Pool Exists */ if (op == POOL_OP_UPDATE) { /* update request */ set_pooldbr_from_poolres(&pr, pool, op); + set_pooldbr_references(jcr, db, &pr, pool); db_update_pool_record(jcr, db, &pr); } return 0; /* exists */ } set_pooldbr_from_poolres(&pr, pool, op); + set_pooldbr_references(jcr, db, &pr, pool); if (!db_create_pool_record(jcr, db, &pr)) { return -1; /* error */ diff --git a/bacula/src/dird/ua_output.c b/bacula/src/dird/ua_output.c index 1efb461a8f..5c48755ea3 100644 --- a/bacula/src/dird/ua_output.c +++ b/bacula/src/dird/ua_output.c @@ -523,6 +523,7 @@ static bool list_nextvol(UAContext *ua, int ndays) mr.PoolId = jcr->jr.PoolId; get_job_storage(&store, job, run); mr.StorageId = store.store->StorageId; + /* no need to set ScratchPoolId, since we use fnv_no_create_vol */ if (!find_next_volume_for_append(jcr, &mr, 1, fnv_no_create_vol, fnv_prune)) { ua->error_msg(_("Could not find next Volume for Job %s (Pool=%s, Level=%s).\n"), job->name(), pr.Name, level_to_str(run->level)); diff --git a/bacula/src/dird/ua_status.c b/bacula/src/dird/ua_status.c index b430007d22..87c70f30ca 100644 --- a/bacula/src/dird/ua_status.c +++ b/bacula/src/dird/ua_status.c @@ -470,6 +470,7 @@ static void prt_runtime(UAContext *ua, sched_pkt *sp) mr.StorageId = sp->store->StorageId; jcr->wstore = sp->store; Dmsg0(250, "call find_next_volume_for_append\n"); + /* no need to set ScratchPoolId, since we use fnv_no_create_vol */ ok = find_next_volume_for_append(jcr, &mr, 1, fnv_no_create_vol, fnv_no_prune); } if (!ok) { diff --git a/bacula/src/dird/ua_update.c b/bacula/src/dird/ua_update.c index e49ef67dc6..e61f813954 100644 --- a/bacula/src/dird/ua_update.c +++ b/bacula/src/dird/ua_update.c @@ -840,7 +840,7 @@ static bool update_pool(UAContext *ua) } set_pooldbr_from_poolres(&pr, pool, POOL_OP_UPDATE); /* update */ - set_pooldbr_recyclepoolid(ua->jcr, ua->db, &pr, pool); + set_pooldbr_references(ua->jcr, ua->db, &pr, pool); id = db_update_pool_record(ua->jcr, ua->db, &pr); if (id <= 0) { diff --git a/bacula/technotes-2.5 b/bacula/technotes-2.5 index e8e6b75a8d..0b7ab88dfa 100644 --- a/bacula/technotes-2.5 +++ b/bacula/technotes-2.5 @@ -11,6 +11,7 @@ mixed priorities General: 28Jan09 +ebl Add new ScratchPool directive to Pool. Thanks to Graham ebl Turn on db_get_file_list() single SQL because the failure was due to a full FS. And the accurate test fails with the other code. -- 2.39.5