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 void DEVICE::free_dcr_blocks(DCR *dcr)
239 if (dcr->block == dcr->ameta_block) {
240 dcr->ameta_block = NULL; /* do not free twice */
242 free_block(dcr->block);
244 free_block(dcr->ameta_block);
245 dcr->ameta_block = NULL;
251 void free_block(DEV_BLOCK *block)
254 Dmsg1(999, "free_block buffer=%p\n", block->buf);
256 free_memory(block->buf);
258 if (block->rechdr_queue) {
259 free_memory(block->rechdr_queue);
261 Dmsg1(999, "=== free_block block %p\n", block);
262 free_memory((POOLMEM *)block);
266 bool is_block_empty(DEV_BLOCK *block)
269 Dmsg1(200, "=== adata=1 binbuf=%d\n", block->binbuf);
270 return block->binbuf <= 0;
272 Dmsg1(200, "=== adata=0 binbuf=%d\n", block->binbuf-WRITE_BLKHDR_LENGTH);
273 return block->binbuf <= WRITE_BLKHDR_LENGTH;
277 /* Empty the block -- for writing */
278 void empty_block(DEV_BLOCK *block)
283 block->binbuf = WRITE_BLKHDR_LENGTH;
285 Dmsg3(250, "empty_block: adata=%d len=%d set binbuf=%d\n",
286 block->adata, block->buf_len, block->binbuf);
287 block->bufp = block->buf + block->binbuf;
289 block->write_failed = false;
290 block->block_read = false;
291 block->needs_write = false;
292 block->FirstIndex = block->LastIndex = 0;
294 block->BlockAddr = 0;
298 * Create block header just before write. The space
299 * in the buffer should have already been reserved by
302 uint32_t ser_block_header(DEV_BLOCK *block, bool do_checksum)
305 uint32_t block_len = block->binbuf;
309 /* Checksum whole block */
311 block->CheckSum = bcrc32((uint8_t *)block->buf, block_len);
314 Dmsg1(160, "block_header: block_len=%d\n", block_len);
315 ser_begin(block->buf, BLKHDR2_LENGTH);
316 ser_uint32(block->CheckSum);
317 ser_uint32(block_len);
318 ser_uint32(block->BlockNumber);
319 ser_bytes(WRITE_BLKHDR_ID, BLKHDR_ID_LENGTH);
320 if (BLOCK_VER >= 2) {
321 ser_uint32(block->VolSessionId);
322 ser_uint32(block->VolSessionTime);
325 /* Checksum whole block except for the checksum */
327 block->CheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
328 block_len-BLKHDR_CS_LENGTH);
330 Dmsg2(160, "ser_block_header: adata=%d checksum=%x\n", block->adata, block->CheckSum);
331 ser_begin(block->buf, BLKHDR2_LENGTH);
332 ser_uint32(block->CheckSum); /* now add checksum to block header */
334 return block->CheckSum;
338 * Unserialize the block header for reading block.
339 * This includes setting all the buffer pointers correctly.
341 * Returns: false on failure (not a block)
344 bool unser_block_header(DCR *dcr, DEVICE *dev, DEV_BLOCK *block)
347 char Id[BLKHDR_ID_LENGTH+1];
348 uint32_t BlockCheckSum;
351 uint32_t BlockNumber;
356 /* Checksum the whole block */
357 if (block->block_len <= block->read_len && dev->do_checksum()) {
358 BlockCheckSum = bcrc32((uint8_t *)block->buf, block->block_len);
359 if (BlockCheckSum != block->CheckSum) {
360 dev->dev_errno = EIO;
361 Mmsg5(dev->errmsg, _("Volume data error at %lld!\n"
362 "Adata block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n"),
363 block->BlockAddr, block->BlockNumber,
364 block->block_len, BlockCheckSum, block->CheckSum);
365 if (block->read_errors == 0 || verbose >= 2) {
366 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
367 dump_block(dev, block, "with checksum error");
369 block->read_errors++;
378 if (block->no_header) {
381 unser_begin(block->buf, BLKHDR_LENGTH);
382 unser_uint32(block->CheckSum);
383 unser_uint32(block_len);
384 unser_uint32(BlockNumber);
385 unser_bytes(Id, BLKHDR_ID_LENGTH);
386 ASSERT(unser_length(block->buf) == BLKHDR1_LENGTH);
387 Id[BLKHDR_ID_LENGTH] = 0;
390 bhl = BLKHDR1_LENGTH;
392 block->bufp = block->buf + bhl;
393 //Dmsg3(100, "Block=%p buf=%p bufp=%p\n", block, block->buf, block->bufp);
394 if (strncmp(Id, BLKHDR1_ID, BLKHDR_ID_LENGTH) != 0) {
395 dev->dev_errno = EIO;
396 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
397 dev->file, dev->block_num, BLKHDR1_ID, Id);
398 if (block->read_errors == 0 || verbose >= 2) {
399 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
401 block->read_errors++;
404 } else if (Id[3] == '2') {
405 unser_uint32(block->VolSessionId);
406 unser_uint32(block->VolSessionTime);
407 bhl = BLKHDR2_LENGTH;
409 block->bufp = block->buf + bhl;
410 //Dmsg5(100, "Read-blkhdr Block=%p adata=%d buf=%p bufp=%p off=%d\n", block, block->adata,
411 // block->buf, block->bufp, block->bufp-block->buf);
412 if (strncmp(Id, BLKHDR2_ID, BLKHDR_ID_LENGTH) != 0) {
413 dev->dev_errno = EIO;
414 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
415 dev->file, dev->block_num, BLKHDR2_ID, Id);
416 if (block->read_errors == 0 || verbose >= 2) {
417 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
419 block->read_errors++;
423 dev->dev_errno = EIO;
424 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
425 dev->file, dev->block_num, BLKHDR2_ID, Id);
426 Dmsg1(50, "%s", dev->errmsg);
427 if (block->read_errors == 0 || verbose >= 2) {
428 Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg);
430 block->read_errors++;
431 unser_uint32(block->VolSessionId);
432 unser_uint32(block->VolSessionTime);
437 if (block_len > MAX_BLOCK_SIZE) {
438 dev->dev_errno = EIO;
439 Mmsg3(dev->errmsg, _("Volume data error at %u:%u! Block length %u is insane (too large), probably due to a bad archive.\n"),
440 dev->file, dev->block_num, block_len);
441 if (block->read_errors == 0 || verbose >= 2) {
442 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
444 block->read_errors++;
448 Dmsg1(390, "unser_block_header block_len=%d\n", block_len);
449 /* Find end of block or end of buffer whichever is smaller */
450 if (block_len > block->read_len) {
451 block_end = block->read_len;
453 block_end = block_len;
455 block->binbuf = block_end - bhl;
456 Dmsg3(200, "set block=%p adata=%d binbuf=%d\n", block, block->adata, block->binbuf);
457 block->block_len = block_len;
458 block->BlockNumber = BlockNumber;
459 Dmsg3(390, "Read binbuf = %d %d block_len=%d\n", block->binbuf,
461 if (block_len <= block->read_len && dev->do_checksum()) {
462 BlockCheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
463 block_len-BLKHDR_CS_LENGTH);
465 if (BlockCheckSum != block->CheckSum) {
466 dev->dev_errno = EIO;
467 Mmsg6(dev->errmsg, _("Volume data error at %u:%u!\n"
468 "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n"),
469 dev->file, dev->block_num, (unsigned)BlockNumber,
470 block_len, BlockCheckSum, block->CheckSum);
471 if (block->read_errors == 0 || verbose >= 2) {
472 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
473 dump_block(dev, block, "with checksum error");
475 block->read_errors++;
485 * Calculate how many bytes to write and then clear to end
488 uint32_t get_len_and_clear_block(DEV_BLOCK *block, DEVICE *dev, uint32_t &pad)
492 * Clear to the end of the buffer if it is not full,
493 * and on tape devices, apply min and fixed blocking.
495 wlen = block->binbuf;
496 if (wlen != block->buf_len) {
497 Dmsg2(250, "binbuf=%d buf_len=%d\n", block->binbuf, block->buf_len);
499 /* Adjust write size to min/max for tapes and aligned only */
500 if (dev->is_tape() || block->adata) {
501 /* check for fixed block size */
502 if (dev->min_block_size == dev->max_block_size) {
503 wlen = block->buf_len; /* fixed block size already rounded */
504 /* Check for min block size */
505 } else if (wlen < dev->min_block_size) {
506 wlen = ((dev->min_block_size + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
507 /* Ensure size is rounded */
509 wlen = ((wlen + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
512 if (block->adata && dev->padding_size > 0) {
513 /* Write to next aligned boundry */
514 wlen = ((wlen + dev->padding_size - 1) / dev->padding_size) * dev->padding_size;
516 ASSERT(wlen <= block->buf_len);
517 /* Clear from end of data to end of block */
518 if (wlen-block->binbuf > 0) {
519 memset(block->bufp, 0, wlen-block->binbuf); /* clear garbage */
521 pad = wlen - block->binbuf; /* padding or zeros written */
522 Dmsg5(150, "Zero end blk: adata=%d cleared=%d buf_len=%d wlen=%d binbuf=%d\n",
523 block->adata, pad, block->buf_len, wlen, block->binbuf);
528 return wlen; /* bytes to write */
532 * Determine if user defined volume size has been
533 * reached, and if so, return true, otherwise
536 bool is_user_volume_size_reached(DCR *dcr, bool quiet)
538 bool hit_max1, hit_max2;
539 uint64_t size, max_size;
540 DEVICE *dev = dcr->ameta_dev;
545 if (dev->is_aligned()) {
546 /* Note, we reserve space for one ameta and one adata block */
547 size = dev->VolCatInfo.VolCatBytes + dcr->ameta_block->buf_len +
548 dcr->adata_block->buf_len;
550 size = dev->VolCatInfo.VolCatBytes + dcr->ameta_block->binbuf;
552 /* Limit maximum Volume size to value specified by user */
553 hit_max1 = (dev->max_volume_size > 0) && (size >= dev->max_volume_size);
554 hit_max2 = (dev->VolCatInfo.VolCatMaxBytes > 0) &&
555 (size >= dev->VolCatInfo.VolCatMaxBytes);
557 max_size = dev->max_volume_size;
559 max_size = dev->VolCatInfo.VolCatMaxBytes;
561 if (hit_max1 || hit_max2) {
563 Jmsg(dcr->jcr, M_INFO, 0, _("User defined maximum volume size %s will be exceeded on device %s.\n"
564 " Marking Volume \"%s\" as Full.\n"),
565 edit_uint64_with_commas(max_size, ed1), dev->print_name(),
566 dev->getVolCatName());
568 Dmsg4(100, "Maximum volume size %s exceeded Vol=%s device=%s.\n"
569 "Marking Volume \"%s\" as Full.\n",
570 edit_uint64_with_commas(max_size, ed1), dev->getVolCatName(),
571 dev->print_name(), dev->getVolCatName());
574 Dmsg1(dbglvl, "Return from is_user_volume_size_reached=%d\n", rtn);
580 void reread_last_block(DCR *dcr)
582 #define CHECK_LAST_BLOCK
583 #ifdef CHECK_LAST_BLOCK
585 DEVICE *dev = dcr->dev;
587 DEV_BLOCK *ameta_block = dcr->ameta_block;
588 DEV_BLOCK *adata_block = dcr->adata_block;
589 DEV_BLOCK *block = dcr->block;
591 * If the device is a tape and it supports backspace record,
592 * we backspace over one or two eof marks depending on
593 * how many we just wrote, then over the last record,
594 * then re-read it and verify that the block number is
597 if (dev->is_tape() && dev->has_cap(CAP_BSR)) {
598 /* Now back up over what we wrote and read the last block */
602 Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"),
603 be.bstrerror(dev->dev_errno));
605 if (ok && dev->has_cap(CAP_TWOEOF) && !dev->bsf(1)) {
608 Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"),
609 be.bstrerror(dev->dev_errno));
611 /* Backspace over record */
612 if (ok && !dev->bsr(1)) {
615 Jmsg(jcr, M_ERROR, 0, _("Backspace record at EOT failed. ERR=%s\n"),
616 be.bstrerror(dev->dev_errno));
618 * On FreeBSD systems, if the user got here, it is likely that his/her
619 * tape drive is "frozen". The correct thing to do is a
620 * rewind(), but if we do that, higher levels in cleaning up, will
621 * most likely write the EOS record over the beginning of the
622 * tape. The rewind *is* done later in mount.c when another
623 * tape is requested. Note, the clrerror() call in bsr()
624 * calls ioctl(MTCERRSTAT), which *should* fix the problem.
628 dev->new_dcr_blocks(dcr);
629 /* Note, this can destroy dev->errmsg */
630 if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
631 Jmsg(jcr, M_ERROR, 0, _("Re-read last block at EOT failed. ERR=%s"),
635 * If we wrote block and the block numbers don't agree
636 * we have a possible problem.
638 if (dcr->block->BlockNumber != dev->LastBlock) {
639 if (dev->LastBlock > (dcr->block->BlockNumber + 1)) {
640 Jmsg(jcr, M_FATAL, 0, _(
641 "Re-read of last block: block numbers differ by more than one.\n"
642 "Probable tape misconfiguration and data loss. Read block=%u Want block=%u.\n"),
643 dcr->block->BlockNumber, dev->LastBlock);
645 Jmsg(jcr, M_ERROR, 0, _(
646 "Re-read of last block OK, but block numbers differ. Read block=%u Want block=%u.\n"),
647 dcr->block->BlockNumber, dev->LastBlock);
650 Jmsg(jcr, M_INFO, 0, _("Re-read of last block succeeded.\n"));
653 dev->free_dcr_blocks(dcr);
654 dcr->ameta_block = ameta_block;
656 dcr->adata_block = adata_block;
663 * If this routine is called, we do our bookkeeping and
664 * then assure that the volume will not be written any
667 bool terminate_writing_volume(DCR *dcr)
669 DEVICE *dev = dcr->dev;
671 bool was_adata = false;
675 if (dev->is_ateot()) {
676 return ok; /* already been here return now */
679 /* Work with ameta device */
681 dev->set_ateot(); /* no more writing this Volume */
682 dcr->adata_block->write_failed = true;
684 dev = dcr->ameta_dev;
688 /* Create a JobMedia record to indicated end of medium */
689 dev->VolCatInfo.VolCatFiles = dev->get_file();
690 dev->VolCatInfo.VolLastPartBytes = dev->part_size;
691 dev->VolCatInfo.VolCatParts = dev->part;
692 if (!dir_create_jobmedia_record(dcr)) {
693 Dmsg0(50, "Error from create JobMedia\n");
694 dev->dev_errno = EIO;
695 Mmsg2(dev->errmsg, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
696 dev->getVolCatName(), dcr->jcr->Job);
697 Jmsg(dcr->jcr, M_FATAL, 0, "%s", dev->errmsg);
700 flush_jobmedia_queue(dcr->jcr);
701 bstrncpy(dev->LoadedVolName, dev->VolCatInfo.VolCatName, sizeof(dev->LoadedVolName));
702 dcr->block->write_failed = true;
703 if (dev->can_append() && !dev->weof(dcr, 1)) { /* end the tape */
704 dev->VolCatInfo.VolCatErrors++;
705 Jmsg(dcr->jcr, M_ERROR, 0, _("Error writing final EOF to tape. Volume %s may not be readable.\n"
706 "%s"), dev->VolCatInfo.VolCatName, dev->errmsg);
708 Dmsg0(50, "Error writing final EOF to volume.\n");
711 ok = dev->end_of_volume(dcr);
714 Dmsg3(100, "Set VolCatStatus Full adata=%d size=%lld vol=%s\n", dev->adata,
715 dev->VolCatInfo.VolCatBytes, dev->VolCatInfo.VolCatName);
717 /* If still in append mode mark volume Full */
718 if (bstrcmp(dev->VolCatInfo.VolCatStatus, "Append")) {
719 dev->setVolCatStatus("Full");
722 if (!dir_update_volume_info(dcr, false, true)) {
723 Mmsg(dev->errmsg, _("Error sending Volume info to Director.\n"));
725 Dmsg0(50, "Error updating volume info.\n");
727 Dmsg2(150, "dir_update_volume_info vol=%s to terminate writing -- %s\n",
728 dev->getVolCatName(), ok?"OK":"ERROR");
730 dev->notify_newvol_in_attached_dcrs(NULL);
732 /* Set new file/block parameters for current dcr */
733 set_new_file_parameters(dcr);
735 if (ok && dev->has_cap(CAP_TWOEOF) && dev->can_append() && !dev->weof(dcr, 1)) { /* end the tape */
736 dev->VolCatInfo.VolCatErrors++;
737 /* This may not be fatal since we already wrote an EOF */
738 if (dev->errmsg[0]) {
739 Jmsg(dcr->jcr, M_ERROR, 0, "%s", dev->errmsg);
741 Dmsg0(50, "Writing second EOF failed.\n");
744 dev->set_ateot(); /* no more writing this tape */
745 Dmsg2(150, "Leave terminate_writing_volume=%s -- %s\n",
746 dev->getVolCatName(), ok?"OK":"ERROR");
755 * If a new volume has been mounted since our last write
756 * Create a JobMedia record for the previous volume written,
757 * and set new parameters to write this volume
758 * The same applies for if we are in a new file.
760 bool check_for_newvol_or_newfile(DCR *dcr)
764 if (dcr->NewVol || dcr->NewFile) {
765 if (job_canceled(jcr)) {
766 Dmsg0(100, "Canceled\n");
769 /* If we wrote on Volume create a last jobmedia record for this job */
770 if (!dcr->VolFirstIndex) {
771 Dmsg7(100, "Skip JobMedia Vol=%s wrote=%d MediaId=%lld FI=%lu LI=%lu StartAddr=%lld EndAddr=%lld\n",
772 dcr->VolumeName, dcr->WroteVol, dcr->VolMediaId,
773 dcr->VolFirstIndex, dcr->VolLastIndex, dcr->StartAddr, dcr->EndAddr);
775 if (dcr->VolFirstIndex && !dir_create_jobmedia_record(dcr)) {
776 dcr->dev->dev_errno = EIO;
777 Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
778 dcr->getVolCatName(), jcr->Job);
779 set_new_volume_parameters(dcr);
780 Dmsg0(100, "cannot create media record\n");
784 Dmsg0(250, "Process NewVol\n");
785 flush_jobmedia_queue(jcr);
786 /* Note, setting a new volume also handles any pending new file */
787 set_new_volume_parameters(dcr);
789 set_new_file_parameters(dcr);
796 * Do bookkeeping when a new file is created on a Volume. This is
797 * also done for disk files to generate the jobmedia records for
800 bool do_new_file_bookkeeping(DCR *dcr)
802 DEVICE *dev = dcr->dev;
805 /* Create a JobMedia record so restore can seek */
806 if (!dir_create_jobmedia_record(dcr)) {
807 Dmsg0(40, "Error from create_job_media.\n");
808 dev->dev_errno = EIO;
809 Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
810 dcr->getVolCatName(), jcr->Job);
811 Dmsg0(40, "Call terminate_writing_volume\n");
812 terminate_writing_volume(dcr);
813 dev->dev_errno = EIO;
816 dev->VolCatInfo.VolCatFiles = dev->get_file();
817 dev->VolCatInfo.VolLastPartBytes = dev->part_size;
818 dev->VolCatInfo.VolCatParts = dev->part;
819 if (!dir_update_volume_info(dcr, false, false)) {
820 Dmsg0(50, "Error from update_vol_info.\n");
821 Dmsg0(40, "Call terminate_writing_volume\n");
822 terminate_writing_volume(dcr);
823 dev->dev_errno = EIO;
826 Dmsg0(100, "dir_update_volume_info max file size -- OK\n");
828 dev->notify_newfile_in_attached_dcrs();
830 /* Set new file/block parameters for current dcr */
831 set_new_file_parameters(dcr);