]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/block_util.c
Remove vestiges of rechdr_queue hopefully fixes bug #2180
[bacula/bacula] / bacula / src / stored / block_util.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2015 Kern Sibbald
5    Copyright (C) 2001-2014 Free Software Foundation Europe e.V.
6
7    The original author of Bacula is Kern Sibbald, with contributions
8    from many others, a complete list can be found in the file AUTHORS.
9
10    You may use this file and others of this release according to the
11    license defined in the LICENSE file, which includes the Affero General
12    Public License, v3.0 ("AGPLv3") and some additional permissions and
13    terms pursuant to its AGPLv3 Section 7.
14
15    This notice must be preserved when any source code is 
16    conveyed and/or propagated.
17
18    Bacula(R) is a registered trademark of Kern Sibbald.
19 */
20 /*
21  *
22  *   block_util.c -- tape block utility functions
23  *
24  *              Kern Sibbald, split from block.c March MMXII
25  *
26  */
27
28
29 #include "bacula.h"
30 #include "stored.h"
31
32 static const int dbgel = 160;
33
34 #ifdef DEBUG_BLOCK_CHECKSUM
35 static const bool debug_block_checksum = true;
36 #else
37 static const bool debug_block_checksum = false;
38 #endif
39
40 #ifdef NO_TAPE_WRITE_TEST
41 static const bool no_tape_write_test = true;
42 #else
43 static const bool no_tape_write_test = false;
44 #endif
45
46 /*
47  * Dump the block header, then walk through
48  * the block printing out the record headers.
49  */
50 void dump_block(DEV_BLOCK *b, const char *msg)
51 {
52    ser_declare;
53    char *p;
54    char Id[BLKHDR_ID_LENGTH+1];
55    uint32_t CheckSum, BlockCheckSum;
56    uint32_t block_len, reclen;
57    uint32_t BlockNumber;
58    uint32_t VolSessionId, VolSessionTime, data_len;
59    int32_t  FileIndex;
60    int32_t  Stream;
61    int bhl, rhl;
62    char buf1[100], buf2[100];
63
64    if ((debug_level & ~DT_ALL) < 250) {
65       return;
66    }
67    unser_begin(b->buf, BLKHDR1_LENGTH);
68    unser_uint32(CheckSum);
69    unser_uint32(block_len);
70    unser_uint32(BlockNumber);
71    unser_bytes(Id, BLKHDR_ID_LENGTH);
72    ASSERT(unser_length(b->buf) == BLKHDR1_LENGTH);
73    Id[BLKHDR_ID_LENGTH] = 0;
74    if (Id[3] == '2') {
75       unser_uint32(VolSessionId);
76       unser_uint32(VolSessionTime);
77       bhl = BLKHDR2_LENGTH;
78       rhl = RECHDR2_LENGTH;
79    } else {
80       VolSessionId = VolSessionTime = 0;
81       bhl = BLKHDR1_LENGTH;
82       rhl = RECHDR1_LENGTH;
83    }
84
85    if (block_len > 4000000) {
86       Dmsg3(20, "!!!Dump block %s 0x%x blocksize too big %u\n", msg, b, block_len);
87       return;
88    }
89
90    BlockCheckSum = bcrc32((uint8_t *)b->buf+BLKHDR_CS_LENGTH,
91                          block_len-BLKHDR_CS_LENGTH);
92    Pmsg6(000, _("Dump block %s %p: size=%d BlkNum=%d\n"
93 "               Hdrcksum=%x cksum=%x\n"),
94       msg, b, block_len, BlockNumber, CheckSum, BlockCheckSum);
95    p = b->buf + bhl;
96    while (p < b->bufp) {
97       unser_begin(p, WRITE_RECHDR_LENGTH);
98       if (rhl == RECHDR1_LENGTH) {
99          unser_uint32(VolSessionId);
100          unser_uint32(VolSessionTime);
101       }
102       unser_int32(FileIndex);
103       unser_int32(Stream);
104       unser_uint32(data_len);
105       reclen = 0;
106       p += data_len + rhl;
107       Pmsg6(000, _("   Rec: VId=%u VT=%u FI=%s Strm=%s len=%d reclen=%d\n"),
108            VolSessionId, VolSessionTime, FI_to_ascii(buf1, FileIndex),
109            stream_to_ascii(buf2, Stream, FileIndex), data_len, reclen);
110   }
111 }
112
113 /*
114  * Create a new block structure.
115  * We pass device so that the block can inherit the
116  * min and max block sizes.
117  */
118 DEV_BLOCK *new_block(DEVICE *dev)
119 {
120    DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK));
121    int len;
122
123    memset(block, 0, sizeof(DEV_BLOCK));
124
125    /* If the user has specified a max_block_size, use it as the default */
126    if (dev->max_block_size == 0) {
127       len = DEFAULT_BLOCK_SIZE;
128    } else {
129       len = dev->max_block_size;
130    }
131    block->dev = dev;
132    /*
133     * Round to multiple of block size + ensure that
134     * the data length is a multiple of the block size
135     */
136    block->buf_len = len;
137    block->buf = get_memory(block->buf_len);
138    block->rechdr_items = 0;
139    empty_block(block);
140    block->BlockVer = BLOCK_VER;       /* default write version */
141    Dmsg2(150, "New block len=%d block=%p\n", len, block);
142    return block;
143 }
144
145
146 /*
147  * Duplicate an existing block (eblock)
148  */
149 DEV_BLOCK *dup_block(DEV_BLOCK *eblock)
150 {
151    DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK));
152    int buf_len = sizeof_pool_memory(eblock->buf);
153
154    memcpy(block, eblock, sizeof(DEV_BLOCK));
155    block->buf = get_memory(buf_len);
156    memcpy(block->buf, eblock->buf, buf_len);
157    return block;
158 }
159
160
161 /*
162  * Only the first block checksum error was reported.
163  *   If there are more, report it now.
164  */
165 void print_block_read_errors(JCR *jcr, DEV_BLOCK *block)
166 {
167    if (block->read_errors > 1) {
168       Jmsg(jcr, M_ERROR, 0, _("%d block read errors not printed.\n"),
169          block->read_errors);
170    }
171 }
172
173
174 void DCR::free_blocks()
175 {
176    if (block) {
177       free_block(block);
178    }
179 }
180
181 /*
182  * Free block
183  */
184 void free_block(DEV_BLOCK *block)
185 {
186    if (block) {
187       Dmsg1(999, "free_block buffer %x\n", block->buf);
188       free_memory(block->buf);
189       Dmsg1(999, "free_block block %x\n", block);
190       free_memory((POOLMEM *)block);
191    }
192 }
193
194 bool is_block_empty(DEV_BLOCK *block)
195 {
196    return block->binbuf <= WRITE_BLKHDR_LENGTH;
197 }
198
199 /* Empty the block -- for writing */
200 void empty_block(DEV_BLOCK *block)
201 {
202    block->binbuf = WRITE_BLKHDR_LENGTH;
203    Dmsg3(200, "empty len=%d block=%p set binbuf=%d\n",
204          block->buf_len, block, block->binbuf);
205    block->bufp = block->buf + block->binbuf;
206    block->buf[0] = 0;        /* clear for debugging */
207    block->bufp[0] = 0;       /* clear for debugging */
208    block->read_len = 0;
209    block->write_failed = false;
210    block->block_read = false;
211    block->needs_write = false;
212    block->FirstIndex = block->LastIndex = 0;
213 }
214
215 /*
216  * Create block header just before write. The space
217  * in the buffer should have already been reserved by
218  * init_block.
219  */
220 uint32_t ser_block_header(DEV_BLOCK *block, bool do_checksum)
221 {
222    ser_declare;
223    uint32_t block_len = block->binbuf;
224
225    block->CheckSum = 0;
226    Dmsg1(160, "block_header: block_len=%d\n", block_len);
227    ser_begin(block->buf, BLKHDR2_LENGTH);
228    ser_uint32(block->CheckSum);
229    ser_uint32(block_len);
230    ser_uint32(block->BlockNumber);
231    ser_bytes(WRITE_BLKHDR_ID, BLKHDR_ID_LENGTH);
232    if (BLOCK_VER >= 2) {
233       ser_uint32(block->VolSessionId);
234       ser_uint32(block->VolSessionTime);
235    }
236
237    /* Checksum whole block except for the checksum */
238    if (do_checksum) {
239       block->CheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
240                     block_len-BLKHDR_CS_LENGTH);
241    }
242    Dmsg1(160, "ser_block_header: checksum=%x\n", block->CheckSum);
243    ser_begin(block->buf, BLKHDR2_LENGTH);
244    ser_uint32(block->CheckSum);    /* now add checksum to block header */
245    return block->CheckSum;
246 }
247
248 /*
249  * Unserialize the block header for reading block.
250  *  This includes setting all the buffer pointers correctly.
251  *
252  *  Returns: false on failure (not a block)
253  *           true  on success
254  */
255 bool unser_block_header(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
256 {
257    ser_declare;
258    char Id[BLKHDR_ID_LENGTH+1];
259    uint32_t BlockCheckSum;
260    uint32_t block_len;
261    uint32_t block_end;
262    uint32_t BlockNumber;
263    int bhl;
264
265    if (block->no_header) {
266       return true;
267    }
268    unser_begin(block->buf, BLKHDR_LENGTH);
269    unser_uint32(block->CheckSum);
270    unser_uint32(block_len);
271    unser_uint32(BlockNumber);
272    unser_bytes(Id, BLKHDR_ID_LENGTH);
273    ASSERT(unser_length(block->buf) == BLKHDR1_LENGTH);
274
275    Id[BLKHDR_ID_LENGTH] = 0;
276    if (Id[3] == '1') {
277       bhl = BLKHDR1_LENGTH;
278       block->BlockVer = 1;
279       block->bufp = block->buf + bhl;
280       //Dmsg3(100, "Block=%p buf=%p bufp=%p\n", block, block->buf, block->bufp);
281       if (strncmp(Id, BLKHDR1_ID, BLKHDR_ID_LENGTH) != 0) {
282          dev->dev_errno = EIO;
283          Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
284             dev->file, dev->block_num, BLKHDR1_ID, Id);
285          if (block->read_errors == 0 || verbose >= 2) {
286             Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
287          }
288          block->read_errors++;
289          return false;
290       }
291    } else if (Id[3] == '2') {
292       unser_uint32(block->VolSessionId);
293       unser_uint32(block->VolSessionTime);
294       bhl = BLKHDR2_LENGTH;
295       block->BlockVer = 2;
296       block->bufp = block->buf + bhl;
297       if (strncmp(Id, BLKHDR2_ID, BLKHDR_ID_LENGTH) != 0) {
298          dev->dev_errno = EIO;
299          Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
300             dev->file, dev->block_num, BLKHDR2_ID, Id);
301          if (block->read_errors == 0 || verbose >= 2) {
302             Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
303          }
304          block->read_errors++;
305          return false;
306       }
307    } else {
308       dev->dev_errno = EIO;
309       Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
310           dev->file, dev->block_num, BLKHDR2_ID, Id);
311       Dmsg1(50, "%s", dev->errmsg);
312       if (block->read_errors == 0 || verbose >= 2) {
313          Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
314       }
315       block->read_errors++;
316       unser_uint32(block->VolSessionId);
317       unser_uint32(block->VolSessionTime);
318       return false;
319    }
320
321    /* Sanity check */
322    if (block_len > MAX_BLOCK_LENGTH) {
323       dev->dev_errno = EIO;
324       Mmsg3(dev->errmsg,  _("Volume data error at %u:%u! Block length %u is insane (too large), probably due to a bad archive.\n"),
325          dev->file, dev->block_num, block_len);
326       if (block->read_errors == 0 || verbose >= 2) {
327          Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
328       }
329       block->read_errors++;
330       return false;
331    }
332
333    Dmsg1(390, "unser_block_header block_len=%d\n", block_len);
334    /* Find end of block or end of buffer whichever is smaller */
335    if (block_len > block->read_len) {
336       block_end = block->read_len;
337    } else {
338       block_end = block_len;
339    }
340    block->binbuf = block_end - bhl;
341    Dmsg2(200, "set block=%p binbuf=%d\n", block, block->binbuf);
342    block->block_len = block_len;
343    block->BlockNumber = BlockNumber;
344    Dmsg3(390, "Read binbuf = %d %d block_len=%d\n", block->binbuf,
345       bhl, block_len);
346    if (block_len <= block->read_len && dev->do_checksum()) {
347       BlockCheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
348                          block_len-BLKHDR_CS_LENGTH);
349       if (BlockCheckSum != block->CheckSum) {
350          dev->dev_errno = EIO;
351          Mmsg6(dev->errmsg, _("Volume data error at %u:%u!\n"
352             "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n"),
353             dev->file, dev->block_num, (unsigned)BlockNumber,
354             block_len, BlockCheckSum, block->CheckSum);
355          if (block->read_errors == 0 || verbose >= 2) {
356             Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
357             dump_block(block, "with checksum error");
358          }
359          block->read_errors++;
360          if (!forge_on) {
361             return false;
362          }
363       }
364    }
365    return true;
366 }
367
368 /*
369  * Calculate how many bytes to write and then clear to end
370  *  of block.
371  */
372 uint32_t get_len_and_clear_block(DEV_BLOCK *block, DEVICE *dev, uint32_t &pad)
373 {
374    uint32_t wlen;
375    /*
376     * Clear to the end of the buffer if it is not full,
377     *  and on tape devices, apply min and fixed blocking.
378     */
379    wlen = block->binbuf;
380    if (wlen != block->buf_len) {
381       Dmsg2(250, "binbuf=%d buf_len=%d\n", block->binbuf, block->buf_len);
382
383       /* Adjust write size to min/max for tapes only */
384       if (dev->is_tape()) {
385          /* check for fixed block size */
386          if (dev->min_block_size == dev->max_block_size) {
387             wlen = block->buf_len;    /* fixed block size already rounded */
388          /* Check for min block size */
389          } else if (wlen < dev->min_block_size) {
390             wlen =  ((dev->min_block_size + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
391          /* Ensure size is rounded */
392          } else {
393             wlen = ((wlen + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
394          }
395       }
396       ASSERT(wlen <= block->buf_len);
397       /* Clear from end of data to end of block */
398       if (wlen-block->binbuf > 0) {
399          memset(block->bufp, 0, wlen-block->binbuf); /* clear garbage */
400       }
401       pad = wlen - block->binbuf;        /* padding or zeros written */
402       Dmsg4(150, "Zero end blk: cleared=%d buf_len=%d wlen=%d binbuf=%d\n",
403          pad, block->buf_len, wlen, block->binbuf);
404    } else {
405       pad = 0;
406    }
407
408    return wlen;              /* bytes to write */
409 }
410
411 /*
412  * Determine if user defined volume size has been
413  *  reached, and if so, return true, otherwise
414  *  return false.
415  */
416 bool user_volume_size_reached(DCR *dcr, bool quiet)
417 {
418    bool hit_max1, hit_max2;
419    uint64_t size, max_size;
420    DEVICE *dev = dcr->dev;
421    char ed1[50];
422    bool rtn = false;
423
424    Enter(dbgel);
425    size = dev->VolCatInfo.VolCatBytes + dcr->block->binbuf;
426    /* Limit maximum Volume size to value specified by user */
427    hit_max1 = (dev->max_volume_size > 0) && (size >= dev->max_volume_size);
428    hit_max2 = (dev->VolCatInfo.VolCatMaxBytes > 0) &&
429        (size >= dev->VolCatInfo.VolCatMaxBytes);
430    if (hit_max1) {
431       max_size = dev->max_volume_size;
432    } else {
433       max_size = dev->VolCatInfo.VolCatMaxBytes;
434    }
435    if (hit_max1 || hit_max2) {
436       if (!quiet) {
437          Jmsg(dcr->jcr, M_INFO, 0, _("User defined maximum volume size %s will be exceeded on device %s.\n"
438             "   Marking Volume \"%s\" as Full.\n"),
439             edit_uint64_with_commas(max_size, ed1),  dev->print_name(),
440             dev->getVolCatName());
441       }
442       Dmsg4(100, "Maximum volume size %s exceeded Vol=%s device=%s.\n"
443          "Marking Volume \"%s\" as Full.\n",
444          edit_uint64_with_commas(max_size, ed1), dev->getVolCatName(),
445          dev->print_name(), dev->getVolCatName());
446       rtn = true;
447    }
448    Dmsg1(dbgel, "Return from user_volume_size_reached=%d\n", rtn);
449    Leave(dbgel);
450    return rtn;
451 }
452
453
454 void reread_last_block(DCR *dcr)
455 {
456 #define CHECK_LAST_BLOCK
457 #ifdef  CHECK_LAST_BLOCK
458    bool ok = true;
459    DEVICE *dev = dcr->dev;
460    JCR *jcr = dcr->jcr;
461    DEV_BLOCK *block = dcr->block;
462    /*
463     * If the device is a tape and it supports backspace record,
464     *   we backspace over one or two eof marks depending on
465     *   how many we just wrote, then over the last record,
466     *   then re-read it and verify that the block number is
467     *   correct.
468     */
469    if (dev->is_tape() && dev->has_cap(CAP_BSR)) {
470       /* Now back up over what we wrote and read the last block */
471       if (!dev->bsf(1)) {
472          berrno be;
473          ok = false;
474          Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"),
475               be.bstrerror(dev->dev_errno));
476       }
477       if (ok && dev->has_cap(CAP_TWOEOF) && !dev->bsf(1)) {
478          berrno be;
479          ok = false;
480          Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"),
481               be.bstrerror(dev->dev_errno));
482       }
483       /* Backspace over record */
484       if (ok && !dev->bsr(1)) {
485          berrno be;
486          ok = false;
487          Jmsg(jcr, M_ERROR, 0, _("Backspace record at EOT failed. ERR=%s\n"),
488               be.bstrerror(dev->dev_errno));
489          /*
490           *  On FreeBSD systems, if the user got here, it is likely that his/her
491           *    tape drive is "frozen".  The correct thing to do is a
492           *    rewind(), but if we do that, higher levels in cleaning up, will
493           *    most likely write the EOS record over the beginning of the
494           *    tape.  The rewind *is* done later in mount.c when another
495           *    tape is requested. Note, the clrerror() call in bsr()
496           *    calls ioctl(MTCERRSTAT), which *should* fix the problem.
497           */
498       }
499       if (ok) {
500          DEV_BLOCK *lblock = new_block(dev);
501          /* Note, this can destroy dev->errmsg */
502          dcr->block = lblock;
503          if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
504             Jmsg(jcr, M_ERROR, 0, _("Re-read last block at EOT failed. ERR=%s"),
505                  dev->errmsg);
506          } else {
507             /*
508              * If we wrote block and the block numbers don't agree
509              *  we have a possible problem.
510              */
511             if (lblock->BlockNumber != dev->LastBlock) {
512                 if (dev->LastBlock > (lblock->BlockNumber + 1)) {
513                    Jmsg(jcr, M_FATAL, 0, _(
514 "Re-read of last block: block numbers differ by more than one.\n"
515 "Probable tape misconfiguration and data loss. Read block=%u Want block=%u.\n"),
516                        lblock->BlockNumber, dev->LastBlock);
517                  } else {
518                    Jmsg(jcr, M_ERROR, 0, _(
519 "Re-read of last block OK, but block numbers differ. Read block=%u Want block=%u.\n"),
520                        lblock->BlockNumber, dev->LastBlock);
521                  }
522             } else {
523                Jmsg(jcr, M_INFO, 0, _("Re-read of last block succeeded.\n"));
524             }
525          }
526          free_block(lblock);
527          dcr->block = block;
528       }
529    }
530 #endif
531 }
532
533 /*
534  * If this routine is called, we do our bookkeeping and
535  *   then assure that the volume will not be written any
536  *   more.
537  */
538 bool terminate_writing_volume(DCR *dcr)
539 {
540    DEVICE *dev = dcr->dev;
541    bool ok = true;
542
543    Enter(dbgel);
544
545    if (dev->is_ateot()) {
546       return ok;          /* already been here return now */
547    }
548
549    /* Create a JobMedia record to indicated end of medium */
550    dev->VolCatInfo.VolCatFiles = dev->get_file();
551    if (!dir_create_jobmedia_record(dcr)) {
552       Dmsg0(50, "Error from create JobMedia\n");
553       dev->dev_errno = EIO;
554         Mmsg2(dev->errmsg, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
555             dev->getVolCatName(), dcr->jcr->Job);
556        Jmsg(dcr->jcr, M_FATAL, 0, "%s", dev->errmsg);
557        ok = false;
558    }
559    flush_jobmedia_queue(dcr->jcr);
560    dcr->block->write_failed = true;
561    if (dev->can_append() && !dev->weof(1)) {     /* end the tape */
562       dev->VolCatInfo.VolCatErrors++;
563       Jmsg(dcr->jcr, M_ERROR, 0, _("Error writing final EOF to tape. This Volume may not be readable.\n"
564            "%s"), dev->errmsg);
565       ok = false;
566       Dmsg0(50, "Error writing final EOF to volume.\n");
567    }
568    if (ok) {
569       ok = write_ansi_ibm_labels(dcr, ANSI_EOV_LABEL, dev->VolHdr.VolumeName);
570    }
571
572    Dmsg2(100, "Set VolCatStatus Full size=%lld vol=%s\n",
573       dev->VolCatInfo.VolCatBytes, dev->VolCatInfo.VolCatName);
574
575    /* If still in append mode mark volume Full */
576    if (bstrcmp(dev->VolCatInfo.VolCatStatus, "Append")) {
577       dev->setVolCatStatus("Full");
578    }
579
580    if (!dir_update_volume_info(dcr, false, true)) {
581       Mmsg(dev->errmsg, _("Error sending Volume info to Director.\n"));
582       ok = false;
583       Dmsg0(50, "Error updating volume info.\n");
584    }
585    Dmsg2(150, "dir_update_volume_info vol=%s to terminate writing -- %s\n",
586       dev->getVolCatName(), ok?"OK":"ERROR");
587
588    dev->notify_newvol_in_attached_dcrs(NULL);
589
590    /* Set new file/block parameters for current dcr */
591    set_new_file_parameters(dcr);
592
593    if (ok && dev->has_cap(CAP_TWOEOF) && dev->can_append() && !dev->weof(1)) {  /* end the tape */
594       dev->VolCatInfo.VolCatErrors++;
595       /* This may not be fatal since we already wrote an EOF */
596       Jmsg(dcr->jcr, M_ERROR, 0, "%s", dev->errmsg);
597       Dmsg0(50, "Writing second EOF failed.\n");
598    }
599
600    dev->set_ateot();                  /* no more writing this tape */
601    Dmsg2(150, "Leave terminate_writing_volume=%s -- %s\n",
602       dev->getVolCatName(), ok?"OK":"ERROR");
603    Leave(dbgel);
604    return ok;
605 }
606
607 /*
608  * If a new volume has been mounted since our last write
609  *   Create a JobMedia record for the previous volume written,
610  *   and set new parameters to write this volume
611  * The same applies for if we are in a new file.
612  */
613 bool check_for_newvol_or_newfile(DCR *dcr)
614 {
615    JCR *jcr = dcr->jcr;
616
617    if (dcr->NewVol || dcr->NewFile) {
618       if (job_canceled(jcr)) {
619          Dmsg0(100, "Canceled\n");
620          return false;
621       }
622       /* Create a jobmedia record for this job */
623       if (!dir_create_jobmedia_record(dcr)) {
624          dcr->dev->dev_errno = EIO;
625          Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
626             dcr->getVolCatName(), jcr->Job);
627          set_new_volume_parameters(dcr);
628          Dmsg0(100, "cannot create media record\n");
629          return false;
630       }
631       if (dcr->NewVol) {
632          flush_jobmedia_queue(jcr);
633          /* Note, setting a new volume also handles any pending new file */
634          set_new_volume_parameters(dcr);
635       } else {
636          set_new_file_parameters(dcr);
637       }
638    }
639    return true;
640 }
641
642 /*
643  * Do bookkeeping when a new file is created on a Volume. This is
644  *  also done for disk files to generate the jobmedia records for
645  *  quick seeking.
646  */
647 bool do_new_file_bookkeeping(DCR *dcr)
648 {
649    DEVICE *dev = dcr->dev;
650    JCR *jcr = dcr->jcr;
651
652    /* Create a JobMedia record so restore can seek */
653    if (!dir_create_jobmedia_record(dcr)) {
654       Dmsg0(40, "Error from create_job_media.\n");
655       dev->dev_errno = EIO;
656       Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
657            dcr->getVolCatName(), jcr->Job);
658       Dmsg0(40, "Call terminate_writing_volume\n");
659       terminate_writing_volume(dcr);
660       dev->dev_errno = EIO;
661       return false;
662    }
663    dev->VolCatInfo.VolCatFiles = dev->get_file();
664    if (!dir_update_volume_info(dcr, false, false)) {
665       Dmsg0(50, "Error from update_vol_info.\n");
666       Dmsg0(40, "Call terminate_writing_volume\n");
667       terminate_writing_volume(dcr);
668       dev->dev_errno = EIO;
669       return false;
670    }
671    Dmsg0(100, "dir_update_volume_info max file size -- OK\n");
672
673    dev->notify_newfile_in_attached_dcrs();
674
675    /* Set new file/block parameters for current dcr */
676    set_new_file_parameters(dcr);
677    return true;
678 }