From f22306c4aa11062bf4fad4eb09b7c88c045efe66 Mon Sep 17 00:00:00 2001 From: "V. Novy" Date: Sun, 19 Nov 2017 12:57:03 +0100 Subject: [PATCH] Apply patches from bugs #2325 and #2326 to fix FIFO bugs --- bacula/src/stored/block.c | 35 ++++++++++----- bacula/src/stored/label.c | 4 +- bacula/src/stored/read_records.c | 73 +++++++++++++++++--------------- 3 files changed, 67 insertions(+), 45 deletions(-) diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index 5134b953d9..a0f33705cd 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -447,6 +447,7 @@ bool DCR::read_block_from_dev(bool check_block_numbers) DCR *dcr = this; boffset_t pos; char ed1[50]; + int data_len; if (job_canceled(jcr)) { Mmsg(dev->errmsg, _("Job failed or canceled.\n")); @@ -512,19 +513,30 @@ reread: Dmsg2(200, "Pos for read=%s %lld\n", dev->print_addr(ed1, sizeof(ed1), pos), pos); } + + data_len = 0; + do { - if ((retry > 0 && stat == -1 && errno == EBUSY)) { - berrno be; - Dmsg4(100, "===== read retry=%d stat=%d errno=%d: ERR=%s\n", - retry, stat, errno, be.bstrerror()); - bmicrosleep(10, 0); /* pause a bit if busy or lots of errors */ - dev->clrerror(-1); - } - stat = dev->read(block->buf, (size_t)block->buf_len); + retry = 0; + + do { + if ((retry > 0 && stat == -1 && errno == EBUSY)) { + berrno be; + Dmsg4(100, "===== read retry=%d stat=%d errno=%d: ERR=%s\n", + retry, stat, errno, be.bstrerror()); + bmicrosleep(10, 0); /* pause a bit if busy or lots of errors */ + dev->clrerror(-1); + } + stat = dev->read(block->buf + data_len, (size_t)(block->buf_len - data_len)); + if (stat > 0) + data_len += stat; + + } while (stat == -1 && (errno == EBUSY || errno == EINTR || errno == EIO) && retry++ < 3); + + } while (data_len < block->buf_len && stat > 0 && dev->dev_type == B_FIFO_DEV); - } while (stat == -1 && (errno == EBUSY || errno == EINTR || errno == EIO) && retry++ < 3); Dmsg4(110, "Read() adata=%d vol=%s nbytes=%d pos=%lld\n", - block->adata, dev->VolHdr.VolumeName, stat, pos); + block->adata, dev->VolHdr.VolumeName, stat < 0 ? stat : data_len, pos); if (stat < 0) { berrno be; dev->clrerror(-1); @@ -547,6 +559,9 @@ reread: } return false; } + + stat = data_len; + if (stat == 0) { /* Got EOF ! */ pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */ pos = dev->get_full_addr(pos); diff --git a/bacula/src/stored/label.c b/bacula/src/stored/label.c index 6f41b7bb0f..236cc70067 100644 --- a/bacula/src/stored/label.c +++ b/bacula/src/stored/label.c @@ -279,7 +279,9 @@ int DEVICE::read_dev_volume_label(DCR *dcr) goto bail_out; } - empty_block(block); + if (dcr->is_writing()) { + empty_block(block); + } Leave(dbglvl); return VOL_OK; diff --git a/bacula/src/stored/read_records.c b/bacula/src/stored/read_records.c index 5b28576894..0e8f02ebe7 100644 --- a/bacula/src/stored/read_records.c +++ b/bacula/src/stored/read_records.c @@ -116,6 +116,7 @@ bool read_records(DCR *dcr, SESSION_LABEL sessrec; dlist *recs; /* linked list of rec packets open */ char ed1[50]; + bool first_block = true; recs = New(dlist(rec, &rec->link)); /* We go to the first_file unless we need to reposition during an @@ -131,44 +132,48 @@ bool read_records(DCR *dcr, } ASSERT2(!dcr->dev->adata, "Called with adata block. Wrong!"); - if (dev->at_eot() || !dcr->read_block_from_device(CHECK_BLOCK_NUMBERS)) { - if (dev->at_eot()) { - Jmsg(jcr, M_INFO, 0, - _("End of Volume \"%s\" at addr=%s on device %s.\n"), - dcr->VolumeName, - dev->print_addr(ed1, sizeof(ed1), dev->EndAddr), - dev->print_name()); - ok = mount_next_vol(jcr, dcr, jcr->bsr, &sessrec, &should_stop, - record_cb, mount_cb); - /* Might have changed after the mount request */ - dev = dcr->dev; - block = dcr->block; - if (should_stop) { - break; - } - continue; - } else if (dev->at_eof()) { - Dmsg3(200, "EOF at addr=%s on device %s, Volume \"%s\"\n", - dev->print_addr(ed1, sizeof(ed1), dev->EndAddr), - dev->print_name(), dcr->VolumeName); - continue; - } else if (dev->is_short_block()) { - Jmsg1(jcr, M_ERROR, 0, "%s", dev->errmsg); - continue; - } else { - /* I/O error or strange end of tape */ - display_tape_error_status(jcr, dev); - if (forge_on || jcr->ignore_label_errors) { - dev->fsr(1); /* try skipping bad record */ - Pmsg0(000, _("Did fsr in attemp to skip bad record.\n")); - continue; /* try to continue */ + if (! first_block || dev->dev_type != B_FIFO_DEV ) { + if (dev->at_eot() || !dcr->read_block_from_device(CHECK_BLOCK_NUMBERS)) { + if (dev->at_eot()) { + Jmsg(jcr, M_INFO, 0, + _("End of Volume \"%s\" at addr=%s on device %s.\n"), + dcr->VolumeName, + dev->print_addr(ed1, sizeof(ed1), dev->EndAddr), + dev->print_name()); + ok = mount_next_vol(jcr, dcr, jcr->bsr, &sessrec, &should_stop, + record_cb, mount_cb); + /* Might have changed after the mount request */ + dev = dcr->dev; + block = dcr->block; + if (should_stop) { + break; + } + continue; + + } else if (dev->at_eof()) { + Dmsg3(200, "EOF at addr=%s on device %s, Volume \"%s\"\n", + dev->print_addr(ed1, sizeof(ed1), dev->EndAddr), + dev->print_name(), dcr->VolumeName); + continue; + } else if (dev->is_short_block()) { + Jmsg1(jcr, M_ERROR, 0, "%s", dev->errmsg); + continue; + } else { + /* I/O error or strange end of tape */ + display_tape_error_status(jcr, dev); + if (forge_on || jcr->ignore_label_errors) { + dev->fsr(1); /* try skipping bad record */ + Pmsg0(000, _("Did fsr in attemp to skip bad record.\n")); + continue; /* try to continue */ + } + ok = false; /* stop everything */ + break; } - ok = false; /* stop everything */ - break; } + Dmsg1(dbglvl, "Read new block at pos=%s\n", dev->print_addr(ed1, sizeof(ed1))); } - Dmsg1(dbglvl, "Read new block at pos=%s\n", dev->print_addr(ed1, sizeof(ed1))); + first_block = false; #ifdef if_and_when_FAST_BLOCK_REJECTION_is_working /* this does not stop when file/block are too big */ if (!match_bsr_block(jcr->bsr, block)) { -- 2.39.5