static bool write_spool_header(DCR *dcr) { spool_hdr hdr; ssize_t status; DEV_BLOCK *block = dcr->block; JCR *jcr = dcr->jcr; hdr.FirstIndex = block->FirstIndex; hdr.LastIndex = block->LastIndex; hdr.len = block->binbuf; /* Write header */ for (int retry = 0; retry <= 1; retry++) { status = write(dcr->spool_fd, (char*)&hdr, sizeof(hdr)); if (status == -1) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Error writing header to spool file. ERR=%s\n"), be.bstrerror()); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ } if (status != (ssize_t)sizeof(hdr)) { Jmsg(jcr, M_ERROR, 0, _("Error writing header to spool file." " Disk probably full. Attempting recovery. Wanted to write=%d got=%d\n"), (int)status, (int)sizeof(hdr)); /* If we wrote something, truncate it, then despool */ if (status != -1) { #if defined(HAVE_WIN32) boffset_t pos = _lseeki64(dcr->spool_fd, (__int64)0, SEEK_CUR); #else boffset_t pos = lseek(dcr->spool_fd, 0, SEEK_CUR); #endif if (ftruncate(dcr->spool_fd, pos - status) != 0) { berrno be; Jmsg(dcr->jcr, M_ERROR, 0, _("Ftruncate spool file failed: ERR=%s\n"), be.bstrerror()); /* Note, try continuing despite ftruncate problem */ } } if (!despool_data(dcr, false)) { Jmsg(jcr, M_FATAL, 0, _("Fatal despooling error.")); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ return false; } continue; /* try again */ } return true; } Jmsg(jcr, M_FATAL, 0, _("Retrying after header spooling error failed.\n")); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ return false; }
static bool write_spool_data(DCR *dcr) { ssize_t status; DEV_BLOCK *block = dcr->block; JCR *jcr = dcr->jcr; /* Write data */ for (int retry = 0; retry <= 1; retry++) { status = write(dcr->spool_fd, block->buf, (size_t)block->binbuf); if (status == -1) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Error writing data to spool file. ERR=%s\n"), be.bstrerror()); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ } if (status != (ssize_t)block->binbuf) { /* * If we wrote something, truncate it and the header, then despool */ if (status != -1) { #if defined(HAVE_WIN32) boffset_t pos = _lseeki64(dcr->spool_fd, (__int64)0, SEEK_CUR); #else boffset_t pos = lseek(dcr->spool_fd, 0, SEEK_CUR); #endif if (ftruncate(dcr->spool_fd, pos - status - sizeof(spool_hdr)) != 0) { berrno be; Jmsg(dcr->jcr, M_ERROR, 0, _("Ftruncate spool file failed: ERR=%s\n"), be.bstrerror()); /* Note, try continuing despite ftruncate problem */ } } if (!despool_data(dcr, false)) { Jmsg(jcr, M_FATAL, 0, _("Fatal despooling error.")); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ return false; } if (!write_spool_header(dcr)) { return false; } continue; /* try again */ } return true; } Jmsg(jcr, M_FATAL, 0, _("Retrying after data spooling error failed.\n")); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ return false; }
bool commit_data_spool(DCR *dcr) { bool status; if (dcr->spooling) { Dmsg0(100, "Committing spooled data\n"); status = despool_data(dcr, true /*commit*/); if (!status) { Dmsg1(100, _("Bad return from despool WroteVol=%d\n"), dcr->WroteVol); close_data_spool_file(dcr); return false; } return close_data_spool_file(dcr); } return true; }
static bool write_spool_header(DCR *dcr) { spool_hdr hdr; ssize_t stat; DEV_BLOCK *block = dcr->block; hdr.FirstIndex = block->FirstIndex; hdr.LastIndex = block->LastIndex; hdr.len = block->binbuf; /* Write header */ for (int retry=0; retry<=1; retry++) { stat = write(dcr->spool_fd, (char*)&hdr, sizeof(hdr)); if (stat == -1) { berrno be; Jmsg(dcr->jcr, M_FATAL, 0, _("Error writing header to spool file. ERR=%s\n"), be.bstrerror()); } if (stat != (ssize_t)sizeof(hdr)) { /* If we wrote something, truncate it, then despool */ if (stat != -1) { #if defined(HAVE_WIN32) boffset_t pos = _lseeki64(dcr->spool_fd, (__int64)0, SEEK_CUR); #else boffset_t pos = lseek(dcr->spool_fd, 0, SEEK_CUR); #endif if (ftruncate(dcr->spool_fd, pos - stat) != 0) { berrno be; Jmsg(dcr->jcr, M_ERROR, 0, _("Ftruncate spool file failed: ERR=%s\n"), be.bstrerror()); /* Note, try continuing despite ftruncate problem */ } } if (!despool_data(dcr, false)) { Jmsg(dcr->jcr, M_FATAL, 0, _("Fatal despooling error.")); return false; } continue; /* try again */ } return true; } Jmsg(dcr->jcr, M_FATAL, 0, _("Retrying after header spooling error failed.\n")); return false; }
/* * Write a block to the spool file * * Returns: true on success or EOT * false on hard error */ bool write_block_to_spool_file(DCR *dcr) { uint32_t wlen, hlen; /* length to write */ bool despool = false; DEV_BLOCK *block = dcr->block; if (job_canceled(dcr->jcr)) { return false; } ASSERT(block->binbuf == ((uint32_t) (block->bufp - block->buf))); if (block->binbuf <= WRITE_BLKHDR_LENGTH) { /* Does block have data in it? */ return true; } hlen = sizeof(spool_hdr); wlen = block->binbuf; P(dcr->dev->spool_mutex); dcr->job_spool_size += hlen + wlen; dcr->dev->spool_size += hlen + wlen; if ((dcr->max_job_spool_size > 0 && dcr->job_spool_size >= dcr->max_job_spool_size) || (dcr->dev->max_spool_size > 0 && dcr->dev->spool_size >= dcr->dev->max_spool_size)) { despool = true; } V(dcr->dev->spool_mutex); P(mutex); spool_stats.data_size += hlen + wlen; if (spool_stats.data_size > spool_stats.max_data_size) { spool_stats.max_data_size = spool_stats.data_size; } V(mutex); if (despool) { char ec1[30], ec2[30]; if (dcr->max_job_spool_size > 0) { Jmsg(dcr->jcr, M_INFO, 0, _("User specified Job spool size reached: " "JobSpoolSize=%s MaxJobSpoolSize=%s\n"), edit_uint64_with_commas(dcr->job_spool_size, ec1), edit_uint64_with_commas(dcr->max_job_spool_size, ec2)); } else { Jmsg(dcr->jcr, M_INFO, 0, _("User specified Device spool size reached: " "DevSpoolSize=%s MaxDevSpoolSize=%s\n"), edit_uint64_with_commas(dcr->dev->spool_size, ec1), edit_uint64_with_commas(dcr->dev->max_spool_size, ec2)); } if (!despool_data(dcr, false)) { Pmsg0(000, _("Bad return from despool in write_block.\n")); return false; } /* Despooling cleared these variables so reset them */ P(dcr->dev->spool_mutex); dcr->job_spool_size += hlen + wlen; dcr->dev->spool_size += hlen + wlen; V(dcr->dev->spool_mutex); Jmsg(dcr->jcr, M_INFO, 0, _("Spooling data again ...\n")); } if (!write_spool_header(dcr)) { return false; } if (!write_spool_data(dcr)) { return false; } Dmsg2(800, "Wrote block FI=%d LI=%d\n", block->FirstIndex, block->LastIndex); empty_block(block); return true; }