From 58c2fb959bdcbfa2afdf55325a4c192ddbcac7fb Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Tue, 7 Feb 2006 14:30:44 +0000 Subject: [PATCH] Add mac.c file git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2781 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/stored/mac.c | 209 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 bacula/src/stored/mac.c diff --git a/bacula/src/stored/mac.c b/bacula/src/stored/mac.c new file mode 100644 index 0000000000..5e51f453f6 --- /dev/null +++ b/bacula/src/stored/mac.c @@ -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; +} -- 2.39.5