]> git.sur5r.net Git - bacula/bacula/commitdiff
Add mac.c file
authorKern Sibbald <kern@sibbald.com>
Tue, 7 Feb 2006 14:30:44 +0000 (14:30 +0000)
committerKern Sibbald <kern@sibbald.com>
Tue, 7 Feb 2006 14:30:44 +0000 (14:30 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2781 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/stored/mac.c [new file with mode: 0644]

diff --git a/bacula/src/stored/mac.c b/bacula/src/stored/mac.c
new file mode 100644 (file)
index 0000000..5e51f45
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * SD -- mac.c --  responsible for doing
+ *     migration, archive, and copy jobs.
+ *
+ *     Kern Sibbald, January MMVI
+ *
+ *   Version $Id$
+ */
+/*
+   Copyright (C) 2006 Kern Sibbald
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   version 2 as amended with additional clauses defined in the
+   file LICENSE in the main source directory.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+   the file LICENSE for additional details.
+
+ */
+
+#include "bacula.h"
+#include "stored.h"
+
+/* Import functions */
+extern char Job_end[];   
+
+/* Forward referenced subroutines */
+static bool record_cb(DCR *dcr, DEV_RECORD *rec);
+
+
+/*
+ *  Read Data and send to File Daemon
+ *   Returns: false on failure
+ *            true  on success
+ */
+bool do_mac(JCR *jcr)
+{
+   bool ok = true;
+   BSOCK *dir = jcr->dir_bsock;
+   const char *Type;
+   char ec1[50];
+   DEVICE *dev;
+
+   switch(jcr->JobType) {
+   case JT_MIGRATE:
+      Type = "Migration";
+      break;
+   case JT_ARCHIVE:
+      Type = "Archive";
+      break;
+   case JT_COPY:
+      Type = "Copy";
+      break;
+   default:
+      Type = "Unknown";
+      break;
+   }
+
+
+   Dmsg0(20, "Start read data.\n");
+
+
+   create_restore_volume_list(jcr);
+   if (jcr->NumVolumes == 0) {
+      Jmsg(jcr, M_FATAL, 0, _("No Volume names found for %s.\n"), Type);
+      free_restore_volume_list(jcr);
+      return false;
+   }
+
+   Dmsg3(200, "Found %d volumes names for %s. First=%s\n", jcr->NumVolumes,
+      jcr->VolList->VolumeName, Type);
+
+   /* Ready device for reading */
+   if (!acquire_device_for_read(jcr->read_dcr)) {
+      ok = false;
+      goto bail_out;
+   }
+
+   if (!acquire_device_for_append(jcr->dcr)) {
+      set_jcr_job_status(jcr, JS_ErrorTerminated);
+      ok = false;
+      goto bail_out;
+   }
+   jcr->dcr->VolFirstIndex = jcr->dcr->VolLastIndex = 0;
+   jcr->run_time = time(NULL);
+
+   ok = read_records(jcr->read_dcr, record_cb, mount_next_read_volume);
+
+bail_out:
+
+   dev = jcr->dcr->dev;
+   if (ok || dev->can_write()) {
+      /* Flush out final partial block of this session */
+      if (!write_block_to_device(jcr->dcr)) {
+         Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"),
+               dev->print_name(), strerror_dev(dev));
+         Dmsg0(100, _("Set ok=FALSE after write_block_to_device.\n"));
+         ok = false;
+      }
+   }  
+
+
+   if (ok && dev->is_dvd()) {
+      ok = dvd_close_job(jcr->dcr);   /* do DVD cleanup if any */
+   }
+   /* Release the device -- and send final Vol info to DIR */
+   release_device(jcr->dcr);
+
+   if (!release_device(jcr->read_dcr)) {
+      ok = false;
+   }
+
+   free_restore_volume_list(jcr);
+
+
+   if (!ok || job_canceled(jcr)) {
+      discard_attribute_spool(jcr);
+   } else {
+      commit_attribute_spool(jcr);
+   }
+
+   dir_send_job_status(jcr);          /* update director */
+
+
+   Dmsg0(30, "Done reading.\n");
+   jcr->end_time = time(NULL);
+   dequeue_messages(jcr);             /* send any queued messages */
+   if (ok) {
+      set_jcr_job_status(jcr, JS_Terminated);
+   }
+   generate_daemon_event(jcr, "JobEnd");
+   bnet_fsend(dir, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles,
+      edit_uint64(jcr->JobBytes, ec1));
+   Dmsg4(400, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, ec1); 
+       
+   bnet_sig(dir, BNET_EOD);           /* send EOD to Director daemon */
+
+   return ok;
+}
+
+/*
+ * Called here for each record from read_records()
+ *  Returns: true if OK
+ *           false if error
+ */
+static bool record_cb(DCR *dcr, DEV_RECORD *rec)
+{
+   bool ok = true;
+   JCR *jcr = dcr->jcr;
+   char buf1[100], buf2[100];
+   int32_t stream;   
+   
+   switch (rec->FileIndex) {                        
+   case PRE_LABEL:
+   case VOL_LABEL:
+   case EOT_LABEL:
+      return true;                    /* don't write vol labels */
+   }
+   rec->VolSessionId = jcr->VolSessionId;
+   rec->VolSessionTime = jcr->VolSessionTime;
+   Dmsg4(850, "before writ_rec FI=%d SessId=%d Strm=%s len=%d\n",
+      rec->FileIndex, rec->VolSessionId, 
+      stream_to_ascii(buf1, rec->Stream,rec->FileIndex),
+      rec->data_len);
+
+   while (!write_record_to_block(jcr->dcr->block, rec)) {
+      Dmsg2(850, "!write_record_to_block data_len=%d rem=%d\n", rec->data_len,
+                 rec->remainder);
+      if (!write_block_to_device(jcr->dcr)) {
+         DEVICE *dev = jcr->dcr->dev;
+         Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
+            dev->print_name(), strerror_dev(dev));
+         Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"),
+               dev->print_name(), strerror_dev(dev));
+         return false;
+      }
+   }
+   jcr->JobBytes += rec->data_len;   /* increment bytes this job */
+   if (rec->FileIndex > 0) {
+      jcr->JobFiles = rec->FileIndex;
+   }
+   Dmsg4(850, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
+      FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId,
+      stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len);
+
+   /* Send attributes and digest to Director for Catalog */
+   stream = rec->Stream;
+   if (stream == STREAM_UNIX_ATTRIBUTES || stream == STREAM_UNIX_ATTRIBUTES_EX ||
+       crypto_digest_stream_type(stream) != CRYPTO_DIGEST_NONE) {
+      if (!jcr->no_attributes) {
+         if (are_attributes_spooled(jcr)) {
+            jcr->dir_bsock->spool = true;
+         }
+         Dmsg0(850, "Send attributes to dir.\n");
+         if (!dir_update_file_attributes(jcr->dcr, rec)) {
+            jcr->dir_bsock->spool = false;
+            Jmsg(jcr, M_FATAL, 0, _("Error updating file attributes. ERR=%s\n"),
+               bnet_strerror(jcr->dir_bsock));
+            return false;
+         }
+         jcr->dir_bsock->spool = false;
+      }
+   }
+
+   return ok;
+}