1 /*
2    Bacula(R) - The Network Backup Solution
3 
4    Copyright (C) 2000-2020 Kern Sibbald
5 
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
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    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16 
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  *
21  *   block_util.c -- tape block utility functions
22  *
23  *              Kern Sibbald, split from block.c March MMXII
24  */
25 
26 
27 #include "bacula.h"
28 #include "stored.h"
29 
30 static const int dbglvl = 160;
31 
32 #ifdef DEBUG_BLOCK_CHECKSUM
33 static const bool debug_block_checksum = true;
34 #else
35 static const bool debug_block_checksum = false;
36 #endif
37 
38 #ifdef NO_TAPE_WRITE_TEST
39 static const bool no_tape_write_test = true;
40 #else
41 static const bool no_tape_write_test = false;
42 #endif
43 
44 /*
45  * Dump the block header, then walk through
46  * the block printing out the record headers.
47  */
dump_block(DEVICE * dev,DEV_BLOCK * b,const char * msg,bool force)48 void dump_block(DEVICE *dev, DEV_BLOCK *b, const char *msg, bool force)
49 {
50    ser_declare;
51    char *p;
52    char *bufp;
53    char Id[BLKHDR_ID_LENGTH+1];
54    uint32_t CheckSum, BlockCheckSum;
55    uint32_t block_len, reclen;
56    uint32_t BlockNumber;
57    uint32_t VolSessionId, VolSessionTime, data_len;
58    int32_t  FileIndex;
59    int32_t  Stream;
60    int bhl, rhl;
61    char buf1[100], buf2[100];
62 
63    if (!force && ((debug_level & ~DT_ALL) < 250)) {
64       return;
65    }
66    if (b->adata) {
67       Dmsg0(20, "Dump block: adata=1 cannot dump.\n");
68       return;
69    }
70    bufp = b->bufp;
71    if (dev) {
72       if (dev->can_read()) {
73          bufp = b->buf + b->block_len;
74       }
75    }
76    unser_begin(b->buf, BLKHDR1_LENGTH);
77    unser_uint32(CheckSum);
78    unser_uint32(block_len);
79    unser_uint32(BlockNumber);
80    unser_bytes(Id, BLKHDR_ID_LENGTH);
81    ASSERT(unser_length(b->buf) == BLKHDR1_LENGTH);
82    Id[BLKHDR_ID_LENGTH] = 0;
83    if (Id[3] == '2') {
84       unser_uint32(VolSessionId);
85       unser_uint32(VolSessionTime);
86       bhl = BLKHDR2_LENGTH;
87       rhl = RECHDR2_LENGTH;
88    } else {
89       VolSessionId = VolSessionTime = 0;
90       bhl = BLKHDR1_LENGTH;
91       rhl = RECHDR1_LENGTH;
92    }
93 
94    if (block_len > 4000000 || block_len < BLKHDR_CS_LENGTH) {
95       Dmsg3(20, "Will not dump blocksize too %s %lu msg: %s\n",
96             (block_len < BLKHDR_CS_LENGTH)?"small":"big",
97             block_len, msg);
98       return;
99    }
100 
101    BlockCheckSum = bcrc32((uint8_t *)b->buf+BLKHDR_CS_LENGTH,
102                          block_len-BLKHDR_CS_LENGTH);
103    Pmsg7(000, _("Dump block %s %p: adata=%d size=%d BlkNum=%d\n"
104 "                           Hdrcksum=%x cksum=%x\n"),
105       msg, b, b->adata, block_len, BlockNumber, CheckSum, BlockCheckSum);
106    p = b->buf + bhl;
107    while (p < bufp) {
108       unser_begin(p, WRITE_RECHDR_LENGTH);
109       if (rhl == RECHDR1_LENGTH) {
110          unser_uint32(VolSessionId);
111          unser_uint32(VolSessionTime);
112       }
113       unser_int32(FileIndex);
114       unser_int32(Stream);
115       unser_uint32(data_len);
116       if (Stream == STREAM_ADATA_BLOCK_HEADER) {
117          reclen = 0;
118          p += WRITE_ADATA_BLKHDR_LENGTH;
119       } else if (Stream == STREAM_ADATA_RECORD_HEADER ||
120                  Stream == -STREAM_ADATA_RECORD_HEADER) {
121          unser_uint32(reclen);
122          unser_int32(Stream);
123          p += WRITE_ADATA_RECHDR_LENGTH;
124          if (Stream & STREAM_BIT_OFFSETS) {
125             p += OFFSET_FADDR_SIZE;
126          }
127       } else {
128          reclen = 0;
129          p += data_len + rhl;
130       }
131       Pmsg6(000, _("   Rec: VId=%u VT=%u FI=%s Strm=%s len=%d reclen=%d\n"),
132            VolSessionId, VolSessionTime, FI_to_ascii(buf1, FileIndex),
133            stream_to_ascii(buf2, Stream, FileIndex), data_len, reclen);
134   }
135 }
136 
137 /*
138  * Create a new block structure.
139  * We pass device so that the block can inherit the
140  * min and max block sizes.
141  */
new_dcr_blocks(DCR * dcr)142 void DEVICE::new_dcr_blocks(DCR *dcr)
143 {
144    dcr->block = dcr->ameta_block = new_block(dcr);
145 }
146 
new_block(DCR * dcr,int size)147 DEV_BLOCK *DEVICE::new_block(DCR *dcr, int size)
148 {
149    DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK));
150    int len;
151 
152    memset(block, 0, sizeof(DEV_BLOCK));
153 
154    /* If the user has specified a max_block_size, use it as the default */
155    if (max_block_size == 0) {
156       len = DEFAULT_BLOCK_SIZE;
157    } else {
158       len = max_block_size;
159    }
160    block->dev = this;
161    /* special size */
162    if (size) {
163       len = size;
164    }
165    block->buf_len = len;
166    block->buf = get_memory(block->buf_len);
167    block->rechdr_queue = get_memory(block->buf_len);
168    block->rechdr_items = 0;
169    Dmsg2(510, "Rechdr len=%d max_items=%d\n", sizeof_pool_memory(block->rechdr_queue),
170       sizeof_pool_memory(block->rechdr_queue)/WRITE_ADATA_RECHDR_LENGTH);
171    block->filemedia = New(alist(1, owned_by_alist));
172    empty_block(block);
173    block->BlockVer = BLOCK_VER;       /* default write version */
174    Dmsg3(150, "New block adata=%d len=%d block=%p\n", block->adata, len, block);
175    return block;
176 }
177 
178 
179 /*
180  * Duplicate an existing block (eblock)
181  */
dup_block(DEV_BLOCK * eblock)182 DEV_BLOCK *dup_block(DEV_BLOCK *eblock)
183 {
184    DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK));
185    int buf_len = sizeof_pool_memory(eblock->buf);
186    int rechdr_len = sizeof_pool_memory(eblock->rechdr_queue);
187 
188    memcpy(block, eblock, sizeof(DEV_BLOCK));
189    block->buf = get_memory(buf_len);
190    memcpy(block->buf, eblock->buf, buf_len);
191 
192    block->rechdr_queue = get_memory(rechdr_len);
193    memcpy(block->rechdr_queue, eblock->rechdr_queue, rechdr_len);
194 
195    FILEMEDIA_ITEM *fm;
196    block->filemedia = New(alist(1, owned_by_alist));
197    foreach_alist(fm, eblock->filemedia) {
198       FILEMEDIA_ITEM *fm2 = (FILEMEDIA_ITEM *) malloc(sizeof(FILEMEDIA_ITEM));
199       memcpy(fm2, fm, sizeof(FILEMEDIA_ITEM));
200       block->filemedia->append(fm2);
201    }
202 
203 
204    /* bufp might point inside buf */
205    if (eblock->bufp &&
206        eblock->bufp >= eblock->buf &&
207        eblock->bufp < (eblock->buf + buf_len))
208    {
209       block->bufp = (eblock->bufp - eblock->buf) + block->buf;
210 
211    } else {
212       block->bufp = NULL;
213    }
214    return block;
215 }
216 
217 /*
218  * Flush block to disk
219  */
flush_block(DCR * dcr)220 bool DEVICE::flush_block(DCR *dcr)
221 {
222    if (!is_block_empty(dcr->block)) {
223       Dmsg0(dbglvl, "=== wpath 53 flush_ameta\n");
224       Dmsg4(190, "Call flush_ameta_block BlockAddr=%lld nbytes=%d adata=%d block=%x\n",
225          dcr->block->BlockAddr, dcr->block->binbuf, dcr->adata_block->adata, dcr->adata_block);
226       dump_block(dcr->dev, dcr->block, "Flush_ameta_block");
227       if (dcr->jcr->is_canceled() || !dcr->write_block_to_device()) {
228          Dmsg0(dbglvl, "=== wpath 54 flush_ameta\n");
229          Dmsg0(190, "Failed to write ameta block to device, return false.\n");
230          return false;
231       }
232       empty_block(dcr->block);
233    }
234    return true;
235 }
236 
237 
238 /*
239  * Only the first block checksum error was reported.
240  *   If there are more, report it now.
241  */
print_block_read_errors(JCR * jcr,DEV_BLOCK * block)242 void print_block_read_errors(JCR *jcr, DEV_BLOCK *block)
243 {
244    if (block->read_errors > 1) {
245       Jmsg(jcr, M_ERROR, 0, _("%d block read errors not printed.\n"),
246          block->read_errors);
247    }
248 }
249 
250 /* We had a problem on some solaris platforms with the CRC32 library, some
251  * 8.4.x jobs uses a bad crc32 algorithm. We just try one then the
252  * other to not create false problems
253  */
crc32(unsigned char * buf,int len,uint32_t expected_crc)254 uint32_t DCR::crc32(unsigned char *buf, int len, uint32_t expected_crc)
255 {
256 #if BEEF && defined(HAVE_SUN_OS) && defined(HAVE_LITTLE_ENDIAN)
257    uint32_t crc = 0;
258    if (crc32_type) {
259       crc = bcrc32_bad(buf, len);
260 
261    } else {
262       crc = bcrc32(buf, len);
263    }
264    if (expected_crc != crc) {
265       crc32_type = !crc32_type; /* Next time, do it well right away */
266 
267       if (crc32_type) {
268          crc = bcrc32_bad(buf, len);
269 
270       } else {
271          crc = bcrc32(buf, len);
272       }
273    }
274    return crc;
275 #else
276    return bcrc32(buf, len);
277 #endif
278 }
279 
free_dcr_blocks(DCR * dcr)280 void DEVICE::free_dcr_blocks(DCR *dcr)
281 {
282    if (dcr->block == dcr->ameta_block) {
283       dcr->ameta_block = NULL;      /* do not free twice */
284    }
285    free_block(dcr->block);
286    dcr->block = NULL;
287    free_block(dcr->ameta_block);
288    dcr->ameta_block = NULL;
289 }
290 
291 /*
292  * Free block
293  */
free_block(DEV_BLOCK * block)294 void free_block(DEV_BLOCK *block)
295 {
296    if (block) {
297       Dmsg1(999, "free_block buffer=%p\n", block->buf);
298       if (block->buf) {
299          free_memory(block->buf);
300       }
301       if (block->rechdr_queue) {
302          free_memory(block->rechdr_queue);
303       }
304       delete block->filemedia;
305       Dmsg1(999, "=== free_block block %p\n", block);
306       free_memory((POOLMEM *)block);
307    }
308 }
309 
is_block_empty(DEV_BLOCK * block)310 bool is_block_empty(DEV_BLOCK *block)
311 {
312    if (block->adata) {
313       Dmsg1(200, "=== adata=1 binbuf=%d\n", block->binbuf);
314       return block->binbuf <= 0;
315    } else {
316       Dmsg1(200, "=== adata=0 binbuf=%d\n", block->binbuf-WRITE_BLKHDR_LENGTH);
317       return block->binbuf <= WRITE_BLKHDR_LENGTH;
318    }
319 }
320 
321 /* Empty the block -- for writing */
empty_block(DEV_BLOCK * block)322 void empty_block(DEV_BLOCK *block)
323 {
324    if (block->adata) {
325       block->binbuf = 0;
326    } else {
327       block->binbuf = WRITE_BLKHDR_LENGTH;
328    }
329    Dmsg3(250, "empty_block: adata=%d len=%d set binbuf=%d\n",
330          block->adata, block->buf_len, block->binbuf);
331    block->bufp = block->buf + block->binbuf;
332    block->read_len = 0;
333    block->write_failed = false;
334    block->block_read = false;
335    block->needs_write = false;
336    block->FirstIndex = block->LastIndex = 0;
337    block->RecNum = 0;
338    block->BlockAddr = 0;
339    block->filemedia->destroy();
340    block->extra_bytes = 0;
341 }
342 
343 /*
344  * Create block header just before write. The space
345  * in the buffer should have already been reserved by
346  * init_block.
347  */
ser_block_header(DEV_BLOCK * block,bool do_checksum)348 uint32_t ser_block_header(DEV_BLOCK *block, bool do_checksum)
349 {
350    ser_declare;
351    uint32_t block_len = block->binbuf;
352 
353    block->CheckSum = 0;
354    /* ***BEEF*** */
355    if (block->adata) {
356       /* Checksum whole block */
357       if (do_checksum) {
358          block->CheckSum = bcrc32((uint8_t *)block->buf, block_len);
359       }
360    } else {
361       Dmsg1(160, "block_header: block_len=%d\n", block_len);
362       ser_begin(block->buf, BLKHDR2_LENGTH);
363       ser_uint32(block->CheckSum);
364       ser_uint32(block_len);
365       ser_uint32(block->BlockNumber);
366       ser_bytes(WRITE_BLKHDR_ID, BLKHDR_ID_LENGTH);
367       if (BLOCK_VER >= 2) {
368          ser_uint32(block->VolSessionId);
369          ser_uint32(block->VolSessionTime);
370       }
371 
372       /* Checksum whole block except for the checksum */
373       if (do_checksum) {
374          block->CheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
375                        block_len-BLKHDR_CS_LENGTH);
376       }
377       Dmsg2(160, "ser_block_header: adata=%d checksum=%x\n", block->adata, block->CheckSum);
378       ser_begin(block->buf, BLKHDR2_LENGTH);
379       ser_uint32(block->CheckSum);    /* now add checksum to block header */
380    }
381    return block->CheckSum;
382 }
383 
384 /*
385  * Unserialize the block header for reading block.
386  *  This includes setting all the buffer pointers correctly.
387  *
388  *  Returns: false on failure (not a block)
389  *           true  on success
390  */
unser_block_header(DCR * dcr,DEVICE * dev,DEV_BLOCK * block)391 bool unser_block_header(DCR *dcr, DEVICE *dev, DEV_BLOCK *block)
392 {
393    ser_declare;
394    char Id[BLKHDR_ID_LENGTH+1];
395    uint32_t BlockCheckSum;
396    uint32_t block_len;
397    uint32_t block_end;
398    uint32_t BlockNumber;
399    JCR *jcr = dcr->jcr;
400    int bhl;
401 
402    if (block->adata) {
403       /* Checksum the whole block */
404       if (block->block_len <= block->read_len && dev->do_checksum()) {
405          BlockCheckSum = dcr->crc32((uint8_t *)block->buf, block->block_len, block->CheckSum);
406          if (BlockCheckSum != block->CheckSum) {
407             dev->dev_errno = EIO;
408             Mmsg5(dev->errmsg, _("Volume data error at %lld!\n"
409                "Adata block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n"),
410                block->BlockAddr, block->BlockNumber,
411                block->block_len, BlockCheckSum, block->CheckSum);
412             if (block->read_errors == 0 || verbose >= 2) {
413                Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
414                dump_block(dev, block, "with checksum error");
415             }
416             block->read_errors++;
417             if (!forge_on) {
418                return false;
419             }
420          }
421       }
422       return true;
423    }
424 
425    if (block->no_header) {
426       return true;
427    }
428    unser_begin(block->buf, BLKHDR_LENGTH);
429    unser_uint32(block->CheckSum);
430    unser_uint32(block_len);
431    unser_uint32(BlockNumber);
432    unser_bytes(Id, BLKHDR_ID_LENGTH);
433    ASSERT(unser_length(block->buf) == BLKHDR1_LENGTH);
434    Id[BLKHDR_ID_LENGTH] = 0;
435 
436    if (Id[3] == '1') {
437       bhl = BLKHDR1_LENGTH;
438       block->BlockVer = 1;
439       block->bufp = block->buf + bhl;
440       //Dmsg3(100, "Block=%p buf=%p bufp=%p\n", block, block->buf, block->bufp);
441       if (strncmp(Id, BLKHDR1_ID, BLKHDR_ID_LENGTH) != 0) {
442          dev->dev_errno = EIO;
443          Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
444                dev->get_hi_addr(block->BlockAddr),
445                dev->get_low_addr(block->BlockAddr),
446                BLKHDR1_ID, Id);
447          if (block->read_errors == 0 || verbose >= 2) {
448             Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
449          }
450          block->read_errors++;
451          return false;
452       }
453    } else if (Id[3] == '2') {
454       unser_uint32(block->VolSessionId);
455       unser_uint32(block->VolSessionTime);
456       bhl = BLKHDR2_LENGTH;
457       block->BlockVer = 2;
458       block->bufp = block->buf + bhl;
459       //Dmsg5(100, "Read-blkhdr Block=%p adata=%d buf=%p bufp=%p off=%d\n", block, block->adata,
460       //   block->buf, block->bufp, block->bufp-block->buf);
461       if (strncmp(Id, BLKHDR2_ID, BLKHDR_ID_LENGTH) != 0) {
462          dev->dev_errno = EIO;
463          Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
464                dev->get_hi_addr(block->BlockAddr),
465                dev->get_low_addr(block->BlockAddr),
466                BLKHDR2_ID, Id);
467          if (block->read_errors == 0 || verbose >= 2) {
468             Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
469          }
470          block->read_errors++;
471          return false;
472       }
473    } else {
474       dev->dev_errno = EIO;
475       Mmsg4(dev->errmsg, _("Volume data error at %d:%d! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
476             dev->get_hi_addr(block->BlockAddr),
477             dev->get_low_addr(block->BlockAddr),
478             BLKHDR2_ID, Id);
479       Dmsg1(50, "%s", dev->errmsg);
480       if (block->read_errors == 0 || verbose >= 2) {
481          Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg);
482       }
483       block->read_errors++;
484       unser_uint32(block->VolSessionId);
485       unser_uint32(block->VolSessionTime);
486       return false;
487    }
488 
489    /* Sanity check */
490    if (block_len > MAX_BLOCK_LENGTH) {
491       dev->dev_errno = EIO;
492       Mmsg3(dev->errmsg,  _("Volume data error at %u:%u! Block length %u is insane (too large), probably due to a bad archive.\n"),
493          dev->file, dev->block_num, block_len);
494       if (block->read_errors == 0 || verbose >= 2) {
495          Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
496       }
497       block->read_errors++;
498       return false;
499    }
500 
501    Dmsg1(390, "unser_block_header block_len=%d\n", block_len);
502    /* Find end of block or end of buffer whichever is smaller */
503    if (block_len > block->read_len) {
504       block_end = block->read_len;
505    } else {
506       block_end = block_len;
507    }
508    block->binbuf = block_end - bhl;
509    Dmsg3(200, "set block=%p adata=%d binbuf=%d\n", block, block->adata, block->binbuf);
510    block->block_len = block_len;
511    block->BlockNumber = BlockNumber;
512    Dmsg3(390, "Read binbuf = %d %d block_len=%d\n", block->binbuf,
513       bhl, block_len);
514    if (block_len <= block->read_len && dev->do_checksum()) {
515       BlockCheckSum = dcr->crc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
516                                  block_len-BLKHDR_CS_LENGTH,
517                                  block->CheckSum);
518 
519       if (BlockCheckSum != block->CheckSum) {
520          dev->dev_errno = EIO;
521          Mmsg6(dev->errmsg, _("Volume data error at %u:%u!\n"
522             "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n"),
523             dev->file, dev->block_num, (unsigned)BlockNumber,
524             block_len, BlockCheckSum, block->CheckSum);
525          if (block->read_errors == 0 || verbose >= 2) {
526             Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
527             dump_block(dev, block, "with checksum error");
528          }
529          block->read_errors++;
530          if (!forge_on) {
531             return false;
532          }
533       }
534    }
535    return true;
536 }
537 
538 /*
539  * Calculate how many bytes to write and then clear to end
540  *  of block.
541  */
get_len_and_clear_block(DEV_BLOCK * block,DEVICE * dev,uint32_t & pad)542 uint32_t get_len_and_clear_block(DEV_BLOCK *block, DEVICE *dev, uint32_t &pad)
543 {
544    uint32_t wlen;
545    /*
546     * Clear to the end of the buffer if it is not full,
547     *  and on tape devices, apply min and fixed blocking.
548     */
549    wlen = block->binbuf;
550    if (wlen != block->buf_len) {
551       Dmsg2(250, "binbuf=%d buf_len=%d\n", block->binbuf, block->buf_len);
552 
553       /* Adjust write size to min/max for tapes and aligned only */
554       if (dev->is_tape() || block->adata) {
555          /* check for fixed block size */
556          if (dev->min_block_size == dev->max_block_size) {
557             wlen = block->buf_len;    /* fixed block size already rounded */
558          /* Check for min block size */
559          } else if (wlen < dev->min_block_size) {
560             wlen =  ((dev->min_block_size + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
561          /* Ensure size is rounded */
562          } else {
563             wlen = ((wlen + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE;
564          }
565       }
566       if (block->adata && dev->padding_size > 0) {
567          /* Write to next aligned boundry */
568          wlen = ((wlen + dev->padding_size - 1) / dev->padding_size) * dev->padding_size;
569       }
570       ASSERT(wlen <= block->buf_len);
571       /* Clear from end of data to end of block */
572       if (wlen-block->binbuf > 0) {
573          memset(block->bufp, 0, wlen-block->binbuf); /* clear garbage */
574       }
575       pad = wlen - block->binbuf;        /* padding or zeros written */
576       Dmsg5(150, "Zero end blk: adata=%d cleared=%d buf_len=%d wlen=%d binbuf=%d\n",
577          block->adata, pad, block->buf_len, wlen, block->binbuf);
578    } else {
579       pad = 0;
580    }
581 
582    return wlen;              /* bytes to write */
583 }
584 
585 /*
586  * Determine if user defined volume size has been
587  *  reached, and if so, return true, otherwise
588  *  return false.
589  */
is_user_volume_size_reached(DCR * dcr,bool quiet)590 bool is_user_volume_size_reached(DCR *dcr, bool quiet)
591 {
592    bool hit_max1, hit_max2;
593    uint64_t size, max_size;
594    DEVICE *dev = dcr->ameta_dev;
595    char ed1[50];
596    bool rtn = false;
597 
598    Enter(dbglvl);
599    if (dev->is_aligned()) {
600       /* Note, we reserve space for one ameta and one adata block */
601       size = dev->VolCatInfo.VolCatBytes + dcr->ameta_block->buf_len +
602          dcr->adata_block->buf_len;
603    } else {
604       size = dev->VolCatInfo.VolCatBytes + dcr->ameta_block->binbuf;
605    }
606    /* Limit maximum Volume size to value specified by user */
607    hit_max1 = (dev->max_volume_size > 0) && (size >= dev->max_volume_size);
608    hit_max2 = (dev->VolCatInfo.VolCatMaxBytes > 0) &&
609        (size >= dev->VolCatInfo.VolCatMaxBytes);
610    if (hit_max1) {
611       max_size = dev->max_volume_size;
612    } else {
613       max_size = dev->VolCatInfo.VolCatMaxBytes;
614    }
615    if (hit_max1 || hit_max2) {
616       if (!quiet) {
617          Jmsg(dcr->jcr, M_INFO, 0, _("User defined maximum volume size %s will be exceeded on device %s.\n"
618             "   Marking Volume \"%s\" as Full.\n"),
619             edit_uint64_with_commas(max_size, ed1),  dev->print_name(),
620             dev->getVolCatName());
621       }
622       Dmsg4(100, "Maximum volume size %s exceeded Vol=%s device=%s.\n"
623          "Marking Volume \"%s\" as Full.\n",
624          edit_uint64_with_commas(max_size, ed1), dev->getVolCatName(),
625          dev->print_name(), dev->getVolCatName());
626       rtn = true;
627 
628    } else if (is_pool_size_reached(dcr, quiet)) {
629       rtn = true;
630    }
631    Dmsg1(dbglvl, "Return from is_user_volume_size_reached=%d\n", rtn);
632    Leave(dbglvl);
633    return rtn;
634 }
635 
636 
reread_last_block(DCR * dcr)637 void reread_last_block(DCR *dcr)
638 {
639 #define CHECK_LAST_BLOCK
640 #ifdef  CHECK_LAST_BLOCK
641    bool ok = true;
642    DEVICE *dev = dcr->dev;
643    JCR *jcr = dcr->jcr;
644    DEV_BLOCK *ameta_block = dcr->ameta_block;
645    DEV_BLOCK *adata_block = dcr->adata_block;
646    DEV_BLOCK *block = dcr->block;
647    /*
648     * If the device is a tape and it supports backspace record,
649     *   we backspace over one or two eof marks depending on
650     *   how many we just wrote, then over the last record,
651     *   then re-read it and verify that the block number is
652     *   correct.
653     */
654    if (dev->is_tape() && dev->has_cap(CAP_BSR)) {
655       /* Now back up over what we wrote and read the last block */
656       if (!dev->bsf(1)) {
657          berrno be;
658          ok = false;
659          Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"),
660               be.bstrerror(dev->dev_errno));
661       }
662       if (ok && dev->has_cap(CAP_TWOEOF) && !dev->bsf(1)) {
663          berrno be;
664          ok = false;
665          Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"),
666               be.bstrerror(dev->dev_errno));
667       }
668       /* Backspace over record */
669       if (ok && !dev->bsr(1)) {
670          berrno be;
671          ok = false;
672          Jmsg(jcr, M_ERROR, 0, _("Backspace record at EOT failed. ERR=%s\n"),
673               be.bstrerror(dev->dev_errno));
674          /*
675           *  On FreeBSD systems, if the user got here, it is likely that his/her
676           *    tape drive is "frozen".  The correct thing to do is a
677           *    rewind(), but if we do that, higher levels in cleaning up, will
678           *    most likely write the EOS record over the beginning of the
679           *    tape.  The rewind *is* done later in mount.c when another
680           *    tape is requested. Note, the clrerror() call in bsr()
681           *    calls ioctl(MTCERRSTAT), which *should* fix the problem.
682           */
683       }
684       if (ok) {
685          dev->new_dcr_blocks(dcr);
686          /* Note, this can destroy dev->errmsg */
687          if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
688             Jmsg(jcr, M_ERROR, 0, _("Re-read last block at EOT failed. ERR=%s"),
689                  dev->errmsg);
690          } else {
691             /*
692              * If we wrote block and the block numbers don't agree
693              *  we have a possible problem.
694              */
695             if (dcr->block->BlockNumber != dev->LastBlock) {
696                 if (dev->LastBlock > (dcr->block->BlockNumber + 1)) {
697                    Jmsg(jcr, M_FATAL, 0, _(
698 "Re-read of last block: block numbers differ by more than one.\n"
699 "Probable tape misconfiguration and data loss. Read block=%u Want block=%u.\n"),
700                        dcr->block->BlockNumber, dev->LastBlock);
701                  } else {
702                    Jmsg(jcr, M_ERROR, 0, _(
703 "Re-read of last block OK, but block numbers differ. Read block=%u Want block=%u.\n"),
704                        dcr->block->BlockNumber, dev->LastBlock);
705                  }
706             } else {
707                Jmsg(jcr, M_INFO, 0, _("Re-read of last block succeeded.\n"));
708             }
709          }
710          dev->free_dcr_blocks(dcr);
711          dcr->ameta_block = ameta_block;
712          dcr->block = block;
713          dcr->adata_block = adata_block;
714       }
715    }
716 #endif
717 }
718 
719 /*
720  * If this routine is called, we do our bookkeeping and
721  *   then assure that the volume will not be written any
722  *   more.
723  */
terminate_writing_volume(DCR * dcr)724 bool terminate_writing_volume(DCR *dcr)
725 {
726    DEVICE *dev = dcr->dev;
727    bool ok = true;
728    bool was_adata = false;
729 
730    Enter(dbglvl);
731 
732    if (dev->is_ateot()) {
733       return ok;          /* already been here return now */
734    }
735 
736    /* Work with ameta device */
737    if (dev->adata) {
738       dev->set_ateot();       /* no more writing this Volume */
739       dcr->adata_block->write_failed = true;
740       dcr->set_ameta();
741       dev = dcr->ameta_dev;
742       was_adata = true;
743    }
744 
745    /* Create a JobMedia record to indicated end of medium */
746    dev->VolCatInfo.VolCatFiles = dev->get_file();
747    dev->VolCatInfo.VolLastPartBytes = dev->part_size;
748    dev->VolCatInfo.VolCatParts = dev->part;
749    if (!dir_create_jobmedia_record(dcr)) {
750       Dmsg0(50, "Error from create JobMedia\n");
751       dev->dev_errno = EIO;
752         Mmsg2(dev->errmsg, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
753             dev->getVolCatName(), dcr->jcr->Job);
754        Jmsg(dcr->jcr, M_FATAL, 0, "%s", dev->errmsg);
755        ok = false;
756    }
757    flush_jobmedia_queue(dcr->jcr);
758    bstrncpy(dev->LoadedVolName, dev->VolCatInfo.VolCatName, sizeof(dev->LoadedVolName));
759    dcr->block->write_failed = true;
760    if (dev->can_append() && !dev->weof(dcr, 1)) {     /* end the tape */
761       dev->VolCatInfo.VolCatErrors++;
762       Jmsg(dcr->jcr, M_ERROR, 0, _("Error writing final EOF to tape. Volume %s may not be readable.\n"
763            "%s"), dev->VolCatInfo.VolCatName, dev->errmsg);
764       ok = false;
765       Dmsg0(50, "Error writing final EOF to volume.\n");
766    }
767    if (ok) {
768       ok = dev->end_of_volume(dcr);
769    }
770 
771    Dmsg3(100, "Set VolCatStatus Full adata=%d size=%lld vol=%s\n", dev->adata,
772       dev->VolCatInfo.VolCatBytes, dev->VolCatInfo.VolCatName);
773 
774    /* If still in append mode mark volume Full */
775    if (bstrcmp(dev->VolCatInfo.VolCatStatus, "Append")) {
776       dev->setVolCatStatus("Full");
777    }
778 
779    if (!dir_update_volume_info(dcr, false, true)) {
780       Mmsg(dev->errmsg, _("Error sending Volume info to Director.\n"));
781       ok = false;
782       Dmsg0(50, "Error updating volume info.\n");
783    }
784    Dmsg2(150, "dir_update_volume_info vol=%s to terminate writing -- %s\n",
785       dev->getVolCatName(), ok?"OK":"ERROR");
786 
787    dev->notify_newvol_in_attached_dcrs(NULL);
788 
789    /* Set new file/block parameters for current dcr */
790    set_new_file_parameters(dcr);
791 
792    if (ok && dev->has_cap(CAP_TWOEOF) && dev->can_append() && !dev->weof(dcr, 1)) {  /* end the tape */
793       dev->VolCatInfo.VolCatErrors++;
794       /* This may not be fatal since we already wrote an EOF */
795       if (dev->errmsg[0]) {
796          Jmsg(dcr->jcr, M_ERROR, 0, "%s", dev->errmsg);
797       }
798       Dmsg0(50, "Writing second EOF failed.\n");
799    }
800 
801    dev->set_ateot();                  /* no more writing this tape */
802    Dmsg2(150, "Leave terminate_writing_volume=%s -- %s\n",
803       dev->getVolCatName(), ok?"OK":"ERROR");
804    if (was_adata) {
805       dcr->set_adata();
806    }
807    Leave(dbglvl);
808    return ok;
809 }
810 
811 /*
812  * If a new volume has been mounted since our last write
813  *   Create a JobMedia record for the previous volume written,
814  *   and set new parameters to write this volume
815  * The same applies for if we are in a new file.
816  */
check_for_newvol_or_newfile(DCR * dcr)817 bool check_for_newvol_or_newfile(DCR *dcr)
818 {
819    JCR *jcr = dcr->jcr;
820 
821    if (dcr->NewVol || dcr->NewFile) {
822       if (job_canceled(jcr)) {
823          Dmsg0(100, "Canceled\n");
824          return false;
825       }
826       /* If we wrote on Volume create a last jobmedia record for this job */
827       if (!dcr->VolFirstIndex) {
828          Dmsg7(100, "Skip JobMedia Vol=%s wrote=%d MediaId=%lld FI=%lu LI=%lu StartAddr=%lld EndAddr=%lld\n",
829             dcr->VolumeName, dcr->WroteVol, dcr->VolMediaId,
830             dcr->VolFirstIndex, dcr->VolLastIndex, dcr->StartAddr, dcr->EndAddr);
831       }
832       if (dcr->VolFirstIndex && !dir_create_jobmedia_record(dcr)) {
833          dcr->dev->dev_errno = EIO;
834          Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
835             dcr->getVolCatName(), jcr->Job);
836          set_new_volume_parameters(dcr);
837          Dmsg0(100, "cannot create media record\n");
838          return false;
839       }
840       if (dcr->NewVol) {
841          Dmsg0(250, "Process NewVol\n");
842          flush_jobmedia_queue(jcr);
843          /* Note, setting a new volume also handles any pending new file */
844          set_new_volume_parameters(dcr);
845       } else {
846          set_new_file_parameters(dcr);
847       }
848    }
849    return true;
850 }
851 
852 /*
853  * Do bookkeeping when a new file is created on a Volume. This is
854  *  also done for disk files to generate the jobmedia records for
855  *  quick seeking.
856  */
do_new_file_bookkeeping(DCR * dcr)857 bool do_new_file_bookkeeping(DCR *dcr)
858 {
859    DEVICE *dev = dcr->dev;
860    JCR *jcr = dcr->jcr;
861 
862    /* Create a JobMedia record so restore can seek */
863    if (!dir_create_jobmedia_record(dcr)) {
864       Dmsg0(40, "Error from create_job_media.\n");
865       dev->dev_errno = EIO;
866       Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
867            dcr->getVolCatName(), jcr->Job);
868       Dmsg0(40, "Call terminate_writing_volume\n");
869       terminate_writing_volume(dcr);
870       dev->dev_errno = EIO;
871       return false;
872    }
873    dev->VolCatInfo.VolCatFiles = dev->get_file();
874    dev->VolCatInfo.VolLastPartBytes = dev->part_size;
875    dev->VolCatInfo.VolCatParts = dev->part;
876    if (!dir_update_volume_info(dcr, false, false)) {
877       Dmsg0(50, "Error from update_vol_info.\n");
878       Dmsg0(40, "Call terminate_writing_volume\n");
879       terminate_writing_volume(dcr);
880       dev->dev_errno = EIO;
881       return false;
882    }
883    Dmsg0(100, "dir_update_volume_info max file size -- OK\n");
884 
885    dev->notify_newfile_in_attached_dcrs();
886 
887    /* Set new file/block parameters for current dcr */
888    set_new_file_parameters(dcr);
889    return true;
890 }
891