3 * block.c -- tape block handling functions
5 * Kern Sibbald, March MMI
6 * added BB02 format October MMII
12 Copyright (C) 2001-2006 Kern Sibbald
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License
16 version 2 as amended with additional clauses defined in the
17 file LICENSE in the main source directory.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 the file LICENSE for additional details.
30 static bool terminate_writing_volume(DCR *dcr);
31 static bool do_new_file_bookkeeping(DCR *dcr);
32 static bool do_dvd_size_checks(DCR *dcr);
33 static void reread_last_block(DCR *dcr);
36 * Dump the block header, then walk through
37 * the block printing out the record headers.
39 void dump_block(DEV_BLOCK *b, const char *msg)
43 char Id[BLKHDR_ID_LENGTH+1];
44 uint32_t CheckSum, BlockCheckSum;
47 uint32_t VolSessionId, VolSessionTime, data_len;
51 char buf1[100], buf2[100];
53 unser_begin(b->buf, BLKHDR1_LENGTH);
54 unser_uint32(CheckSum);
55 unser_uint32(block_len);
56 unser_uint32(BlockNumber);
57 unser_bytes(Id, BLKHDR_ID_LENGTH);
58 ASSERT(unser_length(b->buf) == BLKHDR1_LENGTH);
59 Id[BLKHDR_ID_LENGTH] = 0;
61 unser_uint32(VolSessionId);
62 unser_uint32(VolSessionTime);
66 VolSessionId = VolSessionTime = 0;
71 if (block_len > 100000) {
72 Dmsg3(20, "Dump block %s 0x%x blocksize too big %u\n", msg, b, block_len);
76 BlockCheckSum = bcrc32((uint8_t *)b->buf+BLKHDR_CS_LENGTH,
77 block_len-BLKHDR_CS_LENGTH);
78 Pmsg6(000, _("Dump block %s %x: size=%d BlkNum=%d\n"
79 " Hdrcksum=%x cksum=%x\n"),
80 msg, b, block_len, BlockNumber, CheckSum, BlockCheckSum);
82 while (p < (b->buf + block_len+WRITE_RECHDR_LENGTH)) {
83 unser_begin(p, WRITE_RECHDR_LENGTH);
84 if (rhl == RECHDR1_LENGTH) {
85 unser_uint32(VolSessionId);
86 unser_uint32(VolSessionTime);
88 unser_int32(FileIndex);
90 unser_uint32(data_len);
91 Pmsg6(000, _(" Rec: VId=%u VT=%u FI=%s Strm=%s len=%d p=%x\n"),
92 VolSessionId, VolSessionTime, FI_to_ascii(buf1, FileIndex),
93 stream_to_ascii(buf2, Stream, FileIndex), data_len, p);
99 * Create a new block structure.
100 * We pass device so that the block can inherit the
101 * min and max block sizes.
103 DEV_BLOCK *new_block(DEVICE *dev)
105 DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK));
107 memset(block, 0, sizeof(DEV_BLOCK));
109 /* If the user has specified a max_block_size, use it as the default */
110 if (dev->max_block_size == 0) {
111 block->buf_len = DEFAULT_BLOCK_SIZE;
113 block->buf_len = dev->max_block_size;
116 block->block_len = block->buf_len; /* default block size */
117 block->buf = get_memory(block->buf_len);
119 block->BlockVer = BLOCK_VER; /* default write version */
120 Dmsg1(650, "Returning new block=%x\n", block);
126 * Duplicate an existing block (eblock)
128 DEV_BLOCK *dup_block(DEV_BLOCK *eblock)
130 DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK));
131 int buf_len = sizeof_pool_memory(eblock->buf);
133 memcpy(block, eblock, sizeof(DEV_BLOCK));
134 block->buf = get_memory(buf_len);
135 memcpy(block->buf, eblock->buf, buf_len);
141 * Only the first block checksum error was reported.
142 * If there are more, report it now.
144 void print_block_read_errors(JCR *jcr, DEV_BLOCK *block)
146 if (block->read_errors > 1) {
147 Jmsg(jcr, M_ERROR, 0, _("%d block read errors not printed.\n"),
155 void free_block(DEV_BLOCK *block)
157 Dmsg1(999, "free_block buffer %x\n", block->buf);
158 free_memory(block->buf);
159 Dmsg1(999, "free_block block %x\n", block);
160 free_memory((POOLMEM *)block);
163 /* Empty the block -- for writing */
164 void empty_block(DEV_BLOCK *block)
166 block->binbuf = WRITE_BLKHDR_LENGTH;
167 block->bufp = block->buf + block->binbuf;
169 block->write_failed = false;
170 block->block_read = false;
171 block->FirstIndex = block->LastIndex = 0;
175 * Create block header just before write. The space
176 * in the buffer should have already been reserved by
179 void ser_block_header(DEV_BLOCK *block)
182 uint32_t CheckSum = 0;
183 uint32_t block_len = block->binbuf;
185 Dmsg1(1390, "ser_block_header: block_len=%d\n", block_len);
186 ser_begin(block->buf, BLKHDR2_LENGTH);
187 ser_uint32(CheckSum);
188 ser_uint32(block_len);
189 ser_uint32(block->BlockNumber);
190 ser_bytes(WRITE_BLKHDR_ID, BLKHDR_ID_LENGTH);
191 if (BLOCK_VER >= 2) {
192 ser_uint32(block->VolSessionId);
193 ser_uint32(block->VolSessionTime);
196 /* Checksum whole block except for the checksum */
197 CheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
198 block_len-BLKHDR_CS_LENGTH);
199 Dmsg1(1390, "ser_bloc_header: checksum=%x\n", CheckSum);
200 ser_begin(block->buf, BLKHDR2_LENGTH);
201 ser_uint32(CheckSum); /* now add checksum to block header */
205 * Unserialize the block header for reading block.
206 * This includes setting all the buffer pointers correctly.
208 * Returns: false on failure (not a block)
211 static bool unser_block_header(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
214 char Id[BLKHDR_ID_LENGTH+1];
215 uint32_t CheckSum, BlockCheckSum;
218 uint32_t BlockNumber;
221 unser_begin(block->buf, BLKHDR_LENGTH);
222 unser_uint32(CheckSum);
223 unser_uint32(block_len);
224 unser_uint32(BlockNumber);
225 unser_bytes(Id, BLKHDR_ID_LENGTH);
226 ASSERT(unser_length(block->buf) == BLKHDR1_LENGTH);
228 Id[BLKHDR_ID_LENGTH] = 0;
230 bhl = BLKHDR1_LENGTH;
232 block->bufp = block->buf + bhl;
233 if (strncmp(Id, BLKHDR1_ID, BLKHDR_ID_LENGTH) != 0) {
234 dev->dev_errno = EIO;
235 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
236 dev->file, dev->block_num, BLKHDR1_ID, Id);
237 if (block->read_errors == 0 || verbose >= 2) {
238 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
240 block->read_errors++;
243 } else if (Id[3] == '2') {
244 unser_uint32(block->VolSessionId);
245 unser_uint32(block->VolSessionTime);
246 bhl = BLKHDR2_LENGTH;
248 block->bufp = block->buf + bhl;
249 if (strncmp(Id, BLKHDR2_ID, BLKHDR_ID_LENGTH) != 0) {
250 dev->dev_errno = EIO;
251 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
252 dev->file, dev->block_num, BLKHDR2_ID, Id);
253 if (block->read_errors == 0 || verbose >= 2) {
254 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
256 block->read_errors++;
260 dev->dev_errno = EIO;
261 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
262 dev->file, dev->block_num, BLKHDR2_ID, Id);
263 if (block->read_errors == 0 || verbose >= 2) {
264 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
266 block->read_errors++;
267 unser_uint32(block->VolSessionId);
268 unser_uint32(block->VolSessionTime);
273 if (block_len > MAX_BLOCK_LENGTH) {
274 dev->dev_errno = EIO;
275 Mmsg3(dev->errmsg, _("Volume data error at %u:%u! Block length %u is insane (too large), probably due to a bad archive.\n"),
276 dev->file, dev->block_num, block_len);
277 if (block->read_errors == 0 || verbose >= 2) {
278 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
280 block->read_errors++;
284 Dmsg1(390, "unser_block_header block_len=%d\n", block_len);
285 /* Find end of block or end of buffer whichever is smaller */
286 if (block_len > block->read_len) {
287 block_end = block->read_len;
289 block_end = block_len;
291 block->binbuf = block_end - bhl;
292 block->block_len = block_len;
293 block->BlockNumber = BlockNumber;
294 Dmsg3(390, "Read binbuf = %d %d block_len=%d\n", block->binbuf,
296 if (block_len <= block->read_len) {
297 BlockCheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
298 block_len-BLKHDR_CS_LENGTH);
299 if (BlockCheckSum != CheckSum) {
300 dev->dev_errno = EIO;
301 Mmsg6(dev->errmsg, _("Volume data error at %u:%u!\n"
302 "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n"),
303 dev->file, dev->block_num, (unsigned)BlockNumber,
304 block_len, BlockCheckSum, CheckSum);
305 if (block->read_errors == 0 || verbose >= 2) {
306 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
308 block->read_errors++;
318 * Write a block to the device, with locking and unlocking
320 * Returns: true on success
324 bool write_block_to_device(DCR *dcr)
327 DEVICE *dev = dcr->dev;
331 stat = write_block_to_spool_file(dcr);
335 if (!dcr->dev_locked) {
340 * If a new volume has been mounted since our last write
341 * Create a JobMedia record for the previous volume written,
342 * and set new parameters to write this volume
343 * The same applies for if we are in a new file.
345 if (dcr->NewVol || dcr->NewFile) {
346 if (job_canceled(jcr)) {
350 /* Create a jobmedia record for this job */
351 if (!dir_create_jobmedia_record(dcr)) {
352 dev->dev_errno = EIO;
353 Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
354 dcr->VolCatInfo.VolCatName, jcr->Job);
355 set_new_volume_parameters(dcr);
360 /* Note, setting a new volume also handles any pending new file */
361 set_new_volume_parameters(dcr);
362 dcr->NewFile = false; /* this handled for new file too */
364 set_new_file_parameters(dcr);
368 if (!write_block_to_dev(dcr)) {
369 if (job_canceled(jcr) || jcr->JobType == JT_SYSTEM) {
372 stat = fixup_device_block_write_error(dcr);
377 if (!dcr->dev_locked) {
384 * Write a block to the device
386 * Returns: true on success or EOT
387 * false on hard error
389 bool write_block_to_dev(DCR *dcr)
392 uint32_t wlen; /* length to write */
393 int hit_max1, hit_max2;
395 DEVICE *dev = dcr->dev;
397 DEV_BLOCK *block = dcr->block;
399 #ifdef NO_TAPE_WRITE_TEST
403 ASSERT(block->binbuf == ((uint32_t) (block->bufp - block->buf)));
405 /* dump_block(block, "before write"); */
406 if (dev->at_weot()) {
407 Dmsg0(100, "return write_block_to_dev with ST_WEOT\n");
408 dev->dev_errno = ENOSPC;
409 Jmsg(jcr, M_FATAL, 0, _("Cannot write block. Device at EOM.\n"));
412 if (!dev->can_append()) {
413 dev->dev_errno = EIO;
414 Jmsg(jcr, M_FATAL, 0, _("Attempt to write on read-only Volume.\n"));
417 wlen = block->binbuf;
418 if (wlen <= WRITE_BLKHDR_LENGTH) { /* Does block have data in it? */
419 Dmsg0(100, "return write_block_to_dev no data to write\n");
423 * Clear to the end of the buffer if it is not full,
424 * and on tape devices, apply min and fixed blocking.
426 if (wlen != block->buf_len) {
427 uint32_t blen; /* current buffer length */
429 Dmsg2(200, "binbuf=%d buf_len=%d\n", block->binbuf, block->buf_len);
432 /* Adjust write size to min/max for tapes only */
433 if (dev->is_tape()) {
434 /* check for fixed block size */
435 if (dev->min_block_size == dev->max_block_size) {
436 wlen = block->buf_len; /* fixed block size already rounded */
437 /* Check for min block size */
438 } else if (wlen < dev->min_block_size) {
439 wlen = ((dev->min_block_size + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
440 /* Ensure size is rounded */
442 wlen = ((wlen + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
446 memset(block->bufp, 0, wlen-blen); /* clear garbage */
450 ser_block_header(block);
452 /* Limit maximum Volume size to value specified by user */
453 hit_max1 = (dev->max_volume_size > 0) &&
454 ((dev->VolCatInfo.VolCatBytes + block->binbuf)) >= dev->max_volume_size;
455 hit_max2 = (dev->VolCatInfo.VolCatMaxBytes > 0) &&
456 ((dev->VolCatInfo.VolCatBytes + block->binbuf)) >= dev->VolCatInfo.VolCatMaxBytes;
457 if (hit_max1 || hit_max2) {
460 Dmsg0(10, "==== Output bytes Triggered medium max capacity.\n");
462 max_cap = dev->max_volume_size;
464 max_cap = dev->VolCatInfo.VolCatMaxBytes;
466 Jmsg(jcr, M_INFO, 0, _("User defined maximum volume capacity %s exceeded on device %s.\n"),
467 edit_uint64_with_commas(max_cap, ed1), dev->print_name());
468 terminate_writing_volume(dcr);
469 reread_last_block(dcr); /* DEBUG */
470 dev->dev_errno = ENOSPC;
474 /* Limit maximum File size on volume to user specified value */
475 if ((dev->max_file_size > 0) &&
476 (dev->file_size+block->binbuf) >= dev->max_file_size) {
477 dev->file_size = 0; /* reset file size */
479 if (!dev->weof(1)) { /* write eof */
480 Dmsg0(190, "WEOF error in max file size.\n");
481 Jmsg(jcr, M_FATAL, 0, _("Unable to write EOF. ERR=%s\n"),
483 terminate_writing_volume(dcr);
484 dev->dev_errno = ENOSPC;
487 if (!write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName)) {
491 if (!do_new_file_bookkeeping(dcr)) {
492 /* Error message already sent */
497 if (!do_dvd_size_checks(dcr)) {
498 /* Error message already sent */
502 dev->VolCatInfo.VolCatWrites++;
503 Dmsg1(1300, "Write block of %u bytes\n", wlen);
504 #ifdef DEBUG_BLOCK_ZEROING
505 uint32_t *bp = (uint32_t *)block->buf;
506 if (bp[0] == 0 && bp[1] == 0 && bp[2] == 0 && block->buf[12] == 0) {
507 Jmsg0(jcr, M_ABORT, 0, _("Write block header zeroed.\n"));
512 * Do write here, make a somewhat feeble attempt to recover from
513 * I/O errors, or from the OS telling us it is busy.
517 if (dev->is_tape()) {
518 stat = tape_write(dev->fd, block->buf, (size_t)wlen);
520 stat = write(dev->fd, block->buf, (size_t)wlen);
523 bmicrosleep(0, 100000); /* pause a bit if lots of errors */
525 } while (stat == -1 && (errno == EBUSY || errno == EIO) && retry++ < 30);
527 #ifdef DEBUG_BLOCK_ZEROING
528 if (bp[0] == 0 && bp[1] == 0 && bp[2] == 0 && block->buf[12] == 0) {
529 Jmsg0(jcr, M_ABORT, 0, _("Write block header zeroed.\n"));
533 if (stat != (ssize_t)wlen) {
534 /* Some devices simply report EIO when the volume is full.
535 * With a little more thought we may be able to check
536 * capacity and distinguish real errors and EOT
537 * conditions. In any case, we probably want to
538 * simulate an End of Medium.
543 if (dev->dev_errno == 0) {
544 dev->dev_errno = ENOSPC; /* out of space */
546 if (dev->dev_errno != ENOSPC) {
547 Jmsg4(jcr, M_ERROR, 0, _("Write error at %u:%u on device %s. ERR=%s.\n"),
548 dev->file, dev->block_num, dev->print_name(), be.strerror());
551 dev->dev_errno = ENOSPC; /* out of space */
553 if (dev->dev_errno == ENOSPC) {
554 Jmsg(jcr, M_INFO, 0, _("End of Volume \"%s\" at %u:%u on device %s. Write of %u bytes got %d.\n"),
555 dev->VolCatInfo.VolCatName,
556 dev->file, dev->block_num, dev->print_name(), wlen, stat);
558 Dmsg7(100, "=== Write error. fd=%d size=%u rtn=%d dev_blk=%d blk_blk=%d errno=%d: ERR=%s\n",
559 dev->fd, wlen, stat, dev->block_num, block->BlockNumber,
560 dev->dev_errno, strerror(dev->dev_errno));
562 ok = terminate_writing_volume(dcr);
563 if (!ok && !forge_on) {
567 reread_last_block(dcr);
572 /* We successfully wrote the block, now do housekeeping */
573 Dmsg2(1300, "VolCatBytes=%d newVolCatBytes=%d\n", (int)dev->VolCatInfo.VolCatBytes,
574 (int)(dev->VolCatInfo.VolCatBytes+wlen));
575 dev->VolCatInfo.VolCatBytes += wlen;
576 dev->VolCatInfo.VolCatBlocks++;
577 dev->EndBlock = dev->block_num;
578 dev->EndFile = dev->file;
579 block->BlockNumber++;
581 /* Update dcr values */
582 if (dev->is_tape()) {
583 dcr->EndBlock = dev->EndBlock;
584 dcr->EndFile = dev->EndFile;
587 /* Save address of block just written */
588 uint64_t addr = dev->file_addr + wlen - 1;
589 dcr->EndBlock = (uint32_t)addr;
590 dcr->EndFile = (uint32_t)(addr >> 32);
591 dev->block_num = dcr->EndBlock;
592 dev->file = dcr->EndFile;
594 if (dcr->VolFirstIndex == 0 && block->FirstIndex > 0) {
595 dcr->VolFirstIndex = block->FirstIndex;
597 if (block->LastIndex > 0) {
598 dcr->VolLastIndex = block->LastIndex;
600 dcr->WroteVol = true;
601 dev->file_addr += wlen; /* update file address */
602 dev->file_size += wlen;
603 dev->part_size += wlen;
605 Dmsg2(1300, "write_block: wrote block %d bytes=%d\n", dev->block_num, wlen);
610 static void reread_last_block(DCR *dcr)
612 #define CHECK_LAST_BLOCK
613 #ifdef CHECK_LAST_BLOCK
615 DEVICE *dev = dcr->dev;
617 DEV_BLOCK *block = dcr->block;
619 * If the device is a tape and it supports backspace record,
620 * we backspace over one or two eof marks depending on
621 * how many we just wrote, then over the last record,
622 * then re-read it and verify that the block number is
625 if (dev->is_tape() && dev_cap(dev, CAP_BSR)) {
626 /* Now back up over what we wrote and read the last block */
630 Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"),
631 be.strerror(dev->dev_errno));
633 if (ok && dev->has_cap(CAP_TWOEOF) && !dev->bsf(1)) {
636 Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"),
637 be.strerror(dev->dev_errno));
639 /* Backspace over record */
640 if (ok && !dev->bsr(1)) {
643 Jmsg(jcr, M_ERROR, 0, _("Backspace record at EOT failed. ERR=%s\n"),
644 be.strerror(dev->dev_errno));
646 * On FreeBSD systems, if the user got here, it is likely that his/her
647 * tape drive is "frozen". The correct thing to do is a
648 * rewind(), but if we do that, higher levels in cleaning up, will
649 * most likely write the EOS record over the beginning of the
650 * tape. The rewind *is* done later in mount.c when another
651 * tape is requested. Note, the clrerror() call in bsr()
652 * calls ioctl(MTCERRSTAT), which *should* fix the problem.
656 DEV_BLOCK *lblock = new_block(dev);
657 /* Note, this can destroy dev->errmsg */
659 if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
660 Jmsg(jcr, M_ERROR, 0, _("Re-read last block at EOT failed. ERR=%s"),
664 * If we wrote block and the block numbers don't agree
665 * we have a possible problem.
667 if (lblock->VolSessionId == block->VolSessionId &&
668 lblock->BlockNumber+1 != block->BlockNumber) {
669 Jmsg(jcr, M_ERROR, 0, _(
670 "Re-read of last block OK, but block numbers differ. Last block=%u Current block=%u.\n"),
671 lblock->BlockNumber, block->BlockNumber);
673 Jmsg(jcr, M_INFO, 0, _("Re-read of last block succeeded.\n"));
683 static bool terminate_writing_volume(DCR *dcr)
685 DEVICE *dev = dcr->dev;
688 /* Create a JobMedia record to indicated end of tape */
689 dev->VolCatInfo.VolCatFiles = dev->file;
690 if (!dir_create_jobmedia_record(dcr)) {
691 Dmsg0(190, "Error from create JobMedia\n");
692 dev->dev_errno = EIO;
693 Jmsg(dcr->jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
694 dcr->VolCatInfo.VolCatName, dcr->jcr->Job);
698 dcr->block->write_failed = true;
699 if (!dev->weof(1)) { /* end the tape */
700 dev->VolCatInfo.VolCatErrors++;
701 Jmsg(dcr->jcr, M_ERROR, 0, _("Error writing final EOF to tape. This Volume may not be readable.\n"
704 Dmsg0(100, "WEOF error.\n");
707 ok = write_ansi_ibm_labels(dcr, ANSI_EOV_LABEL, dev->VolHdr.VolumeName);
709 bstrncpy(dev->VolCatInfo.VolCatStatus, "Full", sizeof(dev->VolCatInfo.VolCatStatus));
710 dev->VolCatInfo.VolCatFiles = dev->file; /* set number of files */
711 dev->VolCatInfo.VolCatJobs++; /* increment number of jobs */
714 if (!dvd_write_part(dcr)) { /* write last part */
715 dev->VolCatInfo.VolCatErrors++;
716 Jmsg(dcr->jcr, M_FATAL, 0, _("Error writing final part to DVD. "
717 "This Volume may not be readable.\n%s"),
720 Dmsg0(100, "dvd_write_part error.\n");
722 dev->VolCatInfo.VolCatParts = dev->num_dvd_parts;
725 if (!dir_update_volume_info(dcr, false)) {
728 Dmsg1(100, "dir_update_volume_info terminate writing -- %s\n", ok?"OK":"ERROR");
731 * Walk through all attached dcrs setting flag to call
732 * set_new_file_parameters() when that dcr is next used.
735 foreach_dlist(mdcr, dev->attached_dcrs) {
736 if (mdcr->jcr->JobId == 0) {
739 mdcr->NewFile = true; /* set reminder to do set_new_file_params */
741 /* Set new file/block parameters for current dcr */
742 set_new_file_parameters(dcr);
744 if (ok && dev_cap(dev, CAP_TWOEOF) && !dev->weof(1)) { /* end the tape */
745 dev->VolCatInfo.VolCatErrors++;
746 /* This may not be fatal since we already wrote an EOF */
747 Jmsg(dcr->jcr, M_ERROR, 0, "%s", dev->errmsg);
750 dev->set_ateot(); /* no more writing this tape */
751 Dmsg1(100, "Leave terminate_writing_volume -- %s\n", ok?"OK":"ERROR");
756 * Do bookkeeping when a new file is created on a Volume. This is
757 * also done for disk files to generate the jobmedia records for
760 static bool do_new_file_bookkeeping(DCR *dcr)
762 DEVICE *dev = dcr->dev;
765 /* Create a JobMedia record so restore can seek */
766 if (!dir_create_jobmedia_record(dcr)) {
767 Dmsg0(190, "Error from create_job_media.\n");
768 dev->dev_errno = EIO;
769 Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
770 dcr->VolCatInfo.VolCatName, jcr->Job);
771 terminate_writing_volume(dcr);
772 dev->dev_errno = EIO;
775 dev->VolCatInfo.VolCatFiles = dev->file;
776 if (!dir_update_volume_info(dcr, false)) {
777 Dmsg0(190, "Error from update_vol_info.\n");
778 terminate_writing_volume(dcr);
779 dev->dev_errno = EIO;
782 Dmsg0(100, "dir_update_volume_info max file size -- OK\n");
785 * Walk through all attached dcrs setting flag to call
786 * set_new_file_parameters() when that dcr is next used.
789 foreach_dlist(mdcr, dev->attached_dcrs) {
790 if (mdcr->jcr->JobId == 0) {
793 mdcr->NewFile = true; /* set reminder to do set_new_file_params */
795 /* Set new file/block parameters for current dcr */
796 set_new_file_parameters(dcr);
801 * Do all checks for DVD sizes during writing.
803 static bool do_dvd_size_checks(DCR *dcr)
805 DEVICE *dev = dcr->dev;
807 DEV_BLOCK *block = dcr->block;
809 /* Don't go further if the device is not a dvd */
810 if (!dev->is_dvd()) {
814 /* Limit maximum part size to value specified by user
816 if (dev->max_part_size > 0 && ((dev->part_size + block->binbuf) >= dev->max_part_size)) {
817 if (dev->part < dev->num_dvd_parts) {
818 Jmsg3(dcr->jcr, M_FATAL, 0, _("Error while writing, current part number"
819 " is less than the total number of parts (%d/%d, device=%s)\n"),
820 dev->part, dev->num_dvd_parts, dev->print_name());
821 dev->dev_errno = EIO;
825 if (dvd_open_next_part(dcr) < 0) {
826 Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device next part %s: ERR=%s\n"),
827 dev->print_name(), dev->bstrerror());
828 dev->dev_errno = EIO;
832 dev->VolCatInfo.VolCatParts = dev->num_dvd_parts;
834 if (!dir_update_volume_info(dcr, false)) {
835 Dmsg0(190, "Error from update_vol_info.\n");
836 dev->dev_errno = EIO;
841 if (!dev->is_freespace_ok()) {
842 update_free_space_dev(dev);
845 if (!dev->is_freespace_ok()) { /* Error while getting free space */
846 char ed1[50], ed2[50];
847 Dmsg1(10, "Cannot get free space on the device ERR=%s.\n", dev->errmsg);
848 Jmsg(jcr, M_FATAL, 0, _("End of Volume \"%s\" at %u:%u on device %s "
849 "(part_size=%s, free_space=%s, free_space_errno=%d, errmsg=%s).\n"),
850 dev->VolCatInfo.VolCatName,
851 dev->file, dev->block_num, dev->print_name(),
852 edit_uint64_with_commas(dev->part_size, ed1), edit_uint64_with_commas(dev->free_space, ed2),
853 dev->free_space_errno, dev->errmsg);
854 dev->dev_errno = dev->free_space_errno;
858 if ((dev->is_freespace_ok() && (dev->part_size + block->binbuf) >= dev->free_space)) {
859 char ed1[50], ed2[50];
860 Dmsg0(10, "==== Just enough free space on the device to write the current part...\n");
861 Jmsg(jcr, M_INFO, 0, _("End of Volume \"%s\" at %u:%u on device %s "
862 "(part_size=%s, free_space=%s, free_space_errno=%d).\n"),
863 dev->VolCatInfo.VolCatName,
864 dev->file, dev->block_num, dev->print_name(),
865 edit_uint64_with_commas(dev->part_size, ed1), edit_uint64_with_commas(dev->free_space, ed2),
866 dev->free_space_errno);
867 terminate_writing_volume(dcr);
868 dev->dev_errno = ENOSPC;
876 * Read block with locking
879 bool read_block_from_device(DCR *dcr, bool check_block_numbers)
882 DEVICE *dev = dcr->dev;
883 Dmsg0(200, "Enter read_block_from_device\n");
885 ok = read_block_from_dev(dcr, check_block_numbers);
887 Dmsg0(200, "Leave read_block_from_device\n");
892 * Read the next block into the block structure and unserialize
893 * the block header. For a file, the block may be partially
894 * or completely in the current buffer.
896 bool read_block_from_dev(DCR *dcr, bool check_block_numbers)
900 uint32_t BlockNumber;
903 DEVICE *dev = dcr->dev;
904 DEV_BLOCK *block = dcr->block;
910 Dmsg1(200, "Full read() in read_block_from_device() len=%d\n",
914 dev->dev_errno = EIO;
915 Mmsg1(dev->errmsg, _("Block buffer size looping problem on device %s\n"),
917 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
922 #define lots_of_debug
924 if (dev->at_eof() && dev->is_dvd()) {
925 Dmsg1(100, "file_size=%u\n",(unsigned int)dev->file_size);
926 Dmsg1(100, "file_addr=%u\n",(unsigned int)dev->file_addr);
927 Dmsg1(100, "lseek=%u\n",(unsigned int)lseek(dev->fd, 0, SEEK_CUR));
928 Dmsg1(100, "part_start=%u\n",(unsigned int)dev->part_start);
929 Dmsg1(100, "part_size=%u\n", (unsigned int)dev->part_size);
930 Dmsg2(100, "part=%u num_dvd_parts=%u\n", dev->part, dev->num_dvd_parts);
931 Dmsg1(100, "VolCatInfo.VolCatParts=%u\n", (unsigned int)dev->VolCatInfo.VolCatParts);
932 Dmsg3(100, "Tests : %d %d %d\n", (dev->VolCatInfo.VolCatParts > 0),
933 ((dev->file_addr-dev->part_start) == dev->part_size),
934 (dev->part <= dev->VolCatInfo.VolCatParts));
938 /* Check for DVD part file end */
939 if (dev->at_eof() && dev->is_dvd() && dev->num_dvd_parts > 0 &&
940 dev->part <= dev->num_dvd_parts) {
941 Dmsg0(400, "Call dvd_open_next_part\n");
942 if (dvd_open_next_part(dcr) < 0) {
943 Jmsg3(dcr->jcr, M_FATAL, 0, _("Unable to open device part=%d %s: ERR=%s\n"),
944 dev->part, dev->print_name(), dev->bstrerror());
945 dev->dev_errno = EIO;
952 // uint32_t *bp = (uint32_t *)block->buf;
953 // Pmsg3(000, "Read %p %u at %llu\n", block->buf, block->buf_len, lseek(dev->fd, 0, SEEK_CUR));
955 if (dev->is_tape()) {
956 stat = tape_read(dev->fd, block->buf, (size_t)block->buf_len);
958 stat = read(dev->fd, block->buf, (size_t)block->buf_len);
961 // Pmsg8(000, "stat=%d Csum=%u blen=%u bnum=%u %c%c%c%c\n",stat, bp[0],bp[1],bp[2],
962 // block->buf[12],block->buf[13],block->buf[14],block->buf[15]);
965 dev->VolCatInfo.VolCatErrors++;
967 } while (stat == -1 && (errno == EINTR || errno == EIO) && retry++ < 11);
971 Dmsg1(200, "Read device got: ERR=%s\n", be.strerror());
973 Mmsg4(dev->errmsg, _("Read error at file:blk %u:%u on device %s. ERR=%s.\n"),
974 dev->file, dev->block_num, dev->print_name(), be.strerror());
975 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
976 if (dev->at_eof()) { /* EOF just seen? */
977 dev->set_eot(); /* yes, error => EOT */
981 Dmsg3(200, "Read device got %d bytes at %u:%u\n", stat,
982 dev->file, dev->block_num);
983 if (stat == 0) { /* Got EOF ! */
986 Mmsg3(dev->errmsg, _("Read zero bytes at %u:%u on device %s.\n"),
987 dev->file, dev->block_num, dev->print_name());
988 if (dev->at_eof()) { /* EOF already read? */
989 dev->set_eot(); /* yes, 2 EOFs => EOT */
993 return false; /* return eof */
995 /* Continue here for successful read */
996 block->read_len = stat; /* save length read */
997 if (block->read_len < BLKHDR2_LENGTH) {
998 dev->dev_errno = EIO;
999 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Very short block of %d bytes on device %s discarded.\n"),
1000 dev->file, dev->block_num, block->read_len, dev->print_name());
1001 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
1002 dev->set_short_block();
1003 block->read_len = block->binbuf = 0;
1004 return false; /* return error */
1007 BlockNumber = block->BlockNumber + 1;
1008 if (!unser_block_header(jcr, dev, block)) {
1010 dev->file_addr += block->read_len;
1011 dev->file_size += block->read_len;
1018 * If the block is bigger than the buffer, we reposition for
1019 * re-reading the block, allocate a buffer of the correct size,
1022 if (block->block_len > block->buf_len) {
1023 dev->dev_errno = EIO;
1024 Mmsg2(dev->errmsg, _("Block length %u is greater than buffer %u. Attempting recovery.\n"),
1025 block->block_len, block->buf_len);
1026 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
1027 Pmsg1(000, "%s", dev->errmsg);
1028 /* Attempt to reposition to re-read the block */
1029 if (dev->is_tape()) {
1030 Dmsg0(200, "BSR for reread; block too big for buffer.\n");
1032 Jmsg(jcr, M_ERROR, 0, "%s", dev->bstrerror());
1033 block->read_len = 0;
1037 Dmsg0(200, "Seek to beginning of block for reread.\n");
1038 off_t pos = dev->lseek(dcr, (off_t)0, SEEK_CUR); /* get curr pos */
1039 pos -= block->read_len;
1040 dev->lseek(dcr, pos, SEEK_SET);
1041 dev->file_addr = pos;
1043 Mmsg1(dev->errmsg, _("Setting block buffer size to %u bytes.\n"), block->block_len);
1044 Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg);
1045 Pmsg1(000, "%s", dev->errmsg);
1046 /* Set new block length */
1047 dev->max_block_size = block->block_len;
1048 block->buf_len = block->block_len;
1049 free_memory(block->buf);
1050 block->buf = get_memory(block->buf_len);
1053 goto reread; /* re-read block with correct block size */
1056 if (block->block_len > block->read_len) {
1057 dev->dev_errno = EIO;
1058 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Short block of %d bytes on device %s discarded.\n"),
1059 dev->file, dev->block_num, block->read_len, dev->print_name());
1060 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
1061 dev->set_short_block();
1062 block->read_len = block->binbuf = 0;
1063 return false; /* return error */
1066 dev->clear_short_block();
1068 dev->VolCatInfo.VolCatReads++;
1069 dev->VolCatInfo.VolCatRBytes += block->read_len;
1071 dev->VolCatInfo.VolCatBytes += block->block_len;
1072 dev->VolCatInfo.VolCatBlocks++;
1073 dev->EndBlock = dev->block_num;
1074 dev->EndFile = dev->file;
1077 /* Update dcr values */
1078 if (dev->is_tape()) {
1079 dcr->EndBlock = dev->EndBlock;
1080 dcr->EndFile = dev->EndFile;
1082 uint64_t addr = dev->file_addr + block->read_len - 1;
1083 dcr->EndBlock = (uint32_t)addr;
1084 dcr->EndFile = (uint32_t)(addr >> 32);
1085 dev->block_num = dcr->EndBlock;
1086 dev->file = dcr->EndFile;
1088 dev->file_addr += block->read_len;
1089 dev->file_size += block->read_len;
1092 * If we read a short block on disk,
1093 * seek to beginning of next block. This saves us
1094 * from shuffling blocks around in the buffer. Take a
1095 * look at this from an efficiency stand point later, but
1096 * it should only happen once at the end of each job.
1098 * I've been lseek()ing negative relative to SEEK_CUR for 30
1099 * years now. However, it seems that with the new off_t definition,
1100 * it is not possible to seek negative amounts, so we use two
1101 * lseek(). One to get the position, then the second to do an
1102 * absolute positioning -- so much for efficiency. KES Sep 02.
1104 Dmsg0(200, "At end of read block\n");
1105 if (block->read_len > block->block_len && !dev->is_tape()) {
1107 off_t pos = dev->lseek(dcr, (off_t)0, SEEK_CUR); /* get curr pos */
1108 Dmsg1(200, "Current lseek pos=%s\n", edit_int64(pos, ed1));
1109 pos -= (block->read_len - block->block_len);
1110 dev->lseek(dcr, pos, SEEK_SET);
1111 Dmsg3(200, "Did lseek pos=%s blk_size=%d rdlen=%d\n",
1112 edit_int64(pos, ed1), block->block_len,
1114 dev->file_addr = pos;
1115 dev->file_size = pos;
1117 Dmsg2(200, "Exit read_block read_len=%d block_len=%d\n",
1118 block->read_len, block->block_len);
1119 block->block_read = true;