2 Bacula® - The Network Backup Solution
4 Copyright (C) 2001-2014 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from many
7 others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 Bacula® is a registered trademark of Kern Sibbald.
18 * block_util.c -- tape block utility functions
20 * Kern Sibbald, split from block.c March MMXII
28 static const int dbgel = 160;
30 #ifdef DEBUG_BLOCK_CHECKSUM
31 static const bool debug_block_checksum = true;
33 static const bool debug_block_checksum = false;
36 #ifdef NO_TAPE_WRITE_TEST
37 static const bool no_tape_write_test = true;
39 static const bool no_tape_write_test = false;
43 * Dump the block header, then walk through
44 * the block printing out the record headers.
46 void dump_block(DEV_BLOCK *b, const char *msg)
50 char Id[BLKHDR_ID_LENGTH+1];
51 uint32_t CheckSum, BlockCheckSum;
52 uint32_t block_len, reclen;
54 uint32_t VolSessionId, VolSessionTime, data_len;
58 char buf1[100], buf2[100];
60 if ((debug_level & ~DT_ALL) < 250) {
63 unser_begin(b->buf, BLKHDR1_LENGTH);
64 unser_uint32(CheckSum);
65 unser_uint32(block_len);
66 unser_uint32(BlockNumber);
67 unser_bytes(Id, BLKHDR_ID_LENGTH);
68 ASSERT(unser_length(b->buf) == BLKHDR1_LENGTH);
69 Id[BLKHDR_ID_LENGTH] = 0;
71 unser_uint32(VolSessionId);
72 unser_uint32(VolSessionTime);
76 VolSessionId = VolSessionTime = 0;
81 if (block_len > 4000000) {
82 Dmsg3(20, "!!!Dump block %s 0x%x blocksize too big %u\n", msg, b, block_len);
86 BlockCheckSum = bcrc32((uint8_t *)b->buf+BLKHDR_CS_LENGTH,
87 block_len-BLKHDR_CS_LENGTH);
88 Pmsg6(000, _("Dump block %s %p: size=%d BlkNum=%d\n"
89 " Hdrcksum=%x cksum=%x\n"),
90 msg, b, block_len, BlockNumber, CheckSum, BlockCheckSum);
93 unser_begin(p, WRITE_RECHDR_LENGTH);
94 if (rhl == RECHDR1_LENGTH) {
95 unser_uint32(VolSessionId);
96 unser_uint32(VolSessionTime);
98 unser_int32(FileIndex);
100 unser_uint32(data_len);
103 Pmsg6(000, _(" Rec: VId=%u VT=%u FI=%s Strm=%s len=%d reclen=%d\n"),
104 VolSessionId, VolSessionTime, FI_to_ascii(buf1, FileIndex),
105 stream_to_ascii(buf2, Stream, FileIndex), data_len, reclen);
110 * Create a new block structure.
111 * We pass device so that the block can inherit the
112 * min and max block sizes.
114 DEV_BLOCK *new_block(DEVICE *dev)
116 DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK));
119 memset(block, 0, sizeof(DEV_BLOCK));
121 /* If the user has specified a max_block_size, use it as the default */
122 if (dev->max_block_size == 0) {
123 len = DEFAULT_BLOCK_SIZE;
125 len = dev->max_block_size;
129 * Round to multiple of block size + ensure that
130 * the data length is a multiple of the block size
132 block->buf_len = len;
133 block->buf = get_memory(block->buf_len);
134 block->rechdr_queue = get_memory(block->buf_len);
135 block->rechdr_items = 0;
137 block->BlockVer = BLOCK_VER; /* default write version */
138 Dmsg2(150, "New block len=%d block=%p\n", len, block);
144 * Duplicate an existing block (eblock)
146 DEV_BLOCK *dup_block(DEV_BLOCK *eblock)
148 DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK));
149 int buf_len = sizeof_pool_memory(eblock->buf);
151 memcpy(block, eblock, sizeof(DEV_BLOCK));
152 block->buf = get_memory(buf_len);
153 memcpy(block->buf, eblock->buf, buf_len);
159 * Only the first block checksum error was reported.
160 * If there are more, report it now.
162 void print_block_read_errors(JCR *jcr, DEV_BLOCK *block)
164 if (block->read_errors > 1) {
165 Jmsg(jcr, M_ERROR, 0, _("%d block read errors not printed.\n"),
171 void DCR::free_blocks()
181 void free_block(DEV_BLOCK *block)
184 Dmsg1(999, "free_block buffer %x\n", block->buf);
185 free_memory(block->buf);
186 free_memory(block->rechdr_queue);
187 Dmsg1(999, "free_block block %x\n", block);
188 free_memory((POOLMEM *)block);
192 bool is_block_empty(DEV_BLOCK *block)
194 return block->binbuf <= WRITE_BLKHDR_LENGTH;
197 /* Empty the block -- for writing */
198 void empty_block(DEV_BLOCK *block)
200 block->binbuf = WRITE_BLKHDR_LENGTH;
201 Dmsg3(200, "empty len=%d block=%p set binbuf=%d\n",
202 block->buf_len, block, block->binbuf);
203 block->bufp = block->buf + block->binbuf;
204 block->buf[0] = 0; /* clear for debugging */
205 block->bufp[0] = 0; /* clear for debugging */
207 block->write_failed = false;
208 block->block_read = false;
209 block->needs_write = false;
210 block->FirstIndex = block->LastIndex = 0;
214 * Create block header just before write. The space
215 * in the buffer should have already been reserved by
218 uint32_t ser_block_header(DEV_BLOCK *block, bool do_checksum)
221 uint32_t block_len = block->binbuf;
224 Dmsg1(160, "block_header: block_len=%d\n", block_len);
225 ser_begin(block->buf, BLKHDR2_LENGTH);
226 ser_uint32(block->CheckSum);
227 ser_uint32(block_len);
228 ser_uint32(block->BlockNumber);
229 ser_bytes(WRITE_BLKHDR_ID, BLKHDR_ID_LENGTH);
230 if (BLOCK_VER >= 2) {
231 ser_uint32(block->VolSessionId);
232 ser_uint32(block->VolSessionTime);
235 /* Checksum whole block except for the checksum */
237 block->CheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
238 block_len-BLKHDR_CS_LENGTH);
240 Dmsg1(160, "ser_block_header: checksum=%x\n", block->CheckSum);
241 ser_begin(block->buf, BLKHDR2_LENGTH);
242 ser_uint32(block->CheckSum); /* now add checksum to block header */
243 return block->CheckSum;
247 * Unserialize the block header for reading block.
248 * This includes setting all the buffer pointers correctly.
250 * Returns: false on failure (not a block)
253 bool unser_block_header(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
256 char Id[BLKHDR_ID_LENGTH+1];
257 uint32_t BlockCheckSum;
260 uint32_t BlockNumber;
263 if (block->no_header) {
266 unser_begin(block->buf, BLKHDR_LENGTH);
267 unser_uint32(block->CheckSum);
268 unser_uint32(block_len);
269 unser_uint32(BlockNumber);
270 unser_bytes(Id, BLKHDR_ID_LENGTH);
271 ASSERT(unser_length(block->buf) == BLKHDR1_LENGTH);
273 Id[BLKHDR_ID_LENGTH] = 0;
275 bhl = BLKHDR1_LENGTH;
277 block->bufp = block->buf + bhl;
278 //Dmsg3(100, "Block=%p buf=%p bufp=%p\n", block, block->buf, block->bufp);
279 if (strncmp(Id, BLKHDR1_ID, BLKHDR_ID_LENGTH) != 0) {
280 dev->dev_errno = EIO;
281 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
282 dev->file, dev->block_num, BLKHDR1_ID, Id);
283 if (block->read_errors == 0 || verbose >= 2) {
284 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
286 block->read_errors++;
289 } else if (Id[3] == '2') {
290 unser_uint32(block->VolSessionId);
291 unser_uint32(block->VolSessionTime);
292 bhl = BLKHDR2_LENGTH;
294 block->bufp = block->buf + bhl;
295 if (strncmp(Id, BLKHDR2_ID, BLKHDR_ID_LENGTH) != 0) {
296 dev->dev_errno = EIO;
297 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
298 dev->file, dev->block_num, BLKHDR2_ID, Id);
299 if (block->read_errors == 0 || verbose >= 2) {
300 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
302 block->read_errors++;
306 dev->dev_errno = EIO;
307 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
308 dev->file, dev->block_num, BLKHDR2_ID, Id);
309 Dmsg1(50, "%s", dev->errmsg);
310 if (block->read_errors == 0 || verbose >= 2) {
311 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
313 block->read_errors++;
314 unser_uint32(block->VolSessionId);
315 unser_uint32(block->VolSessionTime);
320 if (block_len > MAX_BLOCK_LENGTH) {
321 dev->dev_errno = EIO;
322 Mmsg3(dev->errmsg, _("Volume data error at %u:%u! Block length %u is insane (too large), probably due to a bad archive.\n"),
323 dev->file, dev->block_num, block_len);
324 if (block->read_errors == 0 || verbose >= 2) {
325 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
327 block->read_errors++;
331 Dmsg1(390, "unser_block_header block_len=%d\n", block_len);
332 /* Find end of block or end of buffer whichever is smaller */
333 if (block_len > block->read_len) {
334 block_end = block->read_len;
336 block_end = block_len;
338 block->binbuf = block_end - bhl;
339 Dmsg2(200, "set block=%p binbuf=%d\n", block, block->binbuf);
340 block->block_len = block_len;
341 block->BlockNumber = BlockNumber;
342 Dmsg3(390, "Read binbuf = %d %d block_len=%d\n", block->binbuf,
344 if (block_len <= block->read_len && dev->do_checksum()) {
345 BlockCheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
346 block_len-BLKHDR_CS_LENGTH);
347 if (BlockCheckSum != block->CheckSum) {
348 dev->dev_errno = EIO;
349 Mmsg6(dev->errmsg, _("Volume data error at %u:%u!\n"
350 "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n"),
351 dev->file, dev->block_num, (unsigned)BlockNumber,
352 block_len, BlockCheckSum, block->CheckSum);
353 if (block->read_errors == 0 || verbose >= 2) {
354 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
355 dump_block(block, "with checksum error");
357 block->read_errors++;
367 * Calculate how many bytes to write and then clear to end
370 uint32_t get_len_and_clear_block(DEV_BLOCK *block, DEVICE *dev, uint32_t &pad)
374 * Clear to the end of the buffer if it is not full,
375 * and on tape devices, apply min and fixed blocking.
377 wlen = block->binbuf;
378 if (wlen != block->buf_len) {
379 Dmsg2(250, "binbuf=%d buf_len=%d\n", block->binbuf, block->buf_len);
381 /* Adjust write size to min/max for tapes only */
382 if (dev->is_tape()) {
383 /* check for fixed block size */
384 if (dev->min_block_size == dev->max_block_size) {
385 wlen = block->buf_len; /* fixed block size already rounded */
386 /* Check for min block size */
387 } else if (wlen < dev->min_block_size) {
388 wlen = ((dev->min_block_size + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
389 /* Ensure size is rounded */
391 wlen = ((wlen + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
394 ASSERT(wlen <= block->buf_len);
395 /* Clear from end of data to end of block */
396 if (wlen-block->binbuf > 0) {
397 memset(block->bufp, 0, wlen-block->binbuf); /* clear garbage */
399 pad = wlen - block->binbuf; /* padding or zeros written */
400 Dmsg4(150, "Zero end blk: cleared=%d buf_len=%d wlen=%d binbuf=%d\n",
401 pad, block->buf_len, wlen, block->binbuf);
406 return wlen; /* bytes to write */
410 * Determine if user defined volume size has been
411 * reached, and if so, return true, otherwise
414 bool user_volume_size_reached(DCR *dcr, bool quiet)
416 bool hit_max1, hit_max2;
417 uint64_t size, max_size;
418 DEVICE *dev = dcr->dev;
423 size = dev->VolCatInfo.VolCatBytes + dcr->block->binbuf;
424 /* Limit maximum Volume size to value specified by user */
425 hit_max1 = (dev->max_volume_size > 0) && (size >= dev->max_volume_size);
426 hit_max2 = (dev->VolCatInfo.VolCatMaxBytes > 0) &&
427 (size >= dev->VolCatInfo.VolCatMaxBytes);
429 max_size = dev->max_volume_size;
431 max_size = dev->VolCatInfo.VolCatMaxBytes;
433 if (hit_max1 || hit_max2) {
435 Jmsg(dcr->jcr, M_INFO, 0, _("User defined maximum volume size %s will be exceeded on device %s.\n"
436 " Marking Volume \"%s\" as Full.\n"),
437 edit_uint64_with_commas(max_size, ed1), dev->print_name(),
438 dev->getVolCatName());
440 Dmsg4(100, "Maximum volume size %s exceeded Vol=%s device=%s.\n"
441 "Marking Volume \"%s\" as Full.\n",
442 edit_uint64_with_commas(max_size, ed1), dev->getVolCatName(),
443 dev->print_name(), dev->getVolCatName());
446 Dmsg1(dbgel, "Return from user_volume_size_reached=%d\n", rtn);
452 void reread_last_block(DCR *dcr)
454 #define CHECK_LAST_BLOCK
455 #ifdef CHECK_LAST_BLOCK
457 DEVICE *dev = dcr->dev;
459 DEV_BLOCK *block = dcr->block;
461 * If the device is a tape and it supports backspace record,
462 * we backspace over one or two eof marks depending on
463 * how many we just wrote, then over the last record,
464 * then re-read it and verify that the block number is
467 if (dev->is_tape() && dev->has_cap(CAP_BSR)) {
468 /* Now back up over what we wrote and read the last block */
472 Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"),
473 be.bstrerror(dev->dev_errno));
475 if (ok && dev->has_cap(CAP_TWOEOF) && !dev->bsf(1)) {
478 Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"),
479 be.bstrerror(dev->dev_errno));
481 /* Backspace over record */
482 if (ok && !dev->bsr(1)) {
485 Jmsg(jcr, M_ERROR, 0, _("Backspace record at EOT failed. ERR=%s\n"),
486 be.bstrerror(dev->dev_errno));
488 * On FreeBSD systems, if the user got here, it is likely that his/her
489 * tape drive is "frozen". The correct thing to do is a
490 * rewind(), but if we do that, higher levels in cleaning up, will
491 * most likely write the EOS record over the beginning of the
492 * tape. The rewind *is* done later in mount.c when another
493 * tape is requested. Note, the clrerror() call in bsr()
494 * calls ioctl(MTCERRSTAT), which *should* fix the problem.
498 DEV_BLOCK *lblock = new_block(dev);
499 /* Note, this can destroy dev->errmsg */
501 if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
502 Jmsg(jcr, M_ERROR, 0, _("Re-read last block at EOT failed. ERR=%s"),
506 * If we wrote block and the block numbers don't agree
507 * we have a possible problem.
509 if (lblock->BlockNumber != dev->LastBlock) {
510 if (dev->LastBlock > (lblock->BlockNumber + 1)) {
511 Jmsg(jcr, M_FATAL, 0, _(
512 "Re-read of last block: block numbers differ by more than one.\n"
513 "Probable tape misconfiguration and data loss. Read block=%u Want block=%u.\n"),
514 lblock->BlockNumber, dev->LastBlock);
516 Jmsg(jcr, M_ERROR, 0, _(
517 "Re-read of last block OK, but block numbers differ. Read block=%u Want block=%u.\n"),
518 lblock->BlockNumber, dev->LastBlock);
521 Jmsg(jcr, M_INFO, 0, _("Re-read of last block succeeded.\n"));
532 * If this routine is called, we do our bookkeeping and
533 * then assure that the volume will not be written any
536 bool terminate_writing_volume(DCR *dcr)
538 DEVICE *dev = dcr->dev;
543 if (dev->is_ateot()) {
544 return ok; /* already been here return now */
547 /* Create a JobMedia record to indicated end of medium */
548 dev->VolCatInfo.VolCatFiles = dev->get_file();
549 if (!dir_create_jobmedia_record(dcr)) {
550 Dmsg0(50, "Error from create JobMedia\n");
551 dev->dev_errno = EIO;
552 Mmsg2(dev->errmsg, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
553 dev->getVolCatName(), dcr->jcr->Job);
554 Jmsg(dcr->jcr, M_FATAL, 0, "%s", dev->errmsg);
557 dcr->block->write_failed = true;
558 if (dev->can_append() && !dev->weof(1)) { /* end the tape */
559 dev->VolCatInfo.VolCatErrors++;
560 Jmsg(dcr->jcr, M_ERROR, 0, _("Error writing final EOF to tape. This Volume may not be readable.\n"
563 Dmsg0(50, "Error writing final EOF to volume.\n");
566 ok = write_ansi_ibm_labels(dcr, ANSI_EOV_LABEL, dev->VolHdr.VolumeName);
569 Dmsg2(100, "Set VolCatStatus Full size=%lld vol=%s\n",
570 dev->VolCatInfo.VolCatBytes, dev->VolCatInfo.VolCatName);
572 /* If still in append mode mark volume Full */
573 if (bstrcmp(dev->VolCatInfo.VolCatStatus, "Append")) {
574 dev->setVolCatStatus("Full");
577 if (!dir_update_volume_info(dcr, false, true)) {
578 Mmsg(dev->errmsg, _("Error sending Volume info to Director.\n"));
580 Dmsg0(50, "Error updating volume info.\n");
582 Dmsg2(150, "dir_update_volume_info vol=%s to terminate writing -- %s\n",
583 dev->getVolCatName(), ok?"OK":"ERROR");
585 dev->notify_newvol_in_attached_dcrs(NULL);
587 /* Set new file/block parameters for current dcr */
588 set_new_file_parameters(dcr);
590 if (ok && dev->has_cap(CAP_TWOEOF) && dev->can_append() && !dev->weof(1)) { /* end the tape */
591 dev->VolCatInfo.VolCatErrors++;
592 /* This may not be fatal since we already wrote an EOF */
593 Jmsg(dcr->jcr, M_ERROR, 0, "%s", dev->errmsg);
594 Dmsg0(50, "Writing second EOF failed.\n");
597 dev->set_ateot(); /* no more writing this tape */
598 Dmsg2(150, "Leave terminate_writing_volume=%s -- %s\n",
599 dev->getVolCatName(), ok?"OK":"ERROR");
605 * If a new volume has been mounted since our last write
606 * Create a JobMedia record for the previous volume written,
607 * and set new parameters to write this volume
608 * The same applies for if we are in a new file.
610 bool check_for_newvol_or_newfile(DCR *dcr)
614 if (dcr->NewVol || dcr->NewFile) {
615 if (job_canceled(jcr)) {
616 Dmsg0(100, "Canceled\n");
619 /* Create a jobmedia record for this job */
620 if (!dir_create_jobmedia_record(dcr)) {
621 dcr->dev->dev_errno = EIO;
622 Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
623 dcr->getVolCatName(), jcr->Job);
624 set_new_volume_parameters(dcr);
625 Dmsg0(100, "cannot create media record\n");
629 /* Note, setting a new volume also handles any pending new file */
630 set_new_volume_parameters(dcr);
632 set_new_file_parameters(dcr);
639 * Do bookkeeping when a new file is created on a Volume. This is
640 * also done for disk files to generate the jobmedia records for
643 bool do_new_file_bookkeeping(DCR *dcr)
645 DEVICE *dev = dcr->dev;
648 /* Create a JobMedia record so restore can seek */
649 if (!dir_create_jobmedia_record(dcr)) {
650 Dmsg0(40, "Error from create_job_media.\n");
651 dev->dev_errno = EIO;
652 Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
653 dcr->getVolCatName(), jcr->Job);
654 Dmsg0(40, "Call terminate_writing_volume\n");
655 terminate_writing_volume(dcr);
656 dev->dev_errno = EIO;
659 dev->VolCatInfo.VolCatFiles = dev->get_file();
660 if (!dir_update_volume_info(dcr, false, false)) {
661 Dmsg0(50, "Error from update_vol_info.\n");
662 Dmsg0(40, "Call terminate_writing_volume\n");
663 terminate_writing_volume(dcr);
664 dev->dev_errno = EIO;
667 Dmsg0(100, "dir_update_volume_info max file size -- OK\n");
669 dev->notify_newfile_in_attached_dcrs();
671 /* Set new file/block parameters for current dcr */
672 set_new_file_parameters(dcr);