From 5151b9a742bd5caf548f6a3fdf9d1e1be60fee00 Mon Sep 17 00:00:00 2001 From: Eric Bollengier Date: Sat, 17 Oct 2009 22:12:25 +0000 Subject: [PATCH] Update Media and Pool record for ActionOnPurge + cleanup --- bacula/src/baconfig.h | 2 +- bacula/src/cats/sql_create.c | 14 +++--- bacula/src/cats/sql_update.c | 8 ++-- bacula/src/dird/dird_conf.c | 21 +++++---- bacula/src/dird/ua_purge.c | 9 ++-- bacula/src/dird/ua_update.c | 33 +++++++++----- bacula/src/lib/protos.h | 1 + bacula/src/lib/util.c | 13 ++++++ bacula/src/stored/dircmd.c | 12 +++-- regress/scripts/functions.pm | 2 +- regress/tests/action-on-purge-test | 72 ++++++++++++++++++++++++++++++ 11 files changed, 145 insertions(+), 42 deletions(-) create mode 100644 regress/tests/action-on-purge-test diff --git a/bacula/src/baconfig.h b/bacula/src/baconfig.h index 20a336a677..09049d266b 100644 --- a/bacula/src/baconfig.h +++ b/bacula/src/baconfig.h @@ -345,7 +345,7 @@ void InitWinAPIWrapper(); #define B_IBM_LABEL 2 /* - * Actions on purge + * Actions on purge (bit mask) */ #define AOP_TRUNCATE 1 diff --git a/bacula/src/cats/sql_create.c b/bacula/src/cats/sql_create.c index ee93e94250..c51261a0ac 100644 --- a/bacula/src/cats/sql_create.c +++ b/bacula/src/cats/sql_create.c @@ -192,8 +192,8 @@ db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr) "INSERT INTO Pool (Name,NumVols,MaxVols,UseOnce,UseCatalog," "AcceptAnyVolume,AutoPrune,Recycle,VolRetention,VolUseDuration," "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)", +"RecyclePoolId,ScratchPoolId,ActionOnPurge) " +"VALUES ('%s',%u,%u,%d,%d,%d,%d,%d,%s,%s,%u,%u,%s,'%s',%d,'%s',%s,%s,%d)", pr->Name, pr->NumVols, pr->MaxVols, pr->UseOnce, pr->UseCatalog, @@ -205,7 +205,9 @@ db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr) edit_uint64(pr->MaxVolBytes, ed3), pr->PoolType, pr->LabelType, pr->LabelFormat, edit_int64(pr->RecyclePoolId,ed4), - edit_int64(pr->ScratchPoolId,ed5)); + edit_int64(pr->ScratchPoolId,ed5), + pr->ActionOnPurge + ); 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"), @@ -410,9 +412,9 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) "VolCapacityBytes,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles," "VolStatus,Slot,VolBytes,InChanger,VolReadTime,VolWriteTime,VolParts," "EndFile,EndBlock,LabelType,StorageId,DeviceId,LocationId," -"ScratchPoolId,RecyclePoolId,Enabled)" +"ScratchPoolId,RecyclePoolId,Enabled,ActionOnPurge)" "VALUES ('%s','%s',0,%u,%s,%s,%d,%s,%s,%u,%u,'%s',%d,%s,%d,%s,%s,%d,0,0,%d,%s," -"%s,%s,%s,%s,%d)", +"%s,%s,%s,%s,%d,%d)", mr->VolumeName, mr->MediaType, mr->PoolId, edit_uint64(mr->MaxVolBytes,ed1), @@ -435,7 +437,7 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) edit_int64(mr->LocationId, ed10), edit_int64(mr->ScratchPoolId, ed11), edit_int64(mr->RecyclePoolId, ed12), - mr->Enabled + mr->Enabled, mr->ActionOnPurge ); diff --git a/bacula/src/cats/sql_update.c b/bacula/src/cats/sql_update.c index 81293a3b9b..c34bf912c2 100644 --- a/bacula/src/cats/sql_update.c +++ b/bacula/src/cats/sql_update.c @@ -415,10 +415,10 @@ db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) db_lock(mdb); if (mr->VolumeName[0]) { Mmsg(mdb->cmd, "UPDATE Media SET " - "Recycle=%d,VolRetention=%s,VolUseDuration=%s," + "ActionOnPurge=%d, Recycle=%d,VolRetention=%s,VolUseDuration=%s," "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s,RecyclePoolId=%s" " WHERE VolumeName='%s'", - mr->Recycle,edit_uint64(mr->VolRetention, ed1), + mr->ActionOnPurge, mr->Recycle,edit_uint64(mr->VolRetention, ed1), edit_uint64(mr->VolUseDuration, ed2), mr->MaxVolJobs, mr->MaxVolFiles, edit_uint64(mr->MaxVolBytes, ed3), @@ -426,10 +426,10 @@ db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) mr->VolumeName); } else { Mmsg(mdb->cmd, "UPDATE Media SET " - "Recycle=%d,VolRetention=%s,VolUseDuration=%s," + "ActionOnPurge=%d, Recycle=%d,VolRetention=%s,VolUseDuration=%s," "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s,RecyclePoolId=%s" " WHERE PoolId=%s", - mr->Recycle,edit_uint64(mr->VolRetention, ed1), + mr->ActionOnPurge, mr->Recycle,edit_uint64(mr->VolRetention, ed1), edit_uint64(mr->VolUseDuration, ed2), mr->MaxVolJobs, mr->MaxVolFiles, edit_uint64(mr->MaxVolBytes, ed3), diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index 4f6b33dc74..abba569f32 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -1601,17 +1601,16 @@ void save_resource(int type, RES_ITEM *items, int pass) static void store_actiononpurge(LEX *lc, RES_ITEM *item, int index, int pass) { - uint32_t *destination = (uint32_t*)item->value; - lex_get_token(lc, T_NAME); - printf("got token %s\n", lc->str); - if (strcasecmp(lc->str, "truncate") == 0) - *destination = (*destination) | AOP_TRUNCATE; - else { - scan_err2(lc, _("Expected one of: %s, got: %s"), "Truncate", lc->str); - return; - } - scan_to_eol(lc); - set_bit(index, res_all.hdr.item_present); + uint32_t *destination = (uint32_t*)item->value; + lex_get_token(lc, T_NAME); + if (strcasecmp(lc->str, "truncate") == 0) { + *destination = (*destination) | AOP_TRUNCATE; + } else { + scan_err2(lc, _("Expected one of: %s, got: %s"), "Truncate", lc->str); + return; + } + scan_to_eol(lc); + set_bit(index, res_all.hdr.item_present); } /* diff --git a/bacula/src/dird/ua_purge.c b/bacula/src/dird/ua_purge.c index e63cf1197a..149072b066 100644 --- a/bacula/src/dird/ua_purge.c +++ b/bacula/src/dird/ua_purge.c @@ -585,16 +585,19 @@ bool mark_media_purged(UAContext *ua, MEDIA_DBR *mr) if (mr->ActionOnPurge > 0) { /* Send the command to truncate the volume after purge. If this feature - * is disabled for the specific device, this will be a no-op. */ + * is disabled for the specific device, this will be a no-op. + */ BSOCK *sd; if ((sd=open_sd_bsock(ua)) != NULL) { + bash_spaces(mr->VolumeName); sd->fsend("action_on_purge %s vol=%s action=%d", ua->jcr->wstore->dev_name(), mr->VolumeName, mr->ActionOnPurge); - - while (sd->recv() >= 0) + unbash_spaces(mr->VolumeName); + while (sd->recv() >= 0) { ua->send_msg("%s", sd->msg); + } sd->signal(BNET_TERMINATE); sd->close(); diff --git a/bacula/src/dird/ua_update.c b/bacula/src/dird/ua_update.c index 00f3902166..5fd7619cf2 100644 --- a/bacula/src/dird/ua_update.c +++ b/bacula/src/dird/ua_update.c @@ -465,7 +465,8 @@ static void update_volenabled(UAContext *ua, char *val, MEDIA_DBR *mr) return; } if (!db_update_media_record(ua->jcr, ua->db, mr)) { - ua->error_msg(_("Error updating media record Enabled: ERR=%s"), db_strerror(ua->db)); + ua->error_msg(_("Error updating media record Enabled: ERR=%s"), + db_strerror(ua->db)); } else { ua->info_msg(_("New Enabled is: %d\n"), mr->Enabled); } @@ -473,15 +474,20 @@ static void update_volenabled(UAContext *ua, char *val, MEDIA_DBR *mr) static void update_vol_actiononpurge(UAContext *ua, char *val, MEDIA_DBR *mr) { - if (strcasecmp(val, "truncate") == 0) - mr->ActionOnPurge = AOP_TRUNCATE; - else mr->ActionOnPurge = 0; - - if (!db_update_media_record(ua->jcr, ua->db, mr)) { - ua->error_msg(_("Error updating media record ActionOnPurge: ERR=%s"), db_strerror(ua->db)); - } else { - ua->info_msg(_("New ActionOnPurge is: %d\n"), mr->ActionOnPurge); - } + POOL_MEM ret; + if (strcasecmp(val, "truncate") == 0) { + mr->ActionOnPurge = AOP_TRUNCATE; + } else { + mr->ActionOnPurge = 0; + } + + if (!db_update_media_record(ua->jcr, ua->db, mr)) { + ua->error_msg(_("Error updating media record ActionOnPurge: ERR=%s"), + db_strerror(ua->db)); + } else { + ua->info_msg(_("New ActionOnPurge is: %d\n"), + aop_to_str(mr->ActionOnPurge, ret)); + } } /* @@ -496,6 +502,7 @@ static int update_volume(UAContext *ua) POOL *pool; POOL_DBR pr; POOLMEM *query; + POOL_MEM ret; char buf[1000]; char ed1[130]; bool done = false; @@ -808,9 +815,11 @@ static int update_volume(UAContext *ua) return 1; case 16: - ua->info_msg(_("Current ActionOnPurge is: %d\n"), mr.ActionOnPurge); + pm_strcpy(ret, ""); + ua->info_msg(_("Current ActionOnPurge is: %s\n"), + aop_to_str(mr.ActionOnPurge, ret)); if (!get_cmd(ua, _("Enter new ActionOnPurge: (one of: Truncate, None) "))) { - return 0; + return 0; } update_vol_actiononpurge(ua, ua->cmd, &mr); diff --git a/bacula/src/lib/protos.h b/bacula/src/lib/protos.h index c5b7ce1fb2..7e700bdad7 100644 --- a/bacula/src/lib/protos.h +++ b/bacula/src/lib/protos.h @@ -320,6 +320,7 @@ void jobstatus_to_ascii (int JobStatus, char *msg, int maxlen); void jobstatus_to_ascii_gui (int JobStatus, char *msg, int maxlen); int run_program (char *prog, int wait, POOLMEM *&results); int run_program_full_output (char *prog, int wait, POOLMEM *&results); +char * aop_to_str (int aop, POOL_MEM &ret); const char * job_type_to_str (int type); const char * job_status_to_str (int stat); const char * job_level_to_str (int level); diff --git a/bacula/src/lib/util.c b/bacula/src/lib/util.c index 82f8ee3cbf..430f44b89a 100644 --- a/bacula/src/lib/util.c +++ b/bacula/src/lib/util.c @@ -395,6 +395,19 @@ const char *job_type_to_str(int type) return str; } +/* Convert ActionOnPurge to string (Truncate, Erase, Destroy) + */ +char *aop_to_str(int aop, POOL_MEM &ret) +{ + if (aop & AOP_TRUNCATE) { + pm_strcpy(ret, _("Truncate")); + } + if (!aop) { + pm_strcpy(ret, _("None")); + } + return ret.c_str(); +} + /* * Convert Job Level into a string */ diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 033cc984a5..c658f5d36d 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -884,7 +884,6 @@ static bool action_on_purge_cmd(JCR *jcr) BSOCK *dir = jcr->dir_bsock; DEVICE *dev; DCR *dcr; - int drive; int action; if (sscanf(dir->msg, "action_on_purge %127s vol=%s action=%d", @@ -892,8 +891,11 @@ static bool action_on_purge_cmd(JCR *jcr) dir->fsend(_("3916 Error scanning action_on_purge command\n")); goto done; } + unbash_spaces(volumename.c_str()); - /* FIXME: autochanger, drive = 0? how can we avoid that? we only work on files */ + /* FIXME: autochanger, drive = 0? how can we avoid that? we only work on + * files + */ if ((dcr = find_device(jcr, devname, 0)) == NULL) { dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str()); goto done; @@ -906,9 +908,11 @@ static bool action_on_purge_cmd(JCR *jcr) bstrncpy(dev->VolHdr.VolumeName, volumename.c_str(), sizeof(dev->VolHdr.VolumeName)); /* Re-write the label with the recycle flag */ - if (rewrite_volume_label(dcr, true)) + if (rewrite_volume_label(dcr, true)) { dir->fsend(_("3917 Volume recycled\n")); - else dir->fsend(_("3918 Recycle failed\n")); + } else { + dir->fsend(_("3918 Recycle failed\n")); + } done: dir->signal(BNET_EOD); diff --git a/regress/scripts/functions.pm b/regress/scripts/functions.pm index 3a1f7c15e2..6c4b5f2bbe 100644 --- a/regress/scripts/functions.pm +++ b/regress/scripts/functions.pm @@ -69,7 +69,7 @@ BEGIN { $ENV{bin} = $bin = $ENV{bin} || "$cwd/bin"; $ENV{tmp} = $tmp = $ENV{tmp} || "$cwd/tmp"; - $ENV{src} = $src = $ENV{src} || "$cwd/scr"; + $ENV{src} = $src = $ENV{src} || "$cwd/src"; $ENV{conf} = $conf = $ENV{conf} || $bin; $ENV{scripts} = $scripts = $ENV{scripts} || $bin; $ENV{tmpsrc} = $tmpsrc = $ENV{tmpsrc} || "$cwd/tmp/build"; diff --git a/regress/tests/action-on-purge-test b/regress/tests/action-on-purge-test new file mode 100644 index 0000000000..f4ca202471 --- /dev/null +++ b/regress/tests/action-on-purge-test @@ -0,0 +1,72 @@ +#!/bin/sh +# +# +TestName="action-on-purge-test" +JobName=AOP +. scripts/functions + +cwd=`pwd` +scripts/cleanup +scripts/copy-test-confs + +echo $src > $tmp/file-list +sed 's/Pool Type = Backup/Pool Type = Backup; ActionOnPurge = Truncate/' $conf/bacula-dir.conf > $tmp/1 +cp $tmp/1 $conf/bacula-dir.conf + +change_jobname CompressedTest $JobName +start_test + +cat >tmp/bconcmds < 4096)" +if [ $? != 0 ]; then + print_debug `ls -l $tmp/TestVolume001` + bstat=2 +fi + +print_debug "Test if Pool record is ok" +r=`awk '/Default/ { print $4 }' $tmp/log4.out` +if [ "$r" != 1 ]; then + print_debug "ActionOnPurge on Pool record should be 1" + bstat=2 +fi + +print_debug "Test if Media record is ok" +r=`awk '/TestVolume001/ { print $4 }' $tmp/log4.out` +if [ "$r" != 1 ]; then + print_debug "ActionOnPurge on Media record should be 1" + bstat=2 +fi + +end_test -- 2.39.5