X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Fmac.c;h=d4de7c124176d863e4d587f9cfee0d1dc3765cab;hb=8ec628bc2c18b136d3496203ebd9fa1a0cdc50d5;hp=a1ad6a3a89d3575c5fb08e244762d284ef661ba7;hpb=eb326beecb6fc8803ab73e6395c68c5a29ac8cc2;p=bacula%2Fbacula diff --git a/bacula/src/stored/mac.c b/bacula/src/stored/mac.c index a1ad6a3a89..d4de7c1241 100644 --- a/bacula/src/stored/mac.c +++ b/bacula/src/stored/mac.c @@ -1,20 +1,12 @@ -/* - * SD -- mac.c -- responsible for doing - * migration, archive, and copy jobs. - * - * Kern Sibbald, January MMVI - * - * Version $Id$ - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2006-2006 Free Software Foundation Europe e.V. + Copyright (C) 2006-2010 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 + modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. @@ -23,16 +15,23 @@ 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 + You should have received a copy of the GNU Affero 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 John Walker. + 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, copy, and virtual backup jobs. + * + * Kern Sibbald, January MMVI + * + */ #include "bacula.h" #include "stored.h" @@ -57,7 +56,7 @@ bool do_mac(JCR *jcr) char ec1[50]; DEVICE *dev; - switch(jcr->JobType) { + switch(jcr->getJobType()) { case JT_MIGRATE: Type = "Migration"; break; @@ -67,6 +66,9 @@ bool do_mac(JCR *jcr) case JT_COPY: Type = "Copy"; break; + case JT_BACKUP: + Type = "Virtual Backup"; + break; default: Type = "Unknown"; break; @@ -81,8 +83,6 @@ bool do_mac(JCR *jcr) } Dmsg2(100, "read_dcr=%p write_dcr=%p\n", jcr->read_dcr, jcr->dcr); - - create_restore_volume_list(jcr); if (jcr->NumReadVolumes == 0) { Jmsg(jcr, M_FATAL, 0, _("No Volume names found for %s.\n"), Type); goto bail_out; @@ -94,13 +94,13 @@ bool do_mac(JCR *jcr) /* 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); + jcr->setJobStatus(JS_ErrorTerminated); 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); + jcr->setJobStatus(JS_Running); dir_send_job_status(jcr); begin_data_spool(jcr->dcr); @@ -108,7 +108,9 @@ bool do_mac(JCR *jcr) jcr->dcr->VolFirstIndex = jcr->dcr->VolLastIndex = 0; jcr->run_time = time(NULL); + set_start_vol_position(jcr->dcr); + jcr->JobFiles = 0; ok = read_records(jcr->read_dcr, record_cb, mount_next_read_volume); goto ok_out; @@ -118,6 +120,7 @@ bail_out: ok_out: if (jcr->dcr) { dev = jcr->dcr->dev; + Dmsg1(100, "ok=%d\n", ok); if (ok || dev->can_write()) { /* Flush out final partial block of this session */ if (!write_block_to_device(jcr->dcr)) { @@ -132,7 +135,7 @@ ok_out: if (!ok) { discard_data_spool(jcr->dcr); } else { - /* Note: if commit is OK, the device will remain locked */ + /* Note: if commit is OK, the device will remain blocked */ commit_data_spool(jcr->dcr); } @@ -155,21 +158,18 @@ ok_out: } } - free_restore_volume_list(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); + jcr->setJobStatus(JS_Terminated); } generate_daemon_event(jcr, "JobEnd"); - bnet_fsend(dir, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, - edit_uint64(jcr->JobBytes, ec1)); - Dmsg4(200, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, ec1); + dir->fsend(Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, + edit_uint64(jcr->JobBytes, ec1), jcr->JobErrors); + Dmsg4(100, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, ec1); dir->signal(BNET_EOD); /* send EOD to Director daemon */ @@ -186,8 +186,13 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) JCR *jcr = dcr->jcr; DEVICE *dev = jcr->dcr->dev; char buf1[100], buf2[100]; - int32_t stream; +#ifdef xxx + Dmsg5(000, "on entry 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); +#endif /* If label and not for us, discard it */ if (rec->FileIndex < 0 && rec->match_stat <= 0) { return true; @@ -200,17 +205,38 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) case EOM_LABEL: return true; /* don't write vol labels */ } +// if (jcr->getJobType() == JT_BACKUP) { + /* + * For normal migration jobs, FileIndex values are sequential because + * we are dealing with one job. However, for Vbackup (consolidation), + * we will be getting records from multiple jobs and writing them back + * out, so we need to ensure that the output FileIndex is sequential. + * We do so by detecting a FileIndex change and incrementing the + * JobFiles, which we then use as the output FileIndex. + */ + if (rec->FileIndex >= 0) { + /* If something changed, increment FileIndex */ + if (rec->VolSessionId != rec->last_VolSessionId || + rec->VolSessionTime != rec->last_VolSessionTime || + rec->FileIndex != rec->last_FileIndex) { + jcr->JobFiles++; + rec->last_VolSessionId = rec->VolSessionId; + rec->last_VolSessionTime = rec->VolSessionTime; + rec->last_FileIndex = rec->FileIndex; + } + rec->FileIndex = jcr->JobFiles; /* set sequential output FileIndex */ + } +// } /* * Modify record SessionId and SessionTime to correspond to * output. */ rec->VolSessionId = jcr->VolSessionId; rec->VolSessionTime = jcr->VolSessionTime; - Dmsg5(200, "before write_rec JobId=%d FI=%s SessId=%d Strm=%s len=%d\n", + Dmsg5(200, "before write 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); - + stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len); while (!write_record_to_block(jcr->dcr->block, rec)) { Dmsg4(200, "!write_record_to_block blkpos=%u:%u len=%d rem=%d\n", dev->file, dev->block_num, rec->data_len, rec->remainder); @@ -223,35 +249,19 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) } 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 { + /* Restore packet */ + rec->VolSessionId = rec->last_VolSessionId; + rec->VolSessionTime = rec->last_VolSessionTime; + if (rec->FileIndex < 0) { return true; /* don't send LABELs to Dir */ } + jcr->JobBytes += rec->data_len; /* increment bytes this job */ 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); - /* 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->m_spool = true; - } - Dmsg0(850, "Send attributes to dir.\n"); - if (!dir_update_file_attributes(jcr->dcr, rec)) { - jcr->dir_bsock->m_spool = false; - Jmsg(jcr, M_FATAL, 0, _("Error updating file attributes. ERR=%s\n"), - bnet_strerror(jcr->dir_bsock)); - return false; - } - jcr->dir_bsock->m_spool = false; - } - } + send_attrs_to_dir(jcr, rec); return true; }