From: Eric Bollengier Date: Thu, 28 Jan 2010 21:00:35 +0000 (+0100) Subject: Fix ActionOnPurge with a relabel command X-Git-Tag: Release-5.2.1~1834 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=5f999d41de529913e0c978b2dcac765e2928aeac;p=bacula%2Fbacula Fix ActionOnPurge with a relabel command --- diff --git a/bacula/src/cats/sql_find.c b/bacula/src/cats/sql_find.c index 827f0cb00d..e492035a51 100644 --- a/bacula/src/cats/sql_find.c +++ b/bacula/src/cats/sql_find.c @@ -331,7 +331,7 @@ db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr "MaxVolFiles,Recycle,Slot,FirstWritten,LastWritten,InChanger," "EndFile,EndBlock,VolParts,LabelType,LabelDate,StorageId," "Enabled,LocationId,RecycleCount,InitialWrite," - "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime " + "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime,ActionOnPurge " "FROM Media WHERE PoolId=%s AND MediaType='%s' AND VolStatus IN ('Full'," "'Recycle','Purged','Used','Append') AND Enabled=1 " "ORDER BY LastWritten LIMIT 1", @@ -356,7 +356,7 @@ db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr "MaxVolFiles,Recycle,Slot,FirstWritten,LastWritten,InChanger," "EndFile,EndBlock,VolParts,LabelType,LabelDate,StorageId," "Enabled,LocationId,RecycleCount,InitialWrite," - "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime " + "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime,ActionOnPurge " "FROM Media WHERE PoolId=%s AND MediaType='%s' AND Enabled=1 " "AND VolStatus='%s' " "%s " @@ -437,6 +437,7 @@ db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr mr->RecyclePoolId = str_to_int64(row[34]); mr->VolReadTime = str_to_int64(row[35]); mr->VolWriteTime = str_to_int64(row[36]); + mr->ActionOnPurge = str_to_int64(row[37]); sql_free_result(mdb); diff --git a/bacula/src/dird/ua_purge.c b/bacula/src/dird/ua_purge.c index c031febc12..da53e4d0d8 100644 --- a/bacula/src/dird/ua_purge.c +++ b/bacula/src/dird/ua_purge.c @@ -571,13 +571,79 @@ static BSOCK *open_sd_bsock(UAContext *ua) return ua->jcr->store_bsock; } +static void do_actions_on_purge(UAContext *ua, MEDIA_DBR *mr) +{ + BSOCK *sd; + POOL_DBR pr; + bool ok=false; + int dvd; + uint64_t VolBytes = 0; + char dev_name[MAX_NAME_LENGTH]; + + if (mr->ActionOnPurge & AOP_TRUNCATE) { + /* Send the command to truncate the volume after purge. If this feature + * is disabled for the specific device, this will be a no-op. + */ + + if ((sd=open_sd_bsock(ua)) != NULL) { + memset(&pr, 0, sizeof(POOL_DBR)); + + pr.PoolId = mr->PoolId; + strcpy(pr.Name, "Default"); /* We don't use the Pool in label */ + bstrncpy(dev_name, ua->jcr->wstore->dev_name(), sizeof(dev_name)); + + /* Protect us from spaces */ + bash_spaces(dev_name); + bash_spaces(mr->VolumeName); + bash_spaces(mr->MediaType); + bash_spaces(pr.Name); + + /* We set drive=-1 to let the storage decide of which drive + * to use + */ + sd->fsend("relabel %s OldName=%s NewName=%s PoolName=%s " + "MediaType=%s Slot=%d drive=%d\n", + dev_name, + mr->VolumeName, mr->VolumeName, + pr.Name, mr->MediaType, mr->Slot, -1); + + unbash_spaces(mr->VolumeName); + unbash_spaces(mr->MediaType); + while (sd->recv() >= 0) { + ua->send_msg("%s", sd->msg); + if (sscanf(sd->msg, "3000 OK label. VolBytes=%llu DVD=%d ", + &VolBytes, &dvd) == 2) + { + ok = true; + } + } + sd->signal(BNET_TERMINATE); + sd->close(); + ua->jcr->store_bsock = NULL; + + } else { + ua->error_msg(_("Could not connect to storage daemon")); + } + + if (ok) { + mr->VolBytes = VolBytes; + mr->VolFiles = 0; + if (!db_update_media_record(ua->jcr, ua->db, mr)) { + ua->error_msg(_("Can't update volume size in the catalog\n")); + } + ua->send_msg(_("The volume has been truncated\n")); + } else { + ua->warning_msg(_("Unable to truncate the volume\n")); + } + } +} + /* * IF volume status is Append, Full, Used, or Error, mark it Purged * Purged volumes can then be recycled (if enabled). */ bool mark_media_purged(UAContext *ua, MEDIA_DBR *mr) { - char dev_name[MAX_NAME_LENGTH]; JCR *jcr = ua->jcr; if (strcmp(mr->VolStatus, "Append") == 0 || strcmp(mr->VolStatus, "Full") == 0 || @@ -587,37 +653,6 @@ bool mark_media_purged(UAContext *ua, MEDIA_DBR *mr) if (!db_update_media_record(jcr, ua->db, mr)) { return false; } - -/* Code currently disabled */ -#if 0 - 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. - */ - BSOCK *sd; - if ((sd=open_sd_bsock(ua)) != NULL) { - bstrncpy(dev_name, ua->jcr->wstore->dev_name(), sizeof(dev_name)); - bash_spaces(dev_name); - bash_spaces(mr->VolumeName); - sd->fsend("action_on_purge %s vol=%s action=%d", - dev_name, - mr->VolumeName, - mr->ActionOnPurge); - unbash_spaces(mr->VolumeName); - while (sd->recv() >= 0) { - ua->send_msg("%s", sd->msg); - } - - sd->signal(BNET_TERMINATE); - sd->close(); - ua->jcr->store_bsock = NULL; - } else { - ua->error_msg(_("Could not connect to storage daemon")); - return false; - } - } -#endif - pm_strcpy(jcr->VolumeName, mr->VolumeName); generate_job_event(jcr, "VolumePurged"); generate_plugin_event(jcr, bEventVolumePurged); @@ -646,6 +681,10 @@ bool mark_media_purged(UAContext *ua, MEDIA_DBR *mr) ua->error_msg("%s", db_strerror(ua->db)); } } + + /* Do any ActionOnPurge for this Volume */ + do_actions_on_purge(ua, mr); + /* Send message to Job report, if it is a *real* job */ if (jcr && jcr->JobId > 0) { Jmsg(jcr, M_INFO, 0, _("All records pruned from Volume \"%s\"; marking it \"Purged\"\n"), diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index c9b74b000f..61e51fae2a 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -880,24 +880,26 @@ static bool unmount_cmd(JCR *jcr) * after purging a volume so that disk space will not be wasted. Only useful * for File Storage, of course. * + * + * It is currently disabled */ static bool action_on_purge_cmd(JCR *jcr) { - char devname[MAX_NAME_LENGTH]; - char volumename[MAX_NAME_LENGTH]; BSOCK *dir = jcr->dir_bsock; - DEVICE *dev; - DCR *dcr; - int action; /* Currently disabled */ dir->fsend(_("3916 Feature action_on_purge currently disabled\n")); + goto done; #if 0 + char devname[MAX_NAME_LENGTH]; + char volumename[MAX_NAME_LENGTH]; + int action; + /* TODO: Need to find a free device and ask for slot to the director */ if (sscanf(dir->msg, "action_on_purge %127s vol=%127s action=%d", - devname.c_str(), volumename.c_str(), &action)!= 5) + devname, volumename, &action)!= 5) { dir->fsend(_("3916 Error scanning action_on_purge command\n")); goto done; @@ -906,39 +908,10 @@ static bool action_on_purge_cmd(JCR *jcr) unbash_spaces(devname); /* Check if action is correct */ - switch (action) { - case AOP_TRUNCTATE: - break; - default: - dir->fsend(_("3919 Bad ActionOnPurge\n")); - goto done; - } - - /* TODO: Ask for Volume information - * - check recycle - * - find slot - */ - - /* 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; - } - - dev = dcr->dev; + if (action & AOP_TRUNCTATE) { - /* Store the VolumeName for opening and re-labeling the volume */ - bstrncpy(dcr->VolumeName, volumename.c_str(), sizeof(dcr->VolumeName)); - 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)) { - dir->fsend(_("3917 Volume recycled\n")); - } else { - dir->fsend(_("3918 Recycle failed\n")); - } + } + /* ... */ #endif done: