]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/block_util.c
Backport from BEE
[bacula/bacula] / bacula / src / stored / block_util.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2001-2014 Free Software Foundation Europe e.V.
5
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.
8
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.
13
14    Bacula® is a registered trademark of Kern Sibbald.
15 */
16 /*
17  *
18  *   block_util.c -- tape block utility functions
19  *
20  *              Kern Sibbald, split from block.c March MMXII
21  *
22  */
23
24
25 #include "bacula.h"
26 #include "stored.h"
27
28 static const int dbgel = 160;
29
30 #ifdef DEBUG_BLOCK_CHECKSUM
31 static const bool debug_block_checksum = true;
32 #else
33 static const bool debug_block_checksum = false;
34 #endif
35
36 #ifdef NO_TAPE_WRITE_TEST
37 static const bool no_tape_write_test = true;
38 #else
39 static const bool no_tape_write_test = false;
40 #endif
41
42 /*
43  * Dump the block header, then walk through
44  * the block printing out the record headers.
45  */
46 void dump_block(DEV_BLOCK *b, const char *msg)
47 {
48    ser_declare;
49    char *p;
50    char Id[BLKHDR_ID_LENGTH+1];
51    uint32_t CheckSum, BlockCheckSum;
52    uint32_t block_len, reclen;
53    uint32_t BlockNumber;
54    uint32_t VolSessionId, VolSessionTime, data_len;
55    int32_t  FileIndex;
56    int32_t  Stream;
57    int bhl, rhl;
58    char buf1[100], buf2[100];
59
60    if ((debug_level & ~DT_ALL) < 250) {
61       return;
62    }
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;
70    if (Id[3] == '2') {
71       unser_uint32(VolSessionId);
72       unser_uint32(VolSessionTime);
73       bhl = BLKHDR2_LENGTH;
74       rhl = RECHDR2_LENGTH;
75    } else {
76       VolSessionId = VolSessionTime = 0;
77       bhl = BLKHDR1_LENGTH;
78       rhl = RECHDR1_LENGTH;
79    }
80
81    if (block_len > 4000000) {
82       Dmsg3(20, "!!!Dump block %s 0x%x blocksize too big %u\n", msg, b, block_len);
83       return;
84    }
85
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);
91    p = b->buf + bhl;
92    while (p < b->bufp) {
93       unser_begin(p, WRITE_RECHDR_LENGTH);
94       if (rhl == RECHDR1_LENGTH) {
95          unser_uint32(VolSessionId);
96          unser_uint32(VolSessionTime);
97       }
98       unser_int32(FileIndex);
99       unser_int32(Stream);
100       unser_uint32(data_len);
101       reclen = 0;
102       p += data_len + rhl;
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);
106   }
107 }
108
109 /*
110  * Create a new block structure.
111  * We pass device so that the block can inherit the
112  * min and max block sizes.
113  */
114 DEV_BLOCK *new_block(DEVICE *dev)
115 {
116    DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK));
117    int len;
118
119    memset(block, 0, sizeof(DEV_BLOCK));
120
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;
124    } else {
125       len = dev->max_block_size;
126    }
127    block->dev = dev;
128    /*
129     * Round to multiple of block size + ensure that
130     * the data length is a multiple of the block size
131     */
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;
136    empty_block(block);
137    block->BlockVer = BLOCK_VER;       /* default write version */
138    Dmsg2(150, "New block len=%d block=%p\n", len, block);
139    return block;
140 }
141
142
143 /*
144  * Duplicate an existing block (eblock)
145  */
146 DEV_BLOCK *dup_block(DEV_BLOCK *eblock)
147 {
148    DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK));
149    int buf_len = sizeof_pool_memory(eblock->buf);
150
151    memcpy(block, eblock, sizeof(DEV_BLOCK));
152    block->buf = get_memory(buf_len);
153    memcpy(block->buf, eblock->buf, buf_len);
154    return block;
155 }
156
157
158 /*
159  * Only the first block checksum error was reported.
160  *   If there are more, report it now.
161  */
162 void print_block_read_errors(JCR *jcr, DEV_BLOCK *block)
163 {
164    if (block->read_errors > 1) {
165       Jmsg(jcr, M_ERROR, 0, _("%d block read errors not printed.\n"),
166          block->read_errors);
167    }
168 }
169
170
171 void DCR::free_blocks()
172 {
173    if (block) {
174       free_block(block);
175    }
176 }
177
178 /*
179  * Free block
180  */
181 void free_block(DEV_BLOCK *block)
182 {
183    if (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);
189    }
190 }
191
192 bool is_block_empty(DEV_BLOCK *block)
193 {
194    return block->binbuf <= WRITE_BLKHDR_LENGTH;
195 }
196
197 /* Empty the block -- for writing */
198 void empty_block(DEV_BLOCK *block)
199 {
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 */
206    block->read_len = 0;
207    block->write_failed = false;
208    block->block_read = false;
209    block->needs_write = false;
210    block->FirstIndex = block->LastIndex = 0;
211 }
212
213 /*
214  * Create block header just before write. The space
215  * in the buffer should have already been reserved by
216  * init_block.
217  */
218 uint32_t ser_block_header(DEV_BLOCK *block, bool do_checksum)
219 {
220    ser_declare;
221    uint32_t block_len = block->binbuf;
222
223    block->CheckSum = 0;
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);
233    }
234
235    /* Checksum whole block except for the checksum */
236    if (do_checksum) {
237       block->CheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
238                     block_len-BLKHDR_CS_LENGTH);
239    }
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;
244 }
245
246 /*
247  * Unserialize the block header for reading block.
248  *  This includes setting all the buffer pointers correctly.
249  *
250  *  Returns: false on failure (not a block)
251  *           true  on success
252  */
253 bool unser_block_header(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
254 {
255    ser_declare;
256    char Id[BLKHDR_ID_LENGTH+1];
257    uint32_t BlockCheckSum;
258    uint32_t block_len;
259    uint32_t block_end;
260    uint32_t BlockNumber;
261    int bhl;
262
263    if (block->no_header) {
264       return true;
265    }
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);
272
273    Id[BLKHDR_ID_LENGTH] = 0;
274    if (Id[3] == '1') {
275       bhl = BLKHDR1_LENGTH;
276       block->BlockVer = 1;
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);
285          }
286          block->read_errors++;
287          return false;
288       }
289    } else if (Id[3] == '2') {
290       unser_uint32(block->VolSessionId);
291       unser_uint32(block->VolSessionTime);
292       bhl = BLKHDR2_LENGTH;
293       block->BlockVer = 2;
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);
301          }
302          block->read_errors++;
303          return false;
304       }
305    } else {
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);
312       }
313       block->read_errors++;
314       unser_uint32(block->VolSessionId);
315       unser_uint32(block->VolSessionTime);
316       return false;
317    }
318
319    /* Sanity check */
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);
326       }
327       block->read_errors++;
328       return false;
329    }
330
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;
335    } else {
336       block_end = block_len;
337    }
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,
343       bhl, block_len);
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");
356          }
357          block->read_errors++;
358          if (!forge_on) {
359             return false;
360          }
361       }
362    }
363    return true;
364 }
365
366 /*
367  * Calculate how many bytes to write and then clear to end
368  *  of block.
369  */
370 uint32_t get_len_and_clear_block(DEV_BLOCK *block, DEVICE *dev, uint32_t &pad)
371 {
372    uint32_t wlen;
373    /*
374     * Clear to the end of the buffer if it is not full,
375     *  and on tape devices, apply min and fixed blocking.
376     */
377    wlen = block->binbuf;
378    if (wlen != block->buf_len) {
379       Dmsg2(250, "binbuf=%d buf_len=%d\n", block->binbuf, block->buf_len);
380
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 */
390          } else {
391             wlen = ((wlen + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
392          }
393       }
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 */
398       }
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);
402    } else {
403       pad = 0;
404    }
405
406    return wlen;              /* bytes to write */
407 }
408
409 /*
410  * Determine if user defined volume size has been
411  *  reached, and if so, return true, otherwise
412  *  return false.
413  */
414 bool user_volume_size_reached(DCR *dcr, bool quiet)
415 {
416    bool hit_max1, hit_max2;
417    uint64_t size, max_size;
418    DEVICE *dev = dcr->dev;
419    char ed1[50];
420    bool rtn = false;
421
422    Enter(dbgel);
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);
428    if (hit_max1) {
429       max_size = dev->max_volume_size;
430    } else {
431       max_size = dev->VolCatInfo.VolCatMaxBytes;
432    }
433    if (hit_max1 || hit_max2) {
434       if (!quiet) {
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());
439       }
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());
444       rtn = true;
445    }
446    Dmsg1(dbgel, "Return from user_volume_size_reached=%d\n", rtn);
447    Leave(dbgel);
448    return rtn;
449 }
450
451
452 void reread_last_block(DCR *dcr)
453 {
454 #define CHECK_LAST_BLOCK
455 #ifdef  CHECK_LAST_BLOCK
456    bool ok = true;
457    DEVICE *dev = dcr->dev;
458    JCR *jcr = dcr->jcr;
459    DEV_BLOCK *block = dcr->block;
460    /*
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
465     *   correct.
466     */
467    if (dev->is_tape() && dev->has_cap(CAP_BSR)) {
468       /* Now back up over what we wrote and read the last block */
469       if (!dev->bsf(1)) {
470          berrno be;
471          ok = false;
472          Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"),
473               be.bstrerror(dev->dev_errno));
474       }
475       if (ok && dev->has_cap(CAP_TWOEOF) && !dev->bsf(1)) {
476          berrno be;
477          ok = false;
478          Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"),
479               be.bstrerror(dev->dev_errno));
480       }
481       /* Backspace over record */
482       if (ok && !dev->bsr(1)) {
483          berrno be;
484          ok = false;
485          Jmsg(jcr, M_ERROR, 0, _("Backspace record at EOT failed. ERR=%s\n"),
486               be.bstrerror(dev->dev_errno));
487          /*
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.
495           */
496       }
497       if (ok) {
498          DEV_BLOCK *lblock = new_block(dev);
499          /* Note, this can destroy dev->errmsg */
500          dcr->block = lblock;
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"),
503                  dev->errmsg);
504          } else {
505             /*
506              * If we wrote block and the block numbers don't agree
507              *  we have a possible problem.
508              */
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);
515                  } else {
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);
519                  }
520             } else {
521                Jmsg(jcr, M_INFO, 0, _("Re-read of last block succeeded.\n"));
522             }
523          }
524          free_block(lblock);
525          dcr->block = block;
526       }
527    }
528 #endif
529 }
530
531 /*
532  * If this routine is called, we do our bookkeeping and
533  *   then assure that the volume will not be written any
534  *   more.
535  */
536 bool terminate_writing_volume(DCR *dcr)
537 {
538    DEVICE *dev = dcr->dev;
539    bool ok = true;
540
541    Enter(dbgel);
542
543    if (dev->is_ateot()) {
544       return ok;          /* already been here return now */
545    }
546
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);
555        ok = false;
556    }
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"
561            "%s"), dev->errmsg);
562       ok = false;
563       Dmsg0(50, "Error writing final EOF to volume.\n");
564    }
565    if (ok) {
566       ok = write_ansi_ibm_labels(dcr, ANSI_EOV_LABEL, dev->VolHdr.VolumeName);
567    }
568
569    Dmsg2(100, "Set VolCatStatus Full size=%lld vol=%s\n",
570       dev->VolCatInfo.VolCatBytes, dev->VolCatInfo.VolCatName);
571
572    /* If still in append mode mark volume Full */
573    if (bstrcmp(dev->VolCatInfo.VolCatStatus, "Append")) {
574       dev->setVolCatStatus("Full");
575    }
576
577    if (!dir_update_volume_info(dcr, false, true)) {
578       Mmsg(dev->errmsg, _("Error sending Volume info to Director.\n"));
579       ok = false;
580       Dmsg0(50, "Error updating volume info.\n");
581    }
582    Dmsg2(150, "dir_update_volume_info vol=%s to terminate writing -- %s\n",
583       dev->getVolCatName(), ok?"OK":"ERROR");
584
585    dev->notify_newvol_in_attached_dcrs(NULL);
586
587    /* Set new file/block parameters for current dcr */
588    set_new_file_parameters(dcr);
589
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");
595    }
596
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");
600    Leave(dbgel);
601    return ok;
602 }
603
604 /*
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.
609  */
610 bool check_for_newvol_or_newfile(DCR *dcr)
611 {
612    JCR *jcr = dcr->jcr;
613
614    if (dcr->NewVol || dcr->NewFile) {
615       if (job_canceled(jcr)) {
616          Dmsg0(100, "Canceled\n");
617          return false;
618       }
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");
626          return false;
627       }
628       if (dcr->NewVol) {
629          /* Note, setting a new volume also handles any pending new file */
630          set_new_volume_parameters(dcr);
631       } else {
632          set_new_file_parameters(dcr);
633       }
634    }
635    return true;
636 }
637
638 /*
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
641  *  quick seeking.
642  */
643 bool do_new_file_bookkeeping(DCR *dcr)
644 {
645    DEVICE *dev = dcr->dev;
646    JCR *jcr = dcr->jcr;
647
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;
657       return false;
658    }
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;
665       return false;
666    }
667    Dmsg0(100, "dir_update_volume_info max file size -- OK\n");
668
669    dev->notify_newfile_in_attached_dcrs();
670
671    /* Set new file/block parameters for current dcr */
672    set_new_file_parameters(dcr);
673    return true;
674 }