]> git.sur5r.net Git - bacula/bacula/commitdiff
Fix ActionOnPurge with a relabel command
authorEric Bollengier <eric@eb.homelinux.org>
Thu, 28 Jan 2010 21:00:35 +0000 (22:00 +0100)
committerEric Bollengier <eric@eb.homelinux.org>
Mon, 2 Aug 2010 14:49:24 +0000 (16:49 +0200)
bacula/src/cats/sql_find.c
bacula/src/dird/ua_purge.c
bacula/src/stored/dircmd.c

index 827f0cb00dc5f49ecceb7cccf481d56075d86b8d..e492035a5149f74188566dc33bfe03626eb89f9f 100644 (file)
@@ -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);
 
index c031febc125efd5a4ea8916b6cbf0b01e8408dc3..da53e4d0d8ddf504e970a07a38d038c1c058a842 100644 (file)
@@ -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"),
index c9b74b000f875c6395e7039af29430aa7510b098..61e51fae2a43536f35de9e7d95e410b173eb951d 100644 (file)
@@ -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: