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