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) {
86 Dmsg3(20, "!!!Dump block %s 0x%x blocksize too big %u\n", msg, b, block_len);
90 BlockCheckSum = bcrc32((uint8_t *)b->buf+BLKHDR_CS_LENGTH,
91 block_len-BLKHDR_CS_LENGTH);
92 Pmsg6(000, _("Dump block %s %p: size=%d BlkNum=%d\n"
93 " Hdrcksum=%x cksum=%x\n"),
94 msg, b, block_len, BlockNumber, CheckSum, BlockCheckSum);
97 unser_begin(p, WRITE_RECHDR_LENGTH);
98 if (rhl == RECHDR1_LENGTH) {
99 unser_uint32(VolSessionId);
100 unser_uint32(VolSessionTime);
102 unser_int32(FileIndex);
104 unser_uint32(data_len);
107 Pmsg6(000, _(" Rec: VId=%u VT=%u FI=%s Strm=%s len=%d reclen=%d\n"),
108 VolSessionId, VolSessionTime, FI_to_ascii(buf1, FileIndex),
109 stream_to_ascii(buf2, Stream, FileIndex), data_len, reclen);
114 * Create a new block structure.
115 * We pass device so that the block can inherit the
116 * min and max block sizes.
118 DEV_BLOCK *new_block(DEVICE *dev)
120 DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK));
123 memset(block, 0, sizeof(DEV_BLOCK));
125 /* If the user has specified a max_block_size, use it as the default */
126 if (dev->max_block_size == 0) {
127 len = DEFAULT_BLOCK_SIZE;
129 len = dev->max_block_size;
133 * Round to multiple of block size + ensure that
134 * the data length is a multiple of the block size
136 block->buf_len = len;
137 block->buf = get_memory(block->buf_len);
138 block->rechdr_items = 0;
140 block->BlockVer = BLOCK_VER; /* default write version */
141 Dmsg2(150, "New block len=%d block=%p\n", len, block);
147 * Duplicate an existing block (eblock)
149 DEV_BLOCK *dup_block(DEV_BLOCK *eblock)
151 DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK));
152 int buf_len = sizeof_pool_memory(eblock->buf);
154 memcpy(block, eblock, sizeof(DEV_BLOCK));
155 block->buf = get_memory(buf_len);
156 memcpy(block->buf, eblock->buf, buf_len);
162 * Only the first block checksum error was reported.
163 * If there are more, report it now.
165 void print_block_read_errors(JCR *jcr, DEV_BLOCK *block)
167 if (block->read_errors > 1) {
168 Jmsg(jcr, M_ERROR, 0, _("%d block read errors not printed.\n"),
174 void DCR::free_blocks()
184 void free_block(DEV_BLOCK *block)
187 Dmsg1(999, "free_block buffer %x\n", block->buf);
188 free_memory(block->buf);
189 Dmsg1(999, "free_block block %x\n", block);
190 free_memory((POOLMEM *)block);
194 bool is_block_empty(DEV_BLOCK *block)
196 return block->binbuf <= WRITE_BLKHDR_LENGTH;
199 /* Empty the block -- for writing */
200 void empty_block(DEV_BLOCK *block)
202 block->binbuf = WRITE_BLKHDR_LENGTH;
203 Dmsg3(200, "empty len=%d block=%p set binbuf=%d\n",
204 block->buf_len, block, block->binbuf);
205 block->bufp = block->buf + block->binbuf;
206 block->buf[0] = 0; /* clear for debugging */
207 block->bufp[0] = 0; /* clear for debugging */
209 block->write_failed = false;
210 block->block_read = false;
211 block->needs_write = false;
212 block->FirstIndex = block->LastIndex = 0;
216 * Create block header just before write. The space
217 * in the buffer should have already been reserved by
220 uint32_t ser_block_header(DEV_BLOCK *block, bool do_checksum)
223 uint32_t block_len = block->binbuf;
226 Dmsg1(160, "block_header: block_len=%d\n", block_len);
227 ser_begin(block->buf, BLKHDR2_LENGTH);
228 ser_uint32(block->CheckSum);
229 ser_uint32(block_len);
230 ser_uint32(block->BlockNumber);
231 ser_bytes(WRITE_BLKHDR_ID, BLKHDR_ID_LENGTH);
232 if (BLOCK_VER >= 2) {
233 ser_uint32(block->VolSessionId);
234 ser_uint32(block->VolSessionTime);
237 /* Checksum whole block except for the checksum */
239 block->CheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
240 block_len-BLKHDR_CS_LENGTH);
242 Dmsg1(160, "ser_block_header: checksum=%x\n", block->CheckSum);
243 ser_begin(block->buf, BLKHDR2_LENGTH);
244 ser_uint32(block->CheckSum); /* now add checksum to block header */
245 return block->CheckSum;
249 * Unserialize the block header for reading block.
250 * This includes setting all the buffer pointers correctly.
252 * Returns: false on failure (not a block)
255 bool unser_block_header(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
258 char Id[BLKHDR_ID_LENGTH+1];
259 uint32_t BlockCheckSum;
262 uint32_t BlockNumber;
265 if (block->no_header) {
268 unser_begin(block->buf, BLKHDR_LENGTH);
269 unser_uint32(block->CheckSum);
270 unser_uint32(block_len);
271 unser_uint32(BlockNumber);
272 unser_bytes(Id, BLKHDR_ID_LENGTH);
273 ASSERT(unser_length(block->buf) == BLKHDR1_LENGTH);
275 Id[BLKHDR_ID_LENGTH] = 0;
277 bhl = BLKHDR1_LENGTH;
279 block->bufp = block->buf + bhl;
280 //Dmsg3(100, "Block=%p buf=%p bufp=%p\n", block, block->buf, block->bufp);
281 if (strncmp(Id, BLKHDR1_ID, BLKHDR_ID_LENGTH) != 0) {
282 dev->dev_errno = EIO;
283 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
284 dev->file, dev->block_num, BLKHDR1_ID, Id);
285 if (block->read_errors == 0 || verbose >= 2) {
286 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
288 block->read_errors++;
291 } else if (Id[3] == '2') {
292 unser_uint32(block->VolSessionId);
293 unser_uint32(block->VolSessionTime);
294 bhl = BLKHDR2_LENGTH;
296 block->bufp = block->buf + bhl;
297 if (strncmp(Id, BLKHDR2_ID, BLKHDR_ID_LENGTH) != 0) {
298 dev->dev_errno = EIO;
299 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
300 dev->file, dev->block_num, BLKHDR2_ID, Id);
301 if (block->read_errors == 0 || verbose >= 2) {
302 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
304 block->read_errors++;
308 dev->dev_errno = EIO;
309 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
310 dev->file, dev->block_num, BLKHDR2_ID, Id);
311 Dmsg1(50, "%s", dev->errmsg);
312 if (block->read_errors == 0 || verbose >= 2) {
313 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
315 block->read_errors++;
316 unser_uint32(block->VolSessionId);
317 unser_uint32(block->VolSessionTime);
322 if (block_len > MAX_BLOCK_LENGTH) {
323 dev->dev_errno = EIO;
324 Mmsg3(dev->errmsg, _("Volume data error at %u:%u! Block length %u is insane (too large), probably due to a bad archive.\n"),
325 dev->file, dev->block_num, block_len);
326 if (block->read_errors == 0 || verbose >= 2) {
327 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
329 block->read_errors++;
333 Dmsg1(390, "unser_block_header block_len=%d\n", block_len);
334 /* Find end of block or end of buffer whichever is smaller */
335 if (block_len > block->read_len) {
336 block_end = block->read_len;
338 block_end = block_len;
340 block->binbuf = block_end - bhl;
341 Dmsg2(200, "set block=%p binbuf=%d\n", block, block->binbuf);
342 block->block_len = block_len;
343 block->BlockNumber = BlockNumber;
344 Dmsg3(390, "Read binbuf = %d %d block_len=%d\n", block->binbuf,
346 if (block_len <= block->read_len && dev->do_checksum()) {
347 BlockCheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
348 block_len-BLKHDR_CS_LENGTH);
349 if (BlockCheckSum != block->CheckSum) {
350 dev->dev_errno = EIO;
351 Mmsg6(dev->errmsg, _("Volume data error at %u:%u!\n"
352 "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n"),
353 dev->file, dev->block_num, (unsigned)BlockNumber,
354 block_len, BlockCheckSum, block->CheckSum);
355 if (block->read_errors == 0 || verbose >= 2) {
356 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
357 dump_block(block, "with checksum error");
359 block->read_errors++;
369 * Calculate how many bytes to write and then clear to end
372 uint32_t get_len_and_clear_block(DEV_BLOCK *block, DEVICE *dev, uint32_t &pad)
376 * Clear to the end of the buffer if it is not full,
377 * and on tape devices, apply min and fixed blocking.
379 wlen = block->binbuf;
380 if (wlen != block->buf_len) {
381 Dmsg2(250, "binbuf=%d buf_len=%d\n", block->binbuf, block->buf_len);
383 /* Adjust write size to min/max for tapes only */
384 if (dev->is_tape()) {
385 /* check for fixed block size */
386 if (dev->min_block_size == dev->max_block_size) {
387 wlen = block->buf_len; /* fixed block size already rounded */
388 /* Check for min block size */
389 } else if (wlen < dev->min_block_size) {
390 wlen = ((dev->min_block_size + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
391 /* Ensure size is rounded */
393 wlen = ((wlen + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
396 ASSERT(wlen <= block->buf_len);
397 /* Clear from end of data to end of block */
398 if (wlen-block->binbuf > 0) {
399 memset(block->bufp, 0, wlen-block->binbuf); /* clear garbage */
401 pad = wlen - block->binbuf; /* padding or zeros written */
402 Dmsg4(150, "Zero end blk: cleared=%d buf_len=%d wlen=%d binbuf=%d\n",
403 pad, block->buf_len, wlen, block->binbuf);
408 return wlen; /* bytes to write */
412 * Determine if user defined volume size has been
413 * reached, and if so, return true, otherwise
416 bool user_volume_size_reached(DCR *dcr, bool quiet)
418 bool hit_max1, hit_max2;
419 uint64_t size, max_size;
420 DEVICE *dev = dcr->dev;
425 size = dev->VolCatInfo.VolCatBytes + dcr->block->binbuf;
426 /* Limit maximum Volume size to value specified by user */
427 hit_max1 = (dev->max_volume_size > 0) && (size >= dev->max_volume_size);
428 hit_max2 = (dev->VolCatInfo.VolCatMaxBytes > 0) &&
429 (size >= dev->VolCatInfo.VolCatMaxBytes);
431 max_size = dev->max_volume_size;
433 max_size = dev->VolCatInfo.VolCatMaxBytes;
435 if (hit_max1 || hit_max2) {
437 Jmsg(dcr->jcr, M_INFO, 0, _("User defined maximum volume size %s will be exceeded on device %s.\n"
438 " Marking Volume \"%s\" as Full.\n"),
439 edit_uint64_with_commas(max_size, ed1), dev->print_name(),
440 dev->getVolCatName());
442 Dmsg4(100, "Maximum volume size %s exceeded Vol=%s device=%s.\n"
443 "Marking Volume \"%s\" as Full.\n",
444 edit_uint64_with_commas(max_size, ed1), dev->getVolCatName(),
445 dev->print_name(), dev->getVolCatName());
448 Dmsg1(dbgel, "Return from user_volume_size_reached=%d\n", rtn);
454 void reread_last_block(DCR *dcr)
456 #define CHECK_LAST_BLOCK
457 #ifdef CHECK_LAST_BLOCK
459 DEVICE *dev = dcr->dev;
461 DEV_BLOCK *block = dcr->block;
463 * If the device is a tape and it supports backspace record,
464 * we backspace over one or two eof marks depending on
465 * how many we just wrote, then over the last record,
466 * then re-read it and verify that the block number is
469 if (dev->is_tape() && dev->has_cap(CAP_BSR)) {
470 /* Now back up over what we wrote and read the last block */
474 Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"),
475 be.bstrerror(dev->dev_errno));
477 if (ok && dev->has_cap(CAP_TWOEOF) && !dev->bsf(1)) {
480 Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"),
481 be.bstrerror(dev->dev_errno));
483 /* Backspace over record */
484 if (ok && !dev->bsr(1)) {
487 Jmsg(jcr, M_ERROR, 0, _("Backspace record at EOT failed. ERR=%s\n"),
488 be.bstrerror(dev->dev_errno));
490 * On FreeBSD systems, if the user got here, it is likely that his/her
491 * tape drive is "frozen". The correct thing to do is a
492 * rewind(), but if we do that, higher levels in cleaning up, will
493 * most likely write the EOS record over the beginning of the
494 * tape. The rewind *is* done later in mount.c when another
495 * tape is requested. Note, the clrerror() call in bsr()
496 * calls ioctl(MTCERRSTAT), which *should* fix the problem.
500 DEV_BLOCK *lblock = new_block(dev);
501 /* Note, this can destroy dev->errmsg */
503 if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
504 Jmsg(jcr, M_ERROR, 0, _("Re-read last block at EOT failed. ERR=%s"),
508 * If we wrote block and the block numbers don't agree
509 * we have a possible problem.
511 if (lblock->BlockNumber != dev->LastBlock) {
512 if (dev->LastBlock > (lblock->BlockNumber + 1)) {
513 Jmsg(jcr, M_FATAL, 0, _(
514 "Re-read of last block: block numbers differ by more than one.\n"
515 "Probable tape misconfiguration and data loss. Read block=%u Want block=%u.\n"),
516 lblock->BlockNumber, dev->LastBlock);
518 Jmsg(jcr, M_ERROR, 0, _(
519 "Re-read of last block OK, but block numbers differ. Read block=%u Want block=%u.\n"),
520 lblock->BlockNumber, dev->LastBlock);
523 Jmsg(jcr, M_INFO, 0, _("Re-read of last block succeeded.\n"));
534 * If this routine is called, we do our bookkeeping and
535 * then assure that the volume will not be written any
538 bool terminate_writing_volume(DCR *dcr)
540 DEVICE *dev = dcr->dev;
545 if (dev->is_ateot()) {
546 return ok; /* already been here return now */
549 /* Create a JobMedia record to indicated end of medium */
550 dev->VolCatInfo.VolCatFiles = dev->get_file();
551 if (!dir_create_jobmedia_record(dcr)) {
552 Dmsg0(50, "Error from create JobMedia\n");
553 dev->dev_errno = EIO;
554 Mmsg2(dev->errmsg, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
555 dev->getVolCatName(), dcr->jcr->Job);
556 Jmsg(dcr->jcr, M_FATAL, 0, "%s", dev->errmsg);
559 flush_jobmedia_queue(dcr->jcr);
560 dcr->block->write_failed = true;
561 if (dev->can_append() && !dev->weof(1)) { /* end the tape */
562 dev->VolCatInfo.VolCatErrors++;
563 Jmsg(dcr->jcr, M_ERROR, 0, _("Error writing final EOF to tape. This Volume may not be readable.\n"
566 Dmsg0(50, "Error writing final EOF to volume.\n");
569 ok = write_ansi_ibm_labels(dcr, ANSI_EOV_LABEL, dev->VolHdr.VolumeName);
572 Dmsg2(100, "Set VolCatStatus Full size=%lld vol=%s\n",
573 dev->VolCatInfo.VolCatBytes, dev->VolCatInfo.VolCatName);
575 /* If still in append mode mark volume Full */
576 if (bstrcmp(dev->VolCatInfo.VolCatStatus, "Append")) {
577 dev->setVolCatStatus("Full");
580 if (!dir_update_volume_info(dcr, false, true)) {
581 Mmsg(dev->errmsg, _("Error sending Volume info to Director.\n"));
583 Dmsg0(50, "Error updating volume info.\n");
585 Dmsg2(150, "dir_update_volume_info vol=%s to terminate writing -- %s\n",
586 dev->getVolCatName(), ok?"OK":"ERROR");
588 dev->notify_newvol_in_attached_dcrs(NULL);
590 /* Set new file/block parameters for current dcr */
591 set_new_file_parameters(dcr);
593 if (ok && dev->has_cap(CAP_TWOEOF) && dev->can_append() && !dev->weof(1)) { /* end the tape */
594 dev->VolCatInfo.VolCatErrors++;
595 /* This may not be fatal since we already wrote an EOF */
596 Jmsg(dcr->jcr, M_ERROR, 0, "%s", dev->errmsg);
597 Dmsg0(50, "Writing second EOF failed.\n");
600 dev->set_ateot(); /* no more writing this tape */
601 Dmsg2(150, "Leave terminate_writing_volume=%s -- %s\n",
602 dev->getVolCatName(), ok?"OK":"ERROR");
608 * If a new volume has been mounted since our last write
609 * Create a JobMedia record for the previous volume written,
610 * and set new parameters to write this volume
611 * The same applies for if we are in a new file.
613 bool check_for_newvol_or_newfile(DCR *dcr)
617 if (dcr->NewVol || dcr->NewFile) {
618 if (job_canceled(jcr)) {
619 Dmsg0(100, "Canceled\n");
622 /* Create a jobmedia record for this job */
623 if (!dir_create_jobmedia_record(dcr)) {
624 dcr->dev->dev_errno = EIO;
625 Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
626 dcr->getVolCatName(), jcr->Job);
627 set_new_volume_parameters(dcr);
628 Dmsg0(100, "cannot create media record\n");
632 flush_jobmedia_queue(jcr);
633 /* Note, setting a new volume also handles any pending new file */
634 set_new_volume_parameters(dcr);
636 set_new_file_parameters(dcr);
643 * Do bookkeeping when a new file is created on a Volume. This is
644 * also done for disk files to generate the jobmedia records for
647 bool do_new_file_bookkeeping(DCR *dcr)
649 DEVICE *dev = dcr->dev;
652 /* Create a JobMedia record so restore can seek */
653 if (!dir_create_jobmedia_record(dcr)) {
654 Dmsg0(40, "Error from create_job_media.\n");
655 dev->dev_errno = EIO;
656 Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
657 dcr->getVolCatName(), jcr->Job);
658 Dmsg0(40, "Call terminate_writing_volume\n");
659 terminate_writing_volume(dcr);
660 dev->dev_errno = EIO;
663 dev->VolCatInfo.VolCatFiles = dev->get_file();
664 if (!dir_update_volume_info(dcr, false, false)) {
665 Dmsg0(50, "Error from update_vol_info.\n");
666 Dmsg0(40, "Call terminate_writing_volume\n");
667 terminate_writing_volume(dcr);
668 dev->dev_errno = EIO;
671 Dmsg0(100, "dir_update_volume_info max file size -- OK\n");
673 dev->notify_newfile_in_attached_dcrs();
675 /* Set new file/block parameters for current dcr */
676 set_new_file_parameters(dcr);