]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/ua_purge.c
Disabled ActionOnPurge waiting for a fix
[bacula/bacula] / bacula / src / dird / ua_purge.c
index 9d2276801f29cdea2920a9d374c72439869af203..c031febc125efd5a4ea8916b6cbf0b01e8408dc3 100644 (file)
@@ -87,11 +87,11 @@ int purgecmd(UAContext *ua, const char *cmd)
       NULL};
 
    ua->warning_msg(_(
-      "\nThis command is can be DANGEROUS!!!\n\n"
+      "\nThis command can be DANGEROUS!!!\n\n"
       "It purges (deletes) all Files from a Job,\n"
       "JobId, Client or Volume; or it purges (deletes)\n"
       "all Jobs from a Client or Volume without regard\n"
-      "for retention periods. Normally you should use the\n"
+      "to retention periods. Normally you should use the\n"
       "PRUNE command, which respects retention periods.\n"));
 
    if (!open_db(ua)) {
@@ -133,8 +133,6 @@ int purgecmd(UAContext *ua, const char *cmd)
       case 1:                         /* Volume */
          if (select_media_dbr(ua, &mr)) {
             purge_jobs_from_volume(ua, &mr, /*force*/true);
-            
-purge_jobs_from_volume(ua, &mr);
          }
          return 1;
       }
@@ -285,6 +283,10 @@ void purge_files_from_jobs(UAContext *ua, char *jobs)
    db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL);
    Dmsg1(050, "Delete File sql=%s\n", query.c_str());
 
+   Mmsg(query, "DELETE FROM BaseFiles WHERE JobId IN (%s)", jobs);
+   db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL);
+   Dmsg1(050, "Delete BaseFiles sql=%s\n", query.c_str());
+
    /*
     * Now mark Job as having files purged. This is necessary to
     * avoid having too many Jobs to process in future prunings. If
@@ -359,6 +361,57 @@ void purge_files_from_job_list(UAContext *ua, del_ctx &del)
    }
 }
 
+/*
+ * Change the type of the next copy job to backup.
+ * We need to upgrade the next copy of a normal job,
+ * and also upgrade the next copy when the normal job
+ * already have been purged.
+ *
+ *   JobId: 1   PriorJobId: 0    (original)
+ *   JobId: 2   PriorJobId: 1    (first copy)
+ *   JobId: 3   PriorJobId: 1    (second copy)
+ *
+ *   JobId: 2   PriorJobId: 1    (first copy, now regular backup)
+ *   JobId: 3   PriorJobId: 1    (second copy)
+ *
+ *  => Search through PriorJobId in jobid and
+ *                    PriorJobId in PriorJobId (jobid)
+ */
+void upgrade_copies(UAContext *ua, char *jobs)
+{
+   POOL_MEM query(PM_MESSAGE);
+   
+   db_lock(ua->db);
+   /* Do it in two times for mysql */
+   Mmsg(query, "CREATE TEMPORARY TABLE cpy_tmp AS "
+                  "SELECT MIN(JobId) AS JobId FROM Job "     /* Choose the oldest job */
+                   "WHERE Type='%c' "
+                     "AND ( PriorJobId IN (%s) "
+                         "OR "
+                          " PriorJobId IN ( "
+                             "SELECT PriorJobId "
+                               "FROM Job "
+                              "WHERE JobId IN (%s) "
+                               " AND Type='B' "
+                            ") "
+                         ") "
+                   "GROUP BY PriorJobId ",           /* one result per copy */
+        JT_JOB_COPY, jobs, jobs);
+   db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL);
+   Dmsg1(050, "Upgrade copies Log sql=%s\n", query.c_str());
+
+   /* Now upgrade first copy to Backup */
+   Mmsg(query, "UPDATE Job SET Type='B' "           /* JT_JOB_COPY => JT_BACKUP  */
+                "WHERE JobId IN ( SELECT JobId FROM cpy_tmp )");
+
+   db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL);
+
+   Mmsg(query, "DROP TABLE cpy_tmp");
+   db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL);
+
+   db_unlock(ua->db);
+}
+
 /*
  * Remove all records from catalog for a list of JobIds
  */
@@ -377,13 +430,15 @@ void purge_jobs_from_catalog(UAContext *ua, char *jobs)
    db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL);
    Dmsg1(050, "Delete Log sql=%s\n", query.c_str());
 
+   upgrade_copies(ua, jobs);
+
    /* Now remove the Job record itself */
    Mmsg(query, "DELETE FROM Job WHERE JobId IN (%s)", jobs);
    db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL);
+
    Dmsg1(050, "Delete Job sql=%s\n", query.c_str());
 }
 
-
 void purge_files_from_volume(UAContext *ua, MEDIA_DBR *mr )
 {} /* ***FIXME*** implement */
 
@@ -501,12 +556,28 @@ bail_out:
    return purged;
 }
 
+static BSOCK *open_sd_bsock(UAContext *ua)
+{
+   STORE *store = ua->jcr->wstore;
+
+   if (!ua->jcr->store_bsock) {
+      ua->send_msg(_("Connecting to Storage daemon %s at %s:%d ...\n"),
+         store->name(), store->address, store->SDport);
+      if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) {
+         ua->error_msg(_("Failed to connect to Storage daemon.\n"));
+         return NULL;
+      }
+   }
+   return ua->jcr->store_bsock;
+}
+
 /*
  * 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 ||
@@ -516,6 +587,37 @@ 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);