]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/vbackup.c
tweak ua_prune
[bacula/bacula] / bacula / src / dird / vbackup.c
index 63d0756ede3987319a2b78ea10170c7c558988e2..75869419d3c7191b722751d41ba4a796b3486e47 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2008-2008 Free Software Foundation Europe e.V.
+   Copyright (C) 2008-2009 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
@@ -50,9 +50,7 @@
 
 static const int dbglevel = 10;
 
-static char OKbootstrap[] = "3000 OK bootstrap\n";
-
-static bool create_bootstrap_file(JCR *jcr, POOLMEM *jobids);
+static bool create_bootstrap_file(JCR *jcr, char *jobids);
 void vbackup_cleanup(JCR *jcr, int TermCode);
 
 /* 
@@ -61,6 +59,7 @@ void vbackup_cleanup(JCR *jcr, int TermCode);
  */
 bool do_vbackup_init(JCR *jcr)
 {
+
    if (!get_or_create_fileset_record(jcr)) {
       Dmsg1(dbglevel, "JobId=%d no FileSet\n", (int)jcr->JobId);
       return false;
@@ -72,6 +71,12 @@ bool do_vbackup_init(JCR *jcr)
       return false;
    }
 
+   jcr->jr.PoolId = get_or_create_pool_record(jcr, jcr->pool->name());
+   if (jcr->jr.PoolId == 0) {
+      Dmsg1(dbglevel, "JobId=%d no PoolId\n", (int)jcr->JobId);
+      Jmsg(jcr, M_FATAL, 0, _("Could not get or create a Pool record.\n"));
+      return false;
+   }
    /*
     * Note, at this point, pool is the pool for this job.  We
     *  transfer it to rpool (read pool), and a bit later,
@@ -81,6 +86,8 @@ bool do_vbackup_init(JCR *jcr)
    jcr->rpool = jcr->pool;            /* save read pool */
    pm_strcpy(jcr->rpool_source, jcr->pool_source);
 
+   /* If pool storage specified, use it for restore */
+   copy_rstorage(jcr, jcr->pool->storage, _("Pool resource"));
 
    Dmsg2(dbglevel, "Read pool=%s (From %s)\n", jcr->rpool->name(), jcr->rpool_source);
 
@@ -91,21 +98,6 @@ bool do_vbackup_init(JCR *jcr)
       Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
    }
 
-   POOLMEM *jobids = get_pool_memory(PM_FNAME);
-   db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, jobids);
-   Dmsg1(100, "Accurate jobids=%s\n", jobids);
-   if (*jobids == 0) {
-      free_pool_memory(jobids);
-      Jmsg(jcr, M_FATAL, 0, _("Cannot find previous JobIds.\n"));
-      return false;
-   }
-
-   if (!create_bootstrap_file(jcr, jobids)) {
-      Jmsg(jcr, M_FATAL, 0, _("Could not get or create the FileSet record.\n"));
-      free_pool_memory(jobids);
-      return false;
-   }
-   free_pool_memory(jobids);
 
    /*
     * If the original backup pool has a NextPool, make sure a 
@@ -118,21 +110,22 @@ bool do_vbackup_init(JCR *jcr)
          return false;
       }
    }
-
    if (!set_migration_wstorage(jcr, jcr->pool)) {
       return false;
    }
+   jcr->pool = jcr->pool->NextPool;
    pm_strcpy(jcr->pool_source, _("Job Pool's NextPool resource"));
 
    Dmsg2(dbglevel, "Write pool=%s read rpool=%s\n", jcr->pool->name(), jcr->rpool->name());
 
-   create_clones(jcr);
+// create_clones(jcr);
 
    return true;
 }
 
 /*
- * Do a backup of the specified FileSet
+ * Do a virtual backup, which consolidates all previous backups into
+ *  a sort of synthetic Full.
  *
  *  Returns:  false on failure
  *            true  on success
@@ -141,10 +134,57 @@ bool do_vbackup(JCR *jcr)
 {
    char ed1[100];
    BSOCK *sd;
+   char *p;
+   db_list_ctx jobids;
+
+   Dmsg2(100, "rstorage=%p wstorage=%p\n", jcr->rstorage, jcr->wstorage);
+   Dmsg2(100, "Read store=%s, write store=%s\n", 
+      ((STORE *)jcr->rstorage->first())->name(),
+      ((STORE *)jcr->wstorage->first())->name());
 
    /* Print Job Start message */
-   Jmsg(jcr, M_INFO, 0, _("Start Vbackup JobId %s, Job=%s\n"),
+   Jmsg(jcr, M_INFO, 0, _("Start Virtual Backup JobId %s, Job=%s\n"),
         edit_uint64(jcr->JobId, ed1), jcr->Job);
+   if (!jcr->accurate) {
+      Jmsg(jcr, M_WARNING, 0, 
+_("This Job is not an Accurate backup so is not equivalent to a Full backup.\n"));
+   }
+
+   jcr->jr.JobLevel = L_VIRTUAL_FULL;
+   db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, &jobids);
+   Dmsg1(10, "Accurate jobids=%s\n", jobids.list);
+   if (jobids.count == 0) {
+      Jmsg(jcr, M_FATAL, 0, _("No previous Jobs found.\n"));
+      return false;
+   }
+
+   jcr->jr.JobLevel = L_FULL;
+
+   /*
+    * Now we find the last job that ran and store it's info in
+    *  the previous_jr record.  We will set our times to the
+    *  values from that job so that anything changed after that
+    *  time will be picked up on the next backup.
+    */
+   p = strrchr(jobids.list, ',');           /* find last jobid */
+   if (p != NULL) {
+      p++;
+   } else {
+      p = jobids.list;
+   }
+   memset(&jcr->previous_jr, 0, sizeof(jcr->previous_jr));
+   jcr->previous_jr.JobId = str_to_int64(p);
+   Dmsg1(10, "Previous JobId=%s\n", p);
+   if (!db_get_job_record(jcr, jcr->db, &jcr->previous_jr)) {
+      Jmsg(jcr, M_FATAL, 0, _("Error getting Job record for previous Job: ERR=%s"),
+               db_strerror(jcr->db));
+      return false;
+   }
+
+   if (!create_bootstrap_file(jcr, jobids.list)) {
+      Jmsg(jcr, M_FATAL, 0, _("Could not get or create the FileSet record.\n"));
+      return false;
+   }
 
    /*
     * Open a message channel connection with the Storage
@@ -161,28 +201,15 @@ bool do_vbackup(JCR *jcr)
       return false;
    }
    sd = jcr->store_bsock;
+
    /*
     * Now start a job with the Storage daemon
     */
-   Dmsg2(100, "rstorage=%p wstorage=%p\n", jcr->rstorage, jcr->wstorage);
-   Dmsg2(100, "Read store=%s, write store=%s\n", 
-      ((STORE *)jcr->rstorage->first())->name(),
-      ((STORE *)jcr->wstorage->first())->name());
-   if (((STORE *)jcr->rstorage->first())->name() == ((STORE *)jcr->wstorage->first())->name()) {
-      Jmsg(jcr, M_FATAL, 0, _("Read storage \"%s\" same as write storage.\n"),
-           ((STORE *)jcr->rstorage->first())->name());
-      return false;
-   }
-   if (!start_storage_daemon_job(jcr, jcr->rstorage, jcr->wstorage)) {
+   if (!start_storage_daemon_job(jcr, jcr->rstorage, jcr->wstorage, /*send_bsr*/true)) {
       return false;
    }
    Dmsg0(100, "Storage daemon connection OK\n");
 
-   if (!send_bootstrap_file(jcr, sd) ||
-       !response(jcr, sd, OKbootstrap, "Bootstrap", DISPLAY_ERROR)) {
-      return false;
-   }
-
    /*    
     * We re-update the job start record so that the start
     *  time is set after the run before job.  This avoids 
@@ -198,7 +225,7 @@ bool do_vbackup(JCR *jcr)
    jcr->jr.JobTDate = jcr->start_time;
    set_jcr_job_status(jcr, JS_Running);
 
-   /* Update job start record for this migration control job */
+   /* Update job start record */
    if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
       Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
       return false;
@@ -223,7 +250,7 @@ bool do_vbackup(JCR *jcr)
    set_jcr_job_status(jcr, JS_Running);
 
    /* Pickup Job termination data */
-   /* Note, the SD stores in jcr->JobFiles/ReadBytes/JobBytes/Errors */
+   /* Note, the SD stores in jcr->JobFiles/ReadBytes/JobBytes/JobErrors */
    wait_for_storage_daemon_termination(jcr);
    set_jcr_job_status(jcr, jcr->SDJobStatus);
    db_write_batch_file_records(jcr);    /* used by bulk batch file insert */
@@ -244,13 +271,14 @@ void vbackup_cleanup(JCR *jcr, int TermCode)
    char sdt[50], edt[50], schedt[50];
    char ec1[30], ec3[30], ec4[30], compress[50];
    char ec7[30], ec8[30], elapsed[50];
-   char term_code[100], fd_term_msg[100], sd_term_msg[100];
+   char term_code[100], sd_term_msg[100];
    const char *term_msg;
    int msg_type = M_INFO;
    MEDIA_DBR mr;
    CLIENT_DBR cr;
    double kbps, compression;
    utime_t RunTime;
+   POOL_MEM query(PM_MESSAGE);
 
    Dmsg2(100, "Enter backup_cleanup %d %c\n", TermCode, TermCode);
    memset(&mr, 0, sizeof(mr));
@@ -262,17 +290,15 @@ void vbackup_cleanup(JCR *jcr, int TermCode)
    jcr->JobBytes = jcr->SDJobBytes;
    update_job_end(jcr, TermCode);
 
-#ifdef xxx
-   /* ***FIXME*** set to time of last incremental */
    /* Update final items to set them to the previous job's values */
    Mmsg(query, "UPDATE Job SET StartTime='%s',EndTime='%s',"
                "JobTDate=%s WHERE JobId=%s", 
       jcr->previous_jr.cStartTime, jcr->previous_jr.cEndTime, 
       edit_uint64(jcr->previous_jr.JobTDate, ec1),
-      edit_uint64(mig_jcr->jr.JobId, ec2));
-   db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
-#endif
+      edit_uint64(jcr->JobId, ec3));
+   db_sql_query(jcr->db, query.c_str(), NULL, NULL);
 
+   /* Get the fully updated job record */
    if (!db_get_job_record(jcr, jcr->db, &jcr->jr)) {
       Jmsg(jcr, M_WARNING, 0, _("Error getting Job record for Job report: ERR=%s"),
          db_strerror(jcr->db));
@@ -296,7 +322,7 @@ void vbackup_cleanup(JCR *jcr, int TermCode)
 
    switch (jcr->JobStatus) {
       case JS_Terminated:
-         if (jcr->Errors || jcr->SDErrors) {
+         if (jcr->JobErrors || jcr->SDErrors) {
             term_msg = _("Backup OK -- with warnings");
          } else {
             term_msg = _("Backup OK");
@@ -359,16 +385,13 @@ void vbackup_cleanup(JCR *jcr, int TermCode)
          bsnprintf(compress, sizeof(compress), "%.1f %%", compression);
       }
    }
-   jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg));
    jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg));
 
-// bmicrosleep(15, 0);                /* for debugging SIGHUP */
-
-   Jmsg(jcr, msg_type, 0, _("Bacula %s %s (%s): %s\n"
+   Jmsg(jcr, msg_type, 0, _("%s %s %s (%s): %s\n"
 "  Build OS:               %s %s %s\n"
 "  JobId:                  %d\n"
 "  Job:                    %s\n"
-"  Backup Level:           %s%s\n"
+"  Backup Level:           Virtual Full\n"
 "  Client:                 \"%s\" %s\n"
 "  FileSet:                \"%s\" %s\n"
 "  Pool:                   \"%s\" (From %s)\n"
@@ -382,10 +405,6 @@ void vbackup_cleanup(JCR *jcr, int TermCode)
 "  SD Files Written:       %s\n"
 "  SD Bytes Written:       %s (%sB)\n"
 "  Rate:                   %.1f KB/s\n"
-"  Software Compression:   %s\n"
-"  VSS:                    %s\n"
-"  Encryption:             %s\n"
-"  Accurate:               %s\n"
 "  Volume name(s):         %s\n"
 "  Volume Session Id:      %d\n"
 "  Volume Session Time:    %d\n"
@@ -393,11 +412,10 @@ void vbackup_cleanup(JCR *jcr, int TermCode)
 "  SD Errors:              %d\n"
 "  SD termination status:  %s\n"
 "  Termination:            %s\n\n"),
-        my_name, VERSION, LSMDATE, edt,
+        BACULA, my_name, VERSION, LSMDATE, edt,
         HOST_OS, DISTNAME, DISTVER,
         jcr->jr.JobId,
         jcr->jr.Job,
-        level_to_str(jcr->get_JobLevel()), jcr->since,
         jcr->client->name(), cr.Uname,
         jcr->fileset->name(), jcr->FSCreateTime,
         jcr->pool->name(), jcr->pool_source,
@@ -412,10 +430,6 @@ void vbackup_cleanup(JCR *jcr, int TermCode)
         edit_uint64_with_commas(jcr->jr.JobBytes, ec3),
         edit_uint64_with_suffix(jcr->jr.JobBytes, ec4),
         kbps,
-        compress,
-        jcr->VSS?_("yes"):_("no"),
-        jcr->Encrypt?_("yes"):_("no"),
-        jcr->accurate?_("yes"):_("no"),
         jcr->VolumeName,
         jcr->VolSessionId,
         jcr->VolSessionTime,
@@ -452,7 +466,7 @@ int insert_bootstrap_handler(void *ctx, int num_fields, char **row)
 }
 
 
-static bool create_bootstrap_file(JCR *jcr, POOLMEM *jobids)
+static bool create_bootstrap_file(JCR *jcr, char *jobids)
 {
    RESTORE_CTX rx;
    UAContext *ua;
@@ -492,11 +506,10 @@ static bool create_bootstrap_file(JCR *jcr, POOLMEM *jobids)
 #endif
 
    complete_bsr(ua, rx.bsr);
-//   Dmsg0(000, "Print bsr\n");
-//   print_bsr(ua, rx.bsr);
-
    jcr->ExpectedFiles = write_bsr_file(ua, rx);
-   Dmsg1(000, "Found %d files to consolidate.\n", jcr->ExpectedFiles);
+   if (debug_level >= 10) {
+      Dmsg1(000,  "Found %d files to consolidate.\n", jcr->ExpectedFiles);
+   }
    if (jcr->ExpectedFiles == 0) {
       free_ua_context(ua);
       free_bsr(rx.bsr);