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