2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2015 Kern Sibbald
5 Copyright (C) 2001-2014 Free Software Foundation Europe e.V.
7 The original author of Bacula is Kern Sibbald, with contributions
8 from many others, a complete list can be found in the file AUTHORS.
10 You may use this file and others of this release according to the
11 license defined in the LICENSE file, which includes the Affero General
12 Public License, v3.0 ("AGPLv3") and some additional permissions and
13 terms pursuant to its AGPLv3 Section 7.
15 This notice must be preserved when any source code is
16 conveyed and/or propagated.
18 Bacula(R) is a registered trademark of Kern Sibbald.
22 * block_util.c -- tape block utility functions
24 * Kern Sibbald, split from block.c March MMXII
32 static const int dbgel = 160;
34 #ifdef DEBUG_BLOCK_CHECKSUM
35 static const bool debug_block_checksum = true;
37 static const bool debug_block_checksum = false;
40 #ifdef NO_TAPE_WRITE_TEST
41 static const bool no_tape_write_test = true;
43 static const bool no_tape_write_test = false;
47 * Dump the block header, then walk through
48 * the block printing out the record headers.
50 void dump_block(DEV_BLOCK *b, const char *msg)
54 char Id[BLKHDR_ID_LENGTH+1];
55 uint32_t CheckSum, BlockCheckSum;
56 uint32_t block_len, reclen;
58 uint32_t VolSessionId, VolSessionTime, data_len;
62 char buf1[100], buf2[100];
64 if ((debug_level & ~DT_ALL) < 250) {
67 unser_begin(b->buf, BLKHDR1_LENGTH);
68 unser_uint32(CheckSum);
69 unser_uint32(block_len);
70 unser_uint32(BlockNumber);
71 unser_bytes(Id, BLKHDR_ID_LENGTH);
72 ASSERT(unser_length(b->buf) == BLKHDR1_LENGTH);
73 Id[BLKHDR_ID_LENGTH] = 0;
75 unser_uint32(VolSessionId);
76 unser_uint32(VolSessionTime);
80 VolSessionId = VolSessionTime = 0;
85 if (block_len > 4000000 || block_len < BLKHDR_CS_LENGTH) {
86 Dmsg4(20, "!!!Dump block %s %p blocksize too %s %lu\n",
88 (block_len < BLKHDR_CS_LENGTH)?"small":"big",
93 BlockCheckSum = bcrc32((uint8_t *)b->buf+BLKHDR_CS_LENGTH,
94 block_len-BLKHDR_CS_LENGTH);
95 Pmsg6(000, _("Dump block %s %p: size=%d BlkNum=%d\n"
96 " Hdrcksum=%x cksum=%x\n"),
97 msg, b, block_len, BlockNumber, CheckSum, BlockCheckSum);
100 unser_begin(p, WRITE_RECHDR_LENGTH);
101 if (rhl == RECHDR1_LENGTH) {
102 unser_uint32(VolSessionId);
103 unser_uint32(VolSessionTime);
105 unser_int32(FileIndex);
107 unser_uint32(data_len);
110 Pmsg6(000, _(" Rec: VId=%u VT=%u FI=%s Strm=%s len=%d reclen=%d\n"),
111 VolSessionId, VolSessionTime, FI_to_ascii(buf1, FileIndex),
112 stream_to_ascii(buf2, Stream, FileIndex), data_len, reclen);
117 * Create a new block structure.
118 * We pass device so that the block can inherit the
119 * min and max block sizes.
121 DEV_BLOCK *new_block(DEVICE *dev)
123 DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK));
126 memset(block, 0, sizeof(DEV_BLOCK));
128 /* If the user has specified a max_block_size, use it as the default */
129 if (dev->max_block_size == 0) {
130 len = DEFAULT_BLOCK_SIZE;
132 len = dev->max_block_size;
136 * Round to multiple of block size + ensure that
137 * the data length is a multiple of the block size
139 block->buf_len = len;
140 block->buf = get_memory(block->buf_len);
141 block->rechdr_items = 0;
143 block->BlockVer = BLOCK_VER; /* default write version */
144 Dmsg2(150, "New block len=%d block=%p\n", len, block);
150 * Duplicate an existing block (eblock)
152 DEV_BLOCK *dup_block(DEV_BLOCK *eblock)
154 DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK));
155 int buf_len = sizeof_pool_memory(eblock->buf);
157 memcpy(block, eblock, sizeof(DEV_BLOCK));
158 block->buf = get_memory(buf_len);
159 memcpy(block->buf, eblock->buf, buf_len);
165 * Only the first block checksum error was reported.
166 * If there are more, report it now.
168 void print_block_read_errors(JCR *jcr, DEV_BLOCK *block)
170 if (block->read_errors > 1) {
171 Jmsg(jcr, M_ERROR, 0, _("%d block read errors not printed.\n"),
177 void DCR::free_blocks()
187 void free_block(DEV_BLOCK *block)
190 Dmsg1(999, "free_block buffer %x\n", block->buf);
191 free_memory(block->buf);
192 Dmsg1(999, "free_block block %x\n", block);
193 free_memory((POOLMEM *)block);
197 bool is_block_empty(DEV_BLOCK *block)
199 return block->binbuf <= WRITE_BLKHDR_LENGTH;
202 /* Empty the block -- for writing */
203 void empty_block(DEV_BLOCK *block)
205 block->binbuf = WRITE_BLKHDR_LENGTH;
206 Dmsg3(200, "empty len=%d block=%p set binbuf=%d\n",
207 block->buf_len, block, block->binbuf);
208 block->bufp = block->buf + block->binbuf;
209 block->buf[0] = 0; /* clear for debugging */
210 block->bufp[0] = 0; /* clear for debugging */
212 block->write_failed = false;
213 block->block_read = false;
214 block->needs_write = false;
215 block->FirstIndex = block->LastIndex = 0;
219 * Create block header just before write. The space
220 * in the buffer should have already been reserved by
223 uint32_t ser_block_header(DEV_BLOCK *block, bool do_checksum)
226 uint32_t block_len = block->binbuf;
229 Dmsg1(160, "block_header: block_len=%d\n", block_len);
230 ser_begin(block->buf, BLKHDR2_LENGTH);
231 ser_uint32(block->CheckSum);
232 ser_uint32(block_len);
233 ser_uint32(block->BlockNumber);
234 ser_bytes(WRITE_BLKHDR_ID, BLKHDR_ID_LENGTH);
235 if (BLOCK_VER >= 2) {
236 ser_uint32(block->VolSessionId);
237 ser_uint32(block->VolSessionTime);
240 /* Checksum whole block except for the checksum */
242 block->CheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
243 block_len-BLKHDR_CS_LENGTH);
245 Dmsg1(160, "ser_block_header: checksum=%x\n", block->CheckSum);
246 ser_begin(block->buf, BLKHDR2_LENGTH);
247 ser_uint32(block->CheckSum); /* now add checksum to block header */
248 return block->CheckSum;
252 * Unserialize the block header for reading block.
253 * This includes setting all the buffer pointers correctly.
255 * Returns: false on failure (not a block)
258 bool unser_block_header(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
261 char Id[BLKHDR_ID_LENGTH+1];
262 uint32_t BlockCheckSum;
265 uint32_t BlockNumber;
268 if (block->no_header) {
271 unser_begin(block->buf, BLKHDR_LENGTH);
272 unser_uint32(block->CheckSum);
273 unser_uint32(block_len);
274 unser_uint32(BlockNumber);
275 unser_bytes(Id, BLKHDR_ID_LENGTH);
276 ASSERT(unser_length(block->buf) == BLKHDR1_LENGTH);
277 Id[BLKHDR_ID_LENGTH] = 0;
280 Dmsg3(0, "len=%d block = %s (id=%s)\n", block->block_len, hexdump(block->buf, MIN(block->block_len, 512), buf, sizeof(buf)), Id);
283 bhl = BLKHDR1_LENGTH;
285 block->bufp = block->buf + bhl;
286 //Dmsg3(100, "Block=%p buf=%p bufp=%p\n", block, block->buf, block->bufp);
287 if (strncmp(Id, BLKHDR1_ID, BLKHDR_ID_LENGTH) != 0) {
288 dev->dev_errno = EIO;
289 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
290 dev->file, dev->block_num, BLKHDR1_ID, Id);
291 if (block->read_errors == 0 || verbose >= 2) {
292 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
294 block->read_errors++;
297 } else if (Id[3] == '2') {
298 unser_uint32(block->VolSessionId);
299 unser_uint32(block->VolSessionTime);
300 bhl = BLKHDR2_LENGTH;
302 block->bufp = block->buf + bhl;
303 if (strncmp(Id, BLKHDR2_ID, BLKHDR_ID_LENGTH) != 0) {
304 dev->dev_errno = EIO;
305 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
306 dev->file, dev->block_num, BLKHDR2_ID, Id);
307 if (block->read_errors == 0 || verbose >= 2) {
308 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
310 block->read_errors++;
314 dev->dev_errno = EIO;
315 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
316 dev->file, dev->block_num, BLKHDR2_ID, Id);
317 Dmsg1(50, "%s", dev->errmsg);
318 if (block->read_errors == 0 || verbose >= 2) {
319 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
321 block->read_errors++;
322 unser_uint32(block->VolSessionId);
323 unser_uint32(block->VolSessionTime);
328 if (block_len > MAX_BLOCK_LENGTH) {
329 dev->dev_errno = EIO;
330 Mmsg3(dev->errmsg, _("Volume data error at %u:%u! Block length %u is insane (too large), probably due to a bad archive.\n"),
331 dev->file, dev->block_num, block_len);
332 if (block->read_errors == 0 || verbose >= 2) {
333 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
335 block->read_errors++;
339 Dmsg1(390, "unser_block_header block_len=%d\n", block_len);
340 /* Find end of block or end of buffer whichever is smaller */
341 if (block_len > block->read_len) {
342 block_end = block->read_len;
344 block_end = block_len;
346 block->binbuf = block_end - bhl;
347 Dmsg2(200, "set block=%p binbuf=%d\n", block, block->binbuf);
348 block->block_len = block_len;
349 block->BlockNumber = BlockNumber;
350 Dmsg3(390, "Read binbuf = %d %d block_len=%d\n", block->binbuf,
352 if (block_len <= block->read_len && dev->do_checksum()) {
353 BlockCheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
354 block_len-BLKHDR_CS_LENGTH);
355 if (BlockCheckSum != block->CheckSum) {
356 dev->dev_errno = EIO;
357 Mmsg6(dev->errmsg, _("Volume data error at %u:%u!\n"
358 "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n"),
359 dev->file, dev->block_num, (unsigned)BlockNumber,
360 block_len, BlockCheckSum, block->CheckSum);
361 if (block->read_errors == 0 || verbose >= 2) {
362 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
363 dump_block(block, "with checksum error");
365 block->read_errors++;
375 * Calculate how many bytes to write and then clear to end
378 uint32_t get_len_and_clear_block(DEV_BLOCK *block, DEVICE *dev, uint32_t &pad)
382 * Clear to the end of the buffer if it is not full,
383 * and on tape devices, apply min and fixed blocking.
385 wlen = block->binbuf;
386 if (wlen != block->buf_len) {
387 Dmsg2(250, "binbuf=%d buf_len=%d\n", block->binbuf, block->buf_len);
389 /* Adjust write size to min/max for tapes only */
390 if (dev->is_tape()) {
391 /* check for fixed block size */
392 if (dev->min_block_size == dev->max_block_size) {
393 wlen = block->buf_len; /* fixed block size already rounded */
394 /* Check for min block size */
395 } else if (wlen < dev->min_block_size) {
396 wlen = ((dev->min_block_size + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
397 /* Ensure size is rounded */
399 wlen = ((wlen + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
402 ASSERT(wlen <= block->buf_len);
403 /* Clear from end of data to end of block */
404 if (wlen-block->binbuf > 0) {
405 memset(block->bufp, 0, wlen-block->binbuf); /* clear garbage */
407 pad = wlen - block->binbuf; /* padding or zeros written */
408 Dmsg4(150, "Zero end blk: cleared=%d buf_len=%d wlen=%d binbuf=%d\n",
409 pad, block->buf_len, wlen, block->binbuf);
414 return wlen; /* bytes to write */
418 * Determine if user defined volume size has been
419 * reached, and if so, return true, otherwise
422 bool user_volume_size_reached(DCR *dcr, bool quiet)
424 bool hit_max1, hit_max2;
425 uint64_t size, max_size;
426 DEVICE *dev = dcr->dev;
431 size = dev->VolCatInfo.VolCatBytes + dcr->block->binbuf;
432 /* Limit maximum Volume size to value specified by user */
433 hit_max1 = (dev->max_volume_size > 0) && (size >= dev->max_volume_size);
434 hit_max2 = (dev->VolCatInfo.VolCatMaxBytes > 0) &&
435 (size >= dev->VolCatInfo.VolCatMaxBytes);
437 max_size = dev->max_volume_size;
439 max_size = dev->VolCatInfo.VolCatMaxBytes;
441 if (hit_max1 || hit_max2) {
443 Jmsg(dcr->jcr, M_INFO, 0, _("User defined maximum volume size %s will be exceeded on device %s.\n"
444 " Marking Volume \"%s\" as Full.\n"),
445 edit_uint64_with_commas(max_size, ed1), dev->print_name(),
446 dev->getVolCatName());
448 Dmsg4(100, "Maximum volume size %s exceeded Vol=%s device=%s.\n"
449 "Marking Volume \"%s\" as Full.\n",
450 edit_uint64_with_commas(max_size, ed1), dev->getVolCatName(),
451 dev->print_name(), dev->getVolCatName());
454 Dmsg1(dbgel, "Return from user_volume_size_reached=%d\n", rtn);
460 void reread_last_block(DCR *dcr)
462 #define CHECK_LAST_BLOCK
463 #ifdef CHECK_LAST_BLOCK
465 DEVICE *dev = dcr->dev;
467 DEV_BLOCK *block = dcr->block;
469 * If the device is a tape and it supports backspace record,
470 * we backspace over one or two eof marks depending on
471 * how many we just wrote, then over the last record,
472 * then re-read it and verify that the block number is
475 if (dev->is_tape() && dev->has_cap(CAP_BSR)) {
476 /* Now back up over what we wrote and read the last block */
480 Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"),
481 be.bstrerror(dev->dev_errno));
483 if (ok && dev->has_cap(CAP_TWOEOF) && !dev->bsf(1)) {
486 Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"),
487 be.bstrerror(dev->dev_errno));
489 /* Backspace over record */
490 if (ok && !dev->bsr(1)) {
493 Jmsg(jcr, M_ERROR, 0, _("Backspace record at EOT failed. ERR=%s\n"),
494 be.bstrerror(dev->dev_errno));
496 * On FreeBSD systems, if the user got here, it is likely that his/her
497 * tape drive is "frozen". The correct thing to do is a
498 * rewind(), but if we do that, higher levels in cleaning up, will
499 * most likely write the EOS record over the beginning of the
500 * tape. The rewind *is* done later in mount.c when another
501 * tape is requested. Note, the clrerror() call in bsr()
502 * calls ioctl(MTCERRSTAT), which *should* fix the problem.
506 DEV_BLOCK *lblock = new_block(dev);
507 /* Note, this can destroy dev->errmsg */
509 if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
510 Jmsg(jcr, M_ERROR, 0, _("Re-read last block at EOT failed. ERR=%s"),
514 * If we wrote block and the block numbers don't agree
515 * we have a possible problem.
517 if (lblock->BlockNumber != dev->LastBlock) {
518 if (dev->LastBlock > (lblock->BlockNumber + 1)) {
519 Jmsg(jcr, M_FATAL, 0, _(
520 "Re-read of last block: block numbers differ by more than one.\n"
521 "Probable tape misconfiguration and data loss. Read block=%u Want block=%u.\n"),
522 lblock->BlockNumber, dev->LastBlock);
524 Jmsg(jcr, M_ERROR, 0, _(
525 "Re-read of last block OK, but block numbers differ. Read block=%u Want block=%u.\n"),
526 lblock->BlockNumber, dev->LastBlock);
529 Jmsg(jcr, M_INFO, 0, _("Re-read of last block succeeded.\n"));
540 * If this routine is called, we do our bookkeeping and
541 * then assure that the volume will not be written any
544 bool terminate_writing_volume(DCR *dcr)
546 DEVICE *dev = dcr->dev;
551 if (dev->is_ateot()) {
552 return ok; /* already been here return now */
555 /* Create a JobMedia record to indicated end of medium */
556 dev->VolCatInfo.VolCatFiles = dev->get_file();
557 if (!dir_create_jobmedia_record(dcr)) {
558 Dmsg0(50, "Error from create JobMedia\n");
559 dev->dev_errno = EIO;
560 Mmsg2(dev->errmsg, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
561 dev->getVolCatName(), dcr->jcr->Job);
562 Jmsg(dcr->jcr, M_FATAL, 0, "%s", dev->errmsg);
565 flush_jobmedia_queue(dcr->jcr);
566 dcr->block->write_failed = true;
567 if (dev->can_append() && !dev->weof(1)) { /* end the tape */
568 dev->VolCatInfo.VolCatErrors++;
569 Jmsg(dcr->jcr, M_ERROR, 0, _("Error writing final EOF to tape. This Volume may not be readable.\n"
572 Dmsg0(50, "Error writing final EOF to volume.\n");
575 ok = write_ansi_ibm_labels(dcr, ANSI_EOV_LABEL, dev->VolHdr.VolumeName);
578 Dmsg2(100, "Set VolCatStatus Full size=%lld vol=%s\n",
579 dev->VolCatInfo.VolCatBytes, dev->VolCatInfo.VolCatName);
581 /* If still in append mode mark volume Full */
582 if (bstrcmp(dev->VolCatInfo.VolCatStatus, "Append")) {
583 dev->setVolCatStatus("Full");
586 if (!dir_update_volume_info(dcr, false, true)) {
587 Mmsg(dev->errmsg, _("Error sending Volume info to Director.\n"));
589 Dmsg0(50, "Error updating volume info.\n");
591 Dmsg2(150, "dir_update_volume_info vol=%s to terminate writing -- %s\n",
592 dev->getVolCatName(), ok?"OK":"ERROR");
594 dev->notify_newvol_in_attached_dcrs(NULL);
596 /* Set new file/block parameters for current dcr */
597 set_new_file_parameters(dcr);
599 if (ok && dev->has_cap(CAP_TWOEOF) && dev->can_append() && !dev->weof(1)) { /* end the tape */
600 dev->VolCatInfo.VolCatErrors++;
601 /* This may not be fatal since we already wrote an EOF */
602 Jmsg(dcr->jcr, M_ERROR, 0, "%s", dev->errmsg);
603 Dmsg0(50, "Writing second EOF failed.\n");
606 dev->set_ateot(); /* no more writing this tape */
607 Dmsg2(150, "Leave terminate_writing_volume=%s -- %s\n",
608 dev->getVolCatName(), ok?"OK":"ERROR");
614 * If a new volume has been mounted since our last write
615 * Create a JobMedia record for the previous volume written,
616 * and set new parameters to write this volume
617 * The same applies for if we are in a new file.
619 bool check_for_newvol_or_newfile(DCR *dcr)
623 if (dcr->NewVol || dcr->NewFile) {
624 if (job_canceled(jcr)) {
625 Dmsg0(100, "Canceled\n");
628 /* Create a jobmedia record for this job */
629 if (!dir_create_jobmedia_record(dcr)) {
630 dcr->dev->dev_errno = EIO;
631 Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
632 dcr->getVolCatName(), jcr->Job);
633 set_new_volume_parameters(dcr);
634 Dmsg0(100, "cannot create media record\n");
638 flush_jobmedia_queue(jcr);
639 /* Note, setting a new volume also handles any pending new file */
640 set_new_volume_parameters(dcr);
642 set_new_file_parameters(dcr);
649 * Do bookkeeping when a new file is created on a Volume. This is
650 * also done for disk files to generate the jobmedia records for
653 bool do_new_file_bookkeeping(DCR *dcr)
655 DEVICE *dev = dcr->dev;
658 /* Create a JobMedia record so restore can seek */
659 if (!dir_create_jobmedia_record(dcr)) {
660 Dmsg0(40, "Error from create_job_media.\n");
661 dev->dev_errno = EIO;
662 Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
663 dcr->getVolCatName(), jcr->Job);
664 Dmsg0(40, "Call terminate_writing_volume\n");
665 terminate_writing_volume(dcr);
666 dev->dev_errno = EIO;
669 dev->VolCatInfo.VolCatFiles = dev->get_file();
670 if (!dir_update_volume_info(dcr, false, false)) {
671 Dmsg0(50, "Error from update_vol_info.\n");
672 Dmsg0(40, "Call terminate_writing_volume\n");
673 terminate_writing_volume(dcr);
674 dev->dev_errno = EIO;
677 Dmsg0(100, "dir_update_volume_info max file size -- OK\n");
679 dev->notify_newfile_in_attached_dcrs();
681 /* Set new file/block parameters for current dcr */
682 set_new_file_parameters(dcr);