2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2017 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many 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 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
21 * block_util.c -- tape block utility functions
23 * Kern Sibbald, split from block.c March MMXII
30 static const int dbglvl = 160;
32 #ifdef DEBUG_BLOCK_CHECKSUM
33 static const bool debug_block_checksum = true;
35 static const bool debug_block_checksum = false;
38 #ifdef NO_TAPE_WRITE_TEST
39 static const bool no_tape_write_test = true;
41 static const bool no_tape_write_test = false;
45 * Dump the block header, then walk through
46 * the block printing out the record headers.
48 void dump_block(DEVICE *dev, DEV_BLOCK *b, const char *msg, bool force)
53 char Id[BLKHDR_ID_LENGTH+1];
54 uint32_t CheckSum, BlockCheckSum;
55 uint32_t block_len, reclen;
57 uint32_t VolSessionId, VolSessionTime, data_len;
61 char buf1[100], buf2[100];
63 if (!force && ((debug_level & ~DT_ALL) < 250)) {
67 Dmsg0(20, "Dump block: adata=1 cannot dump.\n");
72 if (dev->can_read()) {
73 bufp = b->buf + b->block_len;
76 unser_begin(b->buf, BLKHDR1_LENGTH);
77 unser_uint32(CheckSum);
78 unser_uint32(block_len);
79 unser_uint32(BlockNumber);
80 unser_bytes(Id, BLKHDR_ID_LENGTH);
81 ASSERT(unser_length(b->buf) == BLKHDR1_LENGTH);
82 Id[BLKHDR_ID_LENGTH] = 0;
84 unser_uint32(VolSessionId);
85 unser_uint32(VolSessionTime);
89 VolSessionId = VolSessionTime = 0;
94 if (block_len > 4000000 || block_len < BLKHDR_CS_LENGTH) {
95 Dmsg3(20, "Will not dump blocksize too %s %lu msg: %s\n",
96 (block_len < BLKHDR_CS_LENGTH)?"small":"big",
101 BlockCheckSum = bcrc32((uint8_t *)b->buf+BLKHDR_CS_LENGTH,
102 block_len-BLKHDR_CS_LENGTH);
103 Pmsg7(000, _("Dump block %s %p: adata=%d size=%d BlkNum=%d\n"
104 " Hdrcksum=%x cksum=%x\n"),
105 msg, b, b->adata, block_len, BlockNumber, CheckSum, BlockCheckSum);
108 unser_begin(p, WRITE_RECHDR_LENGTH);
109 if (rhl == RECHDR1_LENGTH) {
110 unser_uint32(VolSessionId);
111 unser_uint32(VolSessionTime);
113 unser_int32(FileIndex);
115 unser_uint32(data_len);
116 if (Stream == STREAM_ADATA_BLOCK_HEADER) {
118 p += WRITE_ADATA_BLKHDR_LENGTH;
119 } else if (Stream == STREAM_ADATA_RECORD_HEADER ||
120 Stream == -STREAM_ADATA_RECORD_HEADER) {
121 unser_uint32(reclen);
123 p += WRITE_ADATA_RECHDR_LENGTH;
128 Pmsg6(000, _(" Rec: VId=%u VT=%u FI=%s Strm=%s len=%d reclen=%d\n"),
129 VolSessionId, VolSessionTime, FI_to_ascii(buf1, FileIndex),
130 stream_to_ascii(buf2, Stream, FileIndex), data_len, reclen);
135 * Create a new block structure.
136 * We pass device so that the block can inherit the
137 * min and max block sizes.
139 void DEVICE::new_dcr_blocks(DCR *dcr)
141 dcr->block = dcr->ameta_block = new_block(dcr);
144 DEV_BLOCK *DEVICE::new_block(DCR *dcr, int size)
146 DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK));
149 memset(block, 0, sizeof(DEV_BLOCK));
151 /* If the user has specified a max_block_size, use it as the default */
152 if (max_block_size == 0) {
153 len = DEFAULT_BLOCK_SIZE;
155 len = max_block_size;
162 block->buf_len = len;
163 block->buf = get_memory(block->buf_len);
164 block->rechdr_queue = get_memory(block->buf_len);
165 block->rechdr_items = 0;
166 Dmsg2(510, "Rechdr len=%d max_items=%d\n", sizeof_pool_memory(block->rechdr_queue),
167 sizeof_pool_memory(block->rechdr_queue)/WRITE_ADATA_RECHDR_LENGTH);
169 block->BlockVer = BLOCK_VER; /* default write version */
170 Dmsg3(150, "New block adata=%d len=%d block=%p\n", block->adata, len, block);
176 * Duplicate an existing block (eblock)
178 DEV_BLOCK *dup_block(DEV_BLOCK *eblock)
180 DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK));
181 int buf_len = sizeof_pool_memory(eblock->buf);
182 int rechdr_len = sizeof_pool_memory(eblock->rechdr_queue);
184 memcpy(block, eblock, sizeof(DEV_BLOCK));
185 block->buf = get_memory(buf_len);
186 memcpy(block->buf, eblock->buf, buf_len);
188 block->rechdr_queue = get_memory(rechdr_len);
189 memcpy(block->rechdr_queue, eblock->rechdr_queue, rechdr_len);
191 /* bufp might point inside buf */
193 eblock->bufp >= eblock->buf &&
194 eblock->bufp < (eblock->buf + buf_len))
196 block->bufp = (eblock->bufp - eblock->buf) + block->buf;
205 * Flush block to disk
207 bool DEVICE::flush_block(DCR *dcr)
209 if (!is_block_empty(dcr->block)) {
210 Dmsg0(dbglvl, "=== wpath 53 flush_ameta\n");
211 Dmsg4(190, "Call flush_ameta_block BlockAddr=%lld nbytes=%d adata=%d block=%x\n",
212 dcr->block->BlockAddr, dcr->block->binbuf, dcr->adata_block->adata, dcr->adata_block);
213 dump_block(dcr->dev, dcr->block, "Flush_ameta_block");
214 if (dcr->jcr->is_canceled() || !dcr->write_block_to_device()) {
215 Dmsg0(dbglvl, "=== wpath 54 flush_ameta\n");
216 Dmsg0(190, "Failed to write ameta block to device, return false.\n");
219 empty_block(dcr->block);
226 * Only the first block checksum error was reported.
227 * If there are more, report it now.
229 void print_block_read_errors(JCR *jcr, DEV_BLOCK *block)
231 if (block->read_errors > 1) {
232 Jmsg(jcr, M_ERROR, 0, _("%d block read errors not printed.\n"),
237 /* We had a problem on some solaris platforms with the CRC32 library, some
238 * 8.4.x jobs uses a bad crc32 algorithm. We just try one then the
239 * other to not create false problems
241 uint32_t DCR::crc32(unsigned char *buf, int len, uint32_t expected_crc)
243 #if defined(HAVE_SUN_OS) && defined(HAVE_LITTLE_ENDIAN)
246 crc = bcrc32_bad(buf, len);
249 crc = bcrc32(buf, len);
251 if (expected_crc != crc) {
252 crc32_type = !crc32_type; /* Next time, do it well right away */
255 crc = bcrc32_bad(buf, len);
258 crc = bcrc32(buf, len);
263 return bcrc32(buf, len);
267 void DEVICE::free_dcr_blocks(DCR *dcr)
269 if (dcr->block == dcr->ameta_block) {
270 dcr->ameta_block = NULL; /* do not free twice */
272 free_block(dcr->block);
274 free_block(dcr->ameta_block);
275 dcr->ameta_block = NULL;
281 void free_block(DEV_BLOCK *block)
284 Dmsg1(999, "free_block block=%p\n", block);
286 free_memory(block->buf);
288 if (block->rechdr_queue) {
289 free_memory(block->rechdr_queue);
291 Dmsg1(999, "=== free_block block %p\n", block);
292 free_memory((POOLMEM *)block);
296 bool is_block_empty(DEV_BLOCK *block)
299 Dmsg1(200, "=== adata=1 binbuf=%d\n", block->binbuf);
300 return block->binbuf <= 0;
302 Dmsg1(200, "=== adata=0 binbuf=%d\n", block->binbuf-WRITE_BLKHDR_LENGTH);
303 return block->binbuf <= WRITE_BLKHDR_LENGTH;
307 /* Empty the block -- for writing */
308 void empty_block(DEV_BLOCK *block)
313 block->binbuf = WRITE_BLKHDR_LENGTH;
315 Dmsg3(250, "empty_block: adata=%d len=%d set binbuf=%d\n",
316 block->adata, block->buf_len, block->binbuf);
317 block->bufp = block->buf + block->binbuf;
319 block->write_failed = false;
320 block->block_read = false;
321 block->needs_write = false;
322 block->FirstIndex = block->LastIndex = 0;
324 block->BlockAddr = 0;
328 * Create block header just before write. The space
329 * in the buffer should have already been reserved by
332 uint32_t ser_block_header(DEV_BLOCK *block, bool do_checksum)
335 uint32_t block_len = block->binbuf;
339 /* Checksum whole block */
341 block->CheckSum = bcrc32((uint8_t *)block->buf, block_len);
344 Dmsg1(160, "block_header: block_len=%d\n", block_len);
345 ser_begin(block->buf, BLKHDR2_LENGTH);
346 ser_uint32(block->CheckSum);
347 ser_uint32(block_len);
348 ser_uint32(block->BlockNumber);
349 ser_bytes(WRITE_BLKHDR_ID, BLKHDR_ID_LENGTH);
350 if (BLOCK_VER >= 2) {
351 ser_uint32(block->VolSessionId);
352 ser_uint32(block->VolSessionTime);
355 /* Checksum whole block except for the checksum */
357 block->CheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
358 block_len-BLKHDR_CS_LENGTH);
360 Dmsg2(160, "ser_block_header: adata=%d checksum=%x\n", block->adata, block->CheckSum);
361 ser_begin(block->buf, BLKHDR2_LENGTH);
362 ser_uint32(block->CheckSum); /* now add checksum to block header */
364 return block->CheckSum;
368 * Unserialize the block header for reading block.
369 * This includes setting all the buffer pointers correctly.
371 * Returns: false on failure (not a block)
374 bool unser_block_header(DCR *dcr, DEVICE *dev, DEV_BLOCK *block)
377 char Id[BLKHDR_ID_LENGTH+1];
378 uint32_t BlockCheckSum;
381 uint32_t BlockNumber;
386 /* Checksum the whole block */
387 if (block->block_len <= block->read_len && dev->do_checksum()) {
388 BlockCheckSum = dcr->crc32((uint8_t *)block->buf, block->block_len, block->CheckSum);
389 if (BlockCheckSum != block->CheckSum) {
390 dev->dev_errno = EIO;
391 Mmsg5(dev->errmsg, _("Volume data error at %lld!\n"
392 "Adata block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n"),
393 block->BlockAddr, block->BlockNumber,
394 block->block_len, BlockCheckSum, block->CheckSum);
395 if (block->read_errors == 0 || verbose >= 2) {
396 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
397 dump_block(dev, block, "with checksum error");
399 block->read_errors++;
408 if (block->no_header) {
411 unser_begin(block->buf, BLKHDR_LENGTH);
412 unser_uint32(block->CheckSum);
413 unser_uint32(block_len);
414 unser_uint32(BlockNumber);
415 unser_bytes(Id, BLKHDR_ID_LENGTH);
416 ASSERT(unser_length(block->buf) == BLKHDR1_LENGTH);
417 Id[BLKHDR_ID_LENGTH] = 0;
420 bhl = BLKHDR1_LENGTH;
422 block->bufp = block->buf + bhl;
423 //Dmsg3(100, "Block=%p buf=%p bufp=%p\n", block, block->buf, block->bufp);
424 if (strncmp(Id, BLKHDR1_ID, BLKHDR_ID_LENGTH) != 0) {
425 dev->dev_errno = EIO;
426 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
427 dev->file, dev->block_num, BLKHDR1_ID, Id);
428 if (block->read_errors == 0 || verbose >= 2) {
429 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
431 block->read_errors++;
434 } else if (Id[3] == '2') {
435 unser_uint32(block->VolSessionId);
436 unser_uint32(block->VolSessionTime);
437 bhl = BLKHDR2_LENGTH;
439 block->bufp = block->buf + bhl;
440 //Dmsg5(100, "Read-blkhdr Block=%p adata=%d buf=%p bufp=%p off=%d\n", block, block->adata,
441 // block->buf, block->bufp, block->bufp-block->buf);
442 if (strncmp(Id, BLKHDR2_ID, BLKHDR_ID_LENGTH) != 0) {
443 dev->dev_errno = EIO;
444 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
445 dev->file, dev->block_num, BLKHDR2_ID, Id);
446 if (block->read_errors == 0 || verbose >= 2) {
447 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
449 block->read_errors++;
453 dev->dev_errno = EIO;
454 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
455 dev->file, dev->block_num, BLKHDR2_ID, Id);
456 Dmsg1(50, "%s", dev->errmsg);
457 if (block->read_errors == 0 || verbose >= 2) {
458 Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg);
460 block->read_errors++;
461 unser_uint32(block->VolSessionId);
462 unser_uint32(block->VolSessionTime);
467 if (block_len > MAX_BLOCK_LENGTH) {
468 dev->dev_errno = EIO;
469 Mmsg3(dev->errmsg, _("Volume data error at %u:%u! Block length %u is insane (too large), probably due to a bad archive.\n"),
470 dev->file, dev->block_num, block_len);
471 if (block->read_errors == 0 || verbose >= 2) {
472 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
474 block->read_errors++;
478 Dmsg1(390, "unser_block_header block_len=%d\n", block_len);
479 /* Find end of block or end of buffer whichever is smaller */
480 if (block_len > block->read_len) {
481 block_end = block->read_len;
483 block_end = block_len;
485 block->binbuf = block_end - bhl;
486 Dmsg3(200, "set block=%p adata=%d binbuf=%d\n", block, block->adata, block->binbuf);
487 block->block_len = block_len;
488 block->BlockNumber = BlockNumber;
489 Dmsg3(390, "Read binbuf = %d %d block_len=%d\n", block->binbuf,
491 if (block_len <= block->read_len && dev->do_checksum()) {
492 BlockCheckSum = dcr->crc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
493 block_len-BLKHDR_CS_LENGTH,
496 if (BlockCheckSum != block->CheckSum) {
497 dev->dev_errno = EIO;
498 Mmsg6(dev->errmsg, _("Volume data error at %u:%u!\n"
499 "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n"),
500 dev->file, dev->block_num, (unsigned)BlockNumber,
501 block_len, BlockCheckSum, block->CheckSum);
502 if (block->read_errors == 0 || verbose >= 2) {
503 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
504 dump_block(dev, block, "with checksum error");
506 block->read_errors++;
516 * Calculate how many bytes to write and then clear to end
519 uint32_t get_len_and_clear_block(DEV_BLOCK *block, DEVICE *dev, uint32_t &pad)
523 * Clear to the end of the buffer if it is not full,
524 * and on tape devices, apply min and fixed blocking.
526 wlen = block->binbuf;
527 if (wlen != block->buf_len) {
528 Dmsg2(250, "binbuf=%d buf_len=%d\n", block->binbuf, block->buf_len);
530 /* Adjust write size to min/max for tapes and aligned only */
531 if (dev->is_tape() || block->adata) {
532 /* check for fixed block size */
533 if (dev->min_block_size == dev->max_block_size) {
534 wlen = block->buf_len; /* fixed block size already rounded */
535 /* Check for min block size */
536 } else if (wlen < dev->min_block_size) {
537 wlen = ((dev->min_block_size + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
538 /* Ensure size is rounded */
540 wlen = ((wlen + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
543 if (block->adata && dev->padding_size > 0) {
544 /* Write to next aligned boundry */
545 wlen = ((wlen + dev->padding_size - 1) / dev->padding_size) * dev->padding_size;
547 ASSERT(wlen <= block->buf_len);
548 /* Clear from end of data to end of block */
549 if (wlen-block->binbuf > 0) {
550 memset(block->bufp, 0, wlen-block->binbuf); /* clear garbage */
552 pad = wlen - block->binbuf; /* padding or zeros written */
553 Dmsg5(150, "Zero end blk: adata=%d cleared=%d buf_len=%d wlen=%d binbuf=%d\n",
554 block->adata, pad, block->buf_len, wlen, block->binbuf);
559 return wlen; /* bytes to write */
563 * Determine if user defined volume size has been
564 * reached, and if so, return true, otherwise
567 bool is_user_volume_size_reached(DCR *dcr, bool quiet)
569 bool hit_max1, hit_max2;
570 uint64_t size, max_size;
571 DEVICE *dev = dcr->ameta_dev;
576 if (dev->is_aligned()) {
577 /* Note, we reserve space for one ameta and one adata block */
578 size = dev->VolCatInfo.VolCatBytes + dcr->ameta_block->buf_len +
579 dcr->adata_block->buf_len;
581 size = dev->VolCatInfo.VolCatBytes + dcr->ameta_block->binbuf;
583 /* Limit maximum Volume size to value specified by user */
584 hit_max1 = (dev->max_volume_size > 0) && (size >= dev->max_volume_size);
585 hit_max2 = (dev->VolCatInfo.VolCatMaxBytes > 0) &&
586 (size >= dev->VolCatInfo.VolCatMaxBytes);
588 max_size = dev->max_volume_size;
590 max_size = dev->VolCatInfo.VolCatMaxBytes;
592 if (hit_max1 || hit_max2) {
594 Jmsg(dcr->jcr, M_INFO, 0, _("User defined maximum volume size %s will be exceeded on device %s.\n"
595 " Marking Volume \"%s\" as Full.\n"),
596 edit_uint64_with_commas(max_size, ed1), dev->print_name(),
597 dev->getVolCatName());
599 Dmsg4(100, "Maximum volume size %s exceeded Vol=%s device=%s.\n"
600 "Marking Volume \"%s\" as Full.\n",
601 edit_uint64_with_commas(max_size, ed1), dev->getVolCatName(),
602 dev->print_name(), dev->getVolCatName());
605 Dmsg1(dbglvl, "Return from is_user_volume_size_reached=%d\n", rtn);
611 void reread_last_block(DCR *dcr)
613 #define CHECK_LAST_BLOCK
614 #ifdef CHECK_LAST_BLOCK
616 DEVICE *dev = dcr->dev;
618 DEV_BLOCK *ameta_block = dcr->ameta_block;
619 DEV_BLOCK *adata_block = dcr->adata_block;
620 DEV_BLOCK *block = dcr->block;
622 * If the device is a tape and it supports backspace record,
623 * we backspace over one or two eof marks depending on
624 * how many we just wrote, then over the last record,
625 * then re-read it and verify that the block number is
628 if (dev->is_tape() && dev->has_cap(CAP_BSR)) {
629 /* Now back up over what we wrote and read the last block */
633 Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"),
634 be.bstrerror(dev->dev_errno));
636 if (ok && dev->has_cap(CAP_TWOEOF) && !dev->bsf(1)) {
639 Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"),
640 be.bstrerror(dev->dev_errno));
642 /* Backspace over record */
643 if (ok && !dev->bsr(1)) {
646 Jmsg(jcr, M_ERROR, 0, _("Backspace record at EOT failed. ERR=%s\n"),
647 be.bstrerror(dev->dev_errno));
649 * On FreeBSD systems, if the user got here, it is likely that his/her
650 * tape drive is "frozen". The correct thing to do is a
651 * rewind(), but if we do that, higher levels in cleaning up, will
652 * most likely write the EOS record over the beginning of the
653 * tape. The rewind *is* done later in mount.c when another
654 * tape is requested. Note, the clrerror() call in bsr()
655 * calls ioctl(MTCERRSTAT), which *should* fix the problem.
659 dev->new_dcr_blocks(dcr);
660 /* Note, this can destroy dev->errmsg */
661 if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
662 Jmsg(jcr, M_ERROR, 0, _("Re-read last block at EOT failed. ERR=%s"),
666 * If we wrote block and the block numbers don't agree
667 * we have a possible problem.
669 if (dcr->block->BlockNumber != dev->LastBlock) {
670 if (dev->LastBlock > (dcr->block->BlockNumber + 1)) {
671 Jmsg(jcr, M_FATAL, 0, _(
672 "Re-read of last block: block numbers differ by more than one.\n"
673 "Probable tape misconfiguration and data loss. Read block=%u Want block=%u.\n"),
674 dcr->block->BlockNumber, dev->LastBlock);
676 Jmsg(jcr, M_ERROR, 0, _(
677 "Re-read of last block OK, but block numbers differ. Read block=%u Want block=%u.\n"),
678 dcr->block->BlockNumber, dev->LastBlock);
681 Jmsg(jcr, M_INFO, 0, _("Re-read of last block succeeded.\n"));
684 dev->free_dcr_blocks(dcr);
685 dcr->ameta_block = ameta_block;
687 dcr->adata_block = adata_block;
694 * If this routine is called, we do our bookkeeping and
695 * then assure that the volume will not be written any
698 bool terminate_writing_volume(DCR *dcr)
700 DEVICE *dev = dcr->dev;
702 bool was_adata = false;
706 if (dev->is_ateot()) {
707 return ok; /* already been here return now */
710 /* Work with ameta device */
712 dev->set_ateot(); /* no more writing this Volume */
713 dcr->adata_block->write_failed = true;
715 dev = dcr->ameta_dev;
719 /* Create a JobMedia record to indicated end of medium */
720 dev->VolCatInfo.VolCatFiles = dev->get_file();
721 dev->VolCatInfo.VolLastPartBytes = dev->part_size;
722 dev->VolCatInfo.VolCatParts = dev->part;
723 if (!dir_create_jobmedia_record(dcr)) {
724 Dmsg0(50, "Error from create JobMedia\n");
725 dev->dev_errno = EIO;
726 Mmsg2(dev->errmsg, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
727 dev->getVolCatName(), dcr->jcr->Job);
728 Jmsg(dcr->jcr, M_FATAL, 0, "%s", dev->errmsg);
731 flush_jobmedia_queue(dcr->jcr);
732 bstrncpy(dev->LoadedVolName, dev->VolCatInfo.VolCatName, sizeof(dev->LoadedVolName));
733 dcr->block->write_failed = true;
734 if (dev->can_append() && !dev->weof(dcr, 1)) { /* end the tape */
735 dev->VolCatInfo.VolCatErrors++;
736 Jmsg(dcr->jcr, M_ERROR, 0, _("Error writing final EOF to tape. Volume %s may not be readable.\n"
737 "%s"), dev->VolCatInfo.VolCatName, dev->errmsg);
739 Dmsg0(50, "Error writing final EOF to volume.\n");
742 ok = dev->end_of_volume(dcr);
745 Dmsg3(100, "Set VolCatStatus Full adata=%d size=%lld vol=%s\n", dev->adata,
746 dev->VolCatInfo.VolCatBytes, dev->VolCatInfo.VolCatName);
748 /* If still in append mode mark volume Full */
749 if (bstrcmp(dev->VolCatInfo.VolCatStatus, "Append")) {
750 dev->setVolCatStatus("Full");
753 if (!dir_update_volume_info(dcr, false, true)) {
754 Mmsg(dev->errmsg, _("Error sending Volume info to Director.\n"));
756 Dmsg0(50, "Error updating volume info.\n");
758 Dmsg2(150, "dir_update_volume_info vol=%s to terminate writing -- %s\n",
759 dev->getVolCatName(), ok?"OK":"ERROR");
761 dev->notify_newvol_in_attached_dcrs(NULL);
763 /* Set new file/block parameters for current dcr */
764 set_new_file_parameters(dcr);
766 if (ok && dev->has_cap(CAP_TWOEOF) && dev->can_append() && !dev->weof(dcr, 1)) { /* end the tape */
767 dev->VolCatInfo.VolCatErrors++;
768 /* This may not be fatal since we already wrote an EOF */
769 if (dev->errmsg[0]) {
770 Jmsg(dcr->jcr, M_ERROR, 0, "%s", dev->errmsg);
772 Dmsg0(50, "Writing second EOF failed.\n");
775 dev->set_ateot(); /* no more writing this tape */
776 Dmsg2(150, "Leave terminate_writing_volume=%s -- %s\n",
777 dev->getVolCatName(), ok?"OK":"ERROR");
786 * If a new volume has been mounted since our last write
787 * Create a JobMedia record for the previous volume written,
788 * and set new parameters to write this volume
789 * The same applies for if we are in a new file.
791 bool check_for_newvol_or_newfile(DCR *dcr)
795 if (dcr->NewVol || dcr->NewFile) {
796 if (job_canceled(jcr)) {
797 Dmsg0(100, "Canceled\n");
800 /* If we wrote on Volume create a last jobmedia record for this job */
801 if (!dcr->VolFirstIndex) {
802 Dmsg7(100, "Skip JobMedia Vol=%s wrote=%d MediaId=%lld FI=%lu LI=%lu StartAddr=%lld EndAddr=%lld\n",
803 dcr->VolumeName, dcr->WroteVol, dcr->VolMediaId,
804 dcr->VolFirstIndex, dcr->VolLastIndex, dcr->StartAddr, dcr->EndAddr);
806 if (dcr->VolFirstIndex && !dir_create_jobmedia_record(dcr)) {
807 dcr->dev->dev_errno = EIO;
808 Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
809 dcr->getVolCatName(), jcr->Job);
810 set_new_volume_parameters(dcr);
811 Dmsg0(100, "cannot create media record\n");
815 Dmsg0(250, "Process NewVol\n");
816 flush_jobmedia_queue(jcr);
817 /* Note, setting a new volume also handles any pending new file */
818 set_new_volume_parameters(dcr);
820 set_new_file_parameters(dcr);
827 * Do bookkeeping when a new file is created on a Volume. This is
828 * also done for disk files to generate the jobmedia records for
831 bool do_new_file_bookkeeping(DCR *dcr)
833 DEVICE *dev = dcr->dev;
836 /* Create a JobMedia record so restore can seek */
837 if (!dir_create_jobmedia_record(dcr)) {
838 Dmsg0(40, "Error from create_job_media.\n");
839 dev->dev_errno = EIO;
840 Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
841 dcr->getVolCatName(), jcr->Job);
842 Dmsg0(40, "Call terminate_writing_volume\n");
843 terminate_writing_volume(dcr);
844 dev->dev_errno = EIO;
847 dev->VolCatInfo.VolCatFiles = dev->get_file();
848 dev->VolCatInfo.VolLastPartBytes = dev->part_size;
849 dev->VolCatInfo.VolCatParts = dev->part;
850 if (!dir_update_volume_info(dcr, false, false)) {
851 Dmsg0(50, "Error from update_vol_info.\n");
852 Dmsg0(40, "Call terminate_writing_volume\n");
853 terminate_writing_volume(dcr);
854 dev->dev_errno = EIO;
857 Dmsg0(100, "dir_update_volume_info max file size -- OK\n");
859 dev->notify_newfile_in_attached_dcrs();
861 /* Set new file/block parameters for current dcr */
862 set_new_file_parameters(dcr);