X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Fmac.c;h=f2435e7838a7b9f7a3f10eff7b21407d8b2d036f;hb=36b40d5c7f3ff90565ab73ac75f0dc4f6660ff37;hp=aedbf100b45d05dd2e53ac8651a45cc8cb705be3;hpb=f2dfd500c0acf5ec87f363bc40cddf51b1c1ba7c;p=bacula%2Fbacula diff --git a/bacula/src/stored/mac.c b/bacula/src/stored/mac.c index aedbf100b4..f2435e7838 100644 --- a/bacula/src/stored/mac.c +++ b/bacula/src/stored/mac.c @@ -1,25 +1,38 @@ +/* + Bacula® - The Network Backup Solution + + Copyright (C) 2006-2008 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. + This program is Free Software; you can redistribute it and/or + modify it under the terms of version two of the GNU General Public + License as published by the Free Software Foundation and included + in the file LICENSE. + + 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 GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + + Bacula® is a registered trademark of Kern Sibbald. + The licensor of Bacula is the Free Software Foundation Europe + (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, + Switzerland, email:ftf@fsfeurope.org. +*/ /* * SD -- mac.c -- responsible for doing - * migration, archive, and copy jobs. + * migration, archive, copy, and virtual backup 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" @@ -44,7 +57,7 @@ bool do_mac(JCR *jcr) char ec1[50]; DEVICE *dev; - switch(jcr->JobType) { + switch(jcr->get_JobType()) { case JT_MIGRATE: Type = "Migration"; break; @@ -54,6 +67,9 @@ bool do_mac(JCR *jcr) case JT_COPY: Type = "Copy"; break; + case JT_BACKUP: + Type = "Virtual Backup"; + break; default: Type = "Unknown"; break; @@ -62,66 +78,89 @@ bool do_mac(JCR *jcr) Dmsg0(20, "Start read data.\n"); + if (!jcr->read_dcr || !jcr->dcr) { + Jmsg(jcr, M_FATAL, 0, _("Read and write devices not properly initialized.\n")); + goto bail_out; + } + Dmsg2(100, "read_dcr=%p write_dcr=%p\n", jcr->read_dcr, jcr->dcr); + create_restore_volume_list(jcr); - if (jcr->NumVolumes == 0) { + if (jcr->NumReadVolumes == 0) { Jmsg(jcr, M_FATAL, 0, _("No Volume names found for %s.\n"), Type); - free_restore_volume_list(jcr); - return false; + goto bail_out; } - Dmsg3(200, "Found %d volumes names for %s. First=%s\n", jcr->NumVolumes, + Dmsg3(200, "Found %d volumes names for %s. First=%s\n", jcr->NumReadVolumes, 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)) { + /* Ready devices for reading and writing */ + if (!acquire_device_for_read(jcr->read_dcr) || + !acquire_device_for_append(jcr->dcr)) { set_jcr_job_status(jcr, JS_ErrorTerminated); - ok = false; goto bail_out; } + + Dmsg2(200, "===== After acquire pos %u:%u\n", jcr->dcr->dev->file, jcr->dcr->dev->block_num); + + set_jcr_job_status(jcr, JS_Running); + dir_send_job_status(jcr); + + begin_data_spool(jcr->dcr); + begin_attribute_spool(jcr); + jcr->dcr->VolFirstIndex = jcr->dcr->VolLastIndex = 0; jcr->run_time = time(NULL); + set_start_vol_position(jcr->dcr); ok = read_records(jcr->read_dcr, record_cb, mount_next_read_volume); + goto ok_out; 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(), dev->bstrerror()); - Dmsg0(100, _("Set ok=FALSE after write_block_to_device.\n")); - ok = false; + ok = false; + +ok_out: + if (jcr->dcr) { + 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(), dev->bstrerror()); + Dmsg0(100, _("Set ok=FALSE after write_block_to_device.\n")); + ok = false; + } + Dmsg2(200, "Flush block to device pos %u:%u\n", dev->file, dev->block_num); + } + + if (!ok) { + discard_data_spool(jcr->dcr); + } else { + /* Note: if commit is OK, the device will remain locked */ + commit_data_spool(jcr->dcr); } - } + 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 (ok && dev->is_dvd()) { - ok = dvd_close_job(jcr->dcr); /* do DVD cleanup if any */ + if (!ok || job_canceled(jcr)) { + discard_attribute_spool(jcr); + } else { + commit_attribute_spool(jcr); + } } - /* Release the device -- and send final Vol info to DIR */ - release_device(jcr->dcr); - if (!release_device(jcr->read_dcr)) { - ok = false; + if (jcr->read_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 */ @@ -132,11 +171,11 @@ bail_out: set_jcr_job_status(jcr, JS_Terminated); } generate_daemon_event(jcr, "JobEnd"); - bnet_fsend(dir, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, + dir->fsend(Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, edit_uint64(jcr->JobBytes, ec1)); - Dmsg4(400, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, ec1); + Dmsg4(200, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, ec1); - bnet_sig(dir, BNET_EOD); /* send EOD to Director daemon */ + dir->signal(BNET_EOD); /* send EOD to Director daemon */ return ok; } @@ -148,41 +187,54 @@ bail_out: */ static bool record_cb(DCR *dcr, DEV_RECORD *rec) { - bool ok = true; JCR *jcr = dcr->jcr; + DEVICE *dev = jcr->dcr->dev; char buf1[100], buf2[100]; int32_t stream; + /* If label and not for us, discard it */ + if (rec->FileIndex < 0 && rec->match_stat <= 0) { + return true; + } + /* We want to write SOS_LABEL and EOS_LABEL discard all others */ switch (rec->FileIndex) { case PRE_LABEL: case VOL_LABEL: case EOT_LABEL: + case EOM_LABEL: return true; /* don't write vol labels */ } + /* + * Modify record SessionId and SessionTime to correspond to + * output. + */ 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); + Dmsg5(200, "before write_rec JobId=%d FI=%s SessId=%d Strm=%s len=%d\n", + jcr->JobId, + FI_to_ascii(buf1, 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); + Dmsg4(200, "!write_record_to_block blkpos=%u:%u len=%d rem=%d\n", + dev->file, dev->block_num, 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(), dev->bstrerror()); Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"), dev->print_name(), dev->bstrerror()); return false; } + Dmsg2(200, "===== Wrote block new pos %u:%u\n", dev->file, dev->block_num); } jcr->JobBytes += rec->data_len; /* increment bytes this job */ if (rec->FileIndex > 0) { jcr->JobFiles = rec->FileIndex; + } else { + return true; /* don't send LABELs to Dir */ } - Dmsg4(850, "write_record FI=%s SessId=%d Strm=%s len=%d\n", + Dmsg5(500, "wrote_record JobId=%d FI=%s SessId=%d Strm=%s len=%d\n", + jcr->JobId, FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len); @@ -191,19 +243,20 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) if (stream == STREAM_UNIX_ATTRIBUTES || stream == STREAM_UNIX_ATTRIBUTES_EX || crypto_digest_stream_type(stream) != CRYPTO_DIGEST_NONE) { if (!jcr->no_attributes) { + BSOCK *dir = jcr->dir_bsock; if (are_attributes_spooled(jcr)) { - jcr->dir_bsock->spool = true; + dir->set_spooling(); } Dmsg0(850, "Send attributes to dir.\n"); if (!dir_update_file_attributes(jcr->dcr, rec)) { - jcr->dir_bsock->spool = false; + dir->clear_spooling(); Jmsg(jcr, M_FATAL, 0, _("Error updating file attributes. ERR=%s\n"), - bnet_strerror(jcr->dir_bsock)); + dir->bstrerror()); return false; } - jcr->dir_bsock->spool = false; + dir->clear_spooling(); } } - return ok; + return true; }