From: Kern Sibbald Date: Fri, 8 Jun 2012 15:51:54 +0000 (+0200) Subject: Rewrite some SD subroutines as class members X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=c13b6fc5753ac246af19a791fae64e631bdc58d9;p=bacula%2Fbacula Rewrite some SD subroutines as class members --- diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index 035b9114b4..6ff562b61a 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -660,7 +660,7 @@ DCR *new_dcr(JCR *jcr, DCR *dcr, DEVICE *dev) detach_dcr_from_dev(dcr); } /* Use job spoolsize prior to device spoolsize */ - if (jcr->spool_size) { + if (jcr && jcr->spool_size) { dcr->max_job_spool_size = jcr->spool_size; } else { dcr->max_job_spool_size = dev->device->max_job_spool_size; diff --git a/bacula/src/stored/append.c b/bacula/src/stored/append.c index 1af03fb822..0f95f6463a 100644 --- a/bacula/src/stored/append.c +++ b/bacula/src/stored/append.c @@ -214,10 +214,10 @@ fi_checked: stream_to_ascii(buf1, rec.Stream,rec.FileIndex), rec.data_len); - while (!write_record_to_block(dcr->block, &rec)) { + while (!write_record_to_block(dcr, &rec)) { Dmsg2(850, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len, rec.remainder); - if (!write_block_to_device(dcr)) { + if (!dcr->write_block_to_device()) { Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n", dev->print_name(), dev->bstrerror()); ok = false; @@ -293,13 +293,9 @@ fi_checked: jcr->setJobStatus(JS_ErrorTerminated); ok = false; } - if (dev->VolCatInfo.VolCatName[0] == 0) { - Pmsg0(000, _("NULL Volume name. This shouldn't happen!!!\n")); - Dmsg0(000, _("NULL Volume name. This shouldn't happen!!!\n")); - } Dmsg0(90, "back from write_end_session_label()\n"); /* Flush out final partial block of this session */ - if (!write_block_to_device(dcr)) { + if (!dcr->write_block_to_device()) { /* Print only if ok and not cancelled to avoid spurious messages */ if (ok && !jcr->is_job_canceled()) { Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"), diff --git a/bacula/src/stored/askdir.c b/bacula/src/stored/askdir.c index 35200e09d1..c78034da4b 100644 --- a/bacula/src/stored/askdir.c +++ b/bacula/src/stored/askdir.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2010 Free Software Foundation Europe e.V. + Copyright (C) 2000-2012 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. diff --git a/bacula/src/stored/bcopy.c b/bacula/src/stored/bcopy.c index d53129baae..b512950636 100644 --- a/bacula/src/stored/bcopy.c +++ b/bacula/src/stored/bcopy.c @@ -31,8 +31,6 @@ * * Kern E. Sibbald, October 2002 * - * - * Version $Id$ */ #include "bacula.h" @@ -215,7 +213,7 @@ int main (int argc, char *argv[]) ok = read_records(in_jcr->dcr, record_cb, mount_next_read_volume); if (ok || out_dev->can_write()) { - if (!write_block_to_device(out_jcr->dcr)) { + if (!out_jcr->dcr->write_block_to_device()) { Pmsg0(000, _("Write of last block failed.\n")); } } @@ -273,10 +271,10 @@ static bool record_cb(DCR *in_dcr, DEV_RECORD *rec) /* Skipping record, because does not match BSR filter */ return true; } - while (!write_record_to_block(out_block, rec)) { + while (!write_record_to_block(out_jcr->dcr, rec)) { Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec->data_len, rec->remainder); - if (!write_block_to_device(out_jcr->dcr)) { + if (!out_jcr->dcr->write_block_to_device()) { Dmsg2(90, "Got write_block_to_dev error on device %s: ERR=%s\n", out_dev->print_name(), out_dev->bstrerror()); Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"), @@ -284,7 +282,7 @@ static bool record_cb(DCR *in_dcr, DEV_RECORD *rec) return false; } } - if (!write_block_to_device(out_jcr->dcr)) { + if (!out_jcr->dcr->write_block_to_device()) { Dmsg2(90, "Got write_block_to_dev error on device %s: ERR=%s\n", out_dev->print_name(), out_dev->bstrerror()); Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"), @@ -309,10 +307,10 @@ static bool record_cb(DCR *in_dcr, DEV_RECORD *rec) return true; } records++; - while (!write_record_to_block(out_block, rec)) { + while (!write_record_to_block(out_jcr->dcr, rec)) { Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec->data_len, rec->remainder); - if (!write_block_to_device(out_jcr->dcr)) { + if (!out_jcr->dcr->write_block_to_device()) { Dmsg2(90, "Got write_block_to_dev error on device %s: ERR=%s\n", out_dev->print_name(), out_dev->bstrerror()); Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"), diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index 7e4754694d..ddc7b16f35 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2001-2010 Free Software Foundation Europe e.V. + Copyright (C) 2001-2012 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -335,11 +335,10 @@ static bool unser_block_header(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) * : false on failure * */ -bool write_block_to_device(DCR *dcr) +bool DCR::write_block_to_device() { bool stat = true; - DEVICE *dev = dcr->dev; - JCR *jcr = dcr->jcr; + DCR *dcr = this; if (dcr->spooling) { stat = write_block_to_spool_file(dcr); @@ -379,7 +378,7 @@ bool write_block_to_device(DCR *dcr) } } - if (!write_block_to_dev(dcr)) { + if (!dcr->write_block_to_dev()) { if (job_canceled(jcr) || jcr->getJobType() == JT_SYSTEM) { stat = false; } else { @@ -401,15 +400,13 @@ bail_out: * Returns: true on success or EOT * false on hard error */ -bool write_block_to_dev(DCR *dcr) +bool DCR::write_block_to_dev() { ssize_t stat = 0; uint32_t wlen; /* length to write */ int hit_max1, hit_max2; bool ok = true; - DEVICE *dev = dcr->dev; - JCR *jcr = dcr->jcr; - DEV_BLOCK *block = dcr->block; + DCR *dcr = this; #ifdef NO_TAPE_WRITE_TEST empty_block(block); @@ -690,7 +687,7 @@ static void reread_last_block(DCR *dcr) DEV_BLOCK *lblock = new_block(dev); /* Note, this can destroy dev->errmsg */ dcr->block = lblock; - if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) { + if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) { Jmsg(jcr, M_ERROR, 0, _("Re-read last block at EOT failed. ERR=%s"), dev->errmsg); } else { @@ -919,13 +916,13 @@ static bool do_dvd_size_checks(DCR *dcr) * Read block with locking * */ -bool read_block_from_device(DCR *dcr, bool check_block_numbers) +bool DCR::read_block_from_device(bool check_block_numbers) { bool ok; - DEVICE *dev = dcr->dev; + Dmsg0(250, "Enter read_block_from_device\n"); dev->r_dlock(); - ok = read_block_from_dev(dcr, check_block_numbers); + ok = read_block_from_dev(check_block_numbers); dev->dunlock(); Dmsg0(250, "Leave read_block_from_device\n"); return ok; @@ -936,14 +933,12 @@ bool read_block_from_device(DCR *dcr, bool check_block_numbers) * the block header. For a file, the block may be partially * or completely in the current buffer. */ -bool read_block_from_dev(DCR *dcr, bool check_block_numbers) +bool DCR::read_block_from_dev(bool check_block_numbers) { ssize_t stat; int looping; int retry; - JCR *jcr = dcr->jcr; - DEVICE *dev = dcr->dev; - DEV_BLOCK *block = dcr->block; + DCR *dcr = this; if (job_canceled(jcr)) { return false; diff --git a/bacula/src/stored/block.h b/bacula/src/stored/block.h index 1dd9721cfc..320058d1bc 100644 --- a/bacula/src/stored/block.h +++ b/bacula/src/stored/block.h @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2010 Free Software Foundation Europe e.V. + Copyright (C) 2000-2012 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -57,13 +57,12 @@ #define WRITE_RECHDR_LENGTH RECHDR2_LENGTH /* Tape label and version definitions */ -#define BaculaId "Bacula 1.0 immortal\n" -#define OldBaculaId "Bacula 0.9 mortal\n" -#define BaculaTapeVersion 11 +#define BaculaId "Bacula 1.0 immortal\n" +#define OldBaculaId "Bacula 0.9 mortal\n" +#define BaculaTapeVersion 11 #define OldCompatibleBaculaTapeVersion1 10 #define OldCompatibleBaculaTapeVersion2 9 - /* * This is the Media structure for a block header * Note, when written, it is serialized. diff --git a/bacula/src/stored/bls.c b/bacula/src/stored/bls.c index 77fa78e9dc..bcdd6e385f 100644 --- a/bacula/src/stored/bls.c +++ b/bacula/src/stored/bls.c @@ -283,7 +283,7 @@ static void do_blocks(char *infname) DEV_BLOCK *block = dcr->block; char buf1[100], buf2[100]; for ( ;; ) { - if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) { + if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) { Dmsg1(100, "!read_block(): ERR=%s\n", dev->bstrerror()); if (dev->at_eot()) { if (!mount_next_read_volume(dcr)) { @@ -294,7 +294,7 @@ static void do_blocks(char *infname) /* Read and discard Volume label */ DEV_RECORD *record; record = new_record(); - read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK); + dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK); read_record_from_block(dcr, block, record); get_session_record(dev, record, &sessrec); free_record(record); diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index a6afadd4b1..703f412227 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -733,7 +733,7 @@ static void capcmd() */ static void rectestcmd() { - DEV_BLOCK *block; + DEV_BLOCK *save_block; DEV_RECORD *rec; int i, blkno = 0; @@ -750,7 +750,8 @@ static void rectestcmd() } Dsm_check(200); - block = new_block(dev); + save_block = dcr->block; + dcr->block = new_block(dev); rec = new_record(); for (i=1; i<500000; i++) { @@ -758,8 +759,8 @@ static void rectestcmd() memset(rec->data, i & 0xFF, i); rec->data_len = i; Dsm_check(200); - if (write_record_to_block(block, rec)) { - empty_block(block); + if (write_record_to_block(dcr, rec)) { + empty_block(dcr->block); blkno++; Pmsg2(0, _("Block %d i=%d\n"), blkno, i); } else { @@ -768,7 +769,8 @@ static void rectestcmd() Dsm_check(200); } free_record(rec); - free_block(block); + free_block(dcr->block); + dcr->block = save_block; /* restore block to dcr */ Dsm_check(200); } @@ -803,33 +805,33 @@ static bool re_read_block_test() rec->data = check_pool_memory_size(rec->data, block->buf_len); len = rec->data_len = block->buf_len-100; memset(rec->data, 1, rec->data_len); - if (!write_record_to_block(block, rec)) { + if (!write_record_to_block(dcr, rec)) { Pmsg0(0, _("Error writing record to block.\n")); goto bail_out; } - if (!write_block_to_dev(dcr)) { + if (!dcr->write_block_to_dev()) { Pmsg0(0, _("Error writing block to device.\n")); goto bail_out; } else { Pmsg1(0, _("Wrote first record of %d bytes.\n"), rec->data_len); } memset(rec->data, 2, rec->data_len); - if (!write_record_to_block(block, rec)) { + if (!write_record_to_block(dcr, rec)) { Pmsg0(0, _("Error writing record to block.\n")); goto bail_out; } - if (!write_block_to_dev(dcr)) { + if (!dcr->write_block_to_dev()) { Pmsg0(0, _("Error writing block to device.\n")); goto bail_out; } else { Pmsg1(0, _("Wrote second record of %d bytes.\n"), rec->data_len); } memset(rec->data, 3, rec->data_len); - if (!write_record_to_block(block, rec)) { + if (!write_record_to_block(dcr, rec)) { Pmsg0(0, _("Error writing record to block.\n")); goto bail_out; } - if (!write_block_to_dev(dcr)) { + if (!dcr->write_block_to_dev()) { Pmsg0(0, _("Error writing block to device.\n")); goto bail_out; } else { @@ -855,7 +857,7 @@ static bool re_read_block_test() goto bail_out; } Pmsg0(0, _("Backspace record OK.\n")); - if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) { + if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) { berrno be; Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno)); goto bail_out; @@ -965,11 +967,11 @@ static bool speed_test_bacula(fill_mode_t mode, uint64_t nb_gb, uint32_t nb) init_speed(); for ( ; written < nb_gb; ) { - if (!write_record_to_block(block, rec)) { + if (!write_record_to_block(dcr, rec)) { Pmsg0(0, _("\nError writing record to block.\n")); goto bail_out; } - if (!write_block_to_dev(dcr)) { + if (!dcr->write_block_to_dev()) { Pmsg0(0, _("\nError writing block to device.\n")); goto bail_out; } @@ -1143,11 +1145,11 @@ static bool write_two_files() for (j=0; jwrite_block_to_dev()) { Pmsg0(0, _("Error writing block to device.\n")); goto bail_out; } @@ -1159,11 +1161,11 @@ static bool write_two_files() for (j=0; jwrite_block_to_dev()) { Pmsg0(0, _("Error writing block to device.\n")); goto bail_out; } @@ -1220,7 +1222,7 @@ static bool write_read_test() /* Now read it back */ for (i=1; i<=2*num_recs; i++) { read_again: - if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) { + if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) { berrno be; if (dev_state(dev, ST_EOF)) { Pmsg0(-1, _("Got EOF on tape.\n")); @@ -1339,7 +1341,7 @@ static bool position_test() goto bail_out; } read_again: - if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) { + if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) { berrno be; if (dev_state(dev, ST_EOF)) { Pmsg0(-1, _("Got EOF on tape.\n")); @@ -1874,7 +1876,7 @@ static void fsrcmd() static void rbcmd() { dev->open(dcr, OPEN_READ_ONLY); - read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK); + dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK); } /* @@ -1901,11 +1903,11 @@ static void wrcmd() memset(rec->data, i & 0xFF, i); rec->data_len = i; Dsm_check(200); - if (!write_record_to_block(block, rec)) { + if (!write_record_to_block(dcr, rec)) { Pmsg0(0, _("Error writing record to block.\n")); goto bail_out; } - if (!write_block_to_dev(dcr)) { + if (!dcr->write_block_to_dev()) { Pmsg0(0, _("Error writing block to device.\n")); goto bail_out; } else { @@ -2050,7 +2052,7 @@ static void scan_blocks() dev->update_pos(dcr); tot_files = dev->file; for (;;) { - if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) { + if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) { Dmsg1(100, "!read_block(): ERR=%s\n", dev->bstrerror()); if (dev->state & ST_EOT) { if (blocks > 0) { @@ -2272,7 +2274,7 @@ static void fillcmd() stream_to_ascii(buf1, rec.Stream, rec.FileIndex), rec.data_len); - while (!write_record_to_block(block, &rec)) { + while (!write_record_to_block(dcr, &rec)) { /* * When we get here we have just filled a block */ @@ -2354,7 +2356,7 @@ static void fillcmd() exit_code = 1; } /* Write out final block of this session */ - if (!write_block_to_device(dcr)) { + if (!dcr->write_block_to_device()) { Pmsg0(-1, _("Set ok=false after write_block_to_device.\n")); ok = false; exit_code = 1; @@ -2552,7 +2554,7 @@ static bool do_unfill() goto bail_out; } Pmsg1(-1, _("Reading block %u.\n"), last_block_num); - if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) { + if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) { Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror()); goto bail_out; } @@ -2604,7 +2606,7 @@ static bool do_unfill() goto bail_out; } Pmsg1(-1, _("Reading block %d.\n"), dev->block_num); - if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) { + if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) { Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror()); goto bail_out; } @@ -2620,7 +2622,7 @@ static bool do_unfill() goto bail_out; } Pmsg1(-1, _("Reading block %d.\n"), dev->block_num); - if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) { + if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) { Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror()); goto bail_out; } @@ -2707,7 +2709,7 @@ static int flush_block(DEV_BLOCK *block, int dump) /* Copy block */ this_file = dev->file; this_block_num = dev->block_num; - if (!write_block_to_dev(dcr)) { + if (!dcr->write_block_to_dev()) { Pmsg3(000, _("Last block at: %u:%u this_dev_block_num=%d\n"), last_file, last_block_num, this_block_num); if (vol_num == 1) { @@ -2817,11 +2819,11 @@ static void qfillcmd() printf("+"); fflush(stdout); } - if (!write_record_to_block(block, rec)) { + if (!write_record_to_block(dcr, rec)) { Pmsg0(0, _("Error writing record to block.\n")); goto bail_out; } - if (!write_block_to_dev(dcr)) { + if (!dcr->write_block_to_dev()) { Pmsg0(0, _("Error writing block to device.\n")); goto bail_out; } diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 7c44a9f62d..ee8b91bc2f 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -89,6 +89,7 @@ void set_os_device_parameters(DCR *dcr); static bool dev_get_os_pos(DEVICE *dev, struct mtget *mt_stat); static const char *mode_to_str(int mode); +static DEVICE *m_init_dev(JCR *jcr, DEVRES *device, bool new_init); /* * Allocate and initialize the DEVICE structure @@ -103,6 +104,13 @@ static const char *mode_to_str(int mode); */ DEVICE * init_dev(JCR *jcr, DEVRES *device) +{ + DEVICE *dev = m_init_dev(jcr, device, false); + return dev; +} + +static DEVICE * +m_init_dev(JCR *jcr, DEVRES *device, bool new_init) { struct stat statp; int errstat; @@ -196,6 +204,7 @@ init_dev(JCR *jcr, DEVRES *device) dev->drive_index = device->drive_index; dev->autoselect = device->autoselect; dev->dev_type = device->dev_type; + dev->device = device; if (dev->is_tape()) { /* No parts on tapes */ dev->max_part_size = 0; } else { @@ -205,8 +214,6 @@ init_dev(JCR *jcr, DEVRES *device) if (dev->vol_poll_interval && dev->vol_poll_interval < 60) { dev->vol_poll_interval = 60; } - /* Link the dev and device structures together */ - dev->device = device; device->dev = dev; if (dev->is_fifo()) { @@ -521,7 +528,7 @@ void DEVICE::open_device(DCR *dcr, int omode) } /* - * Open a file device + * Open a file device. */ void DEVICE::open_file_device(DCR *dcr, int omode) { @@ -1407,6 +1414,7 @@ void DEVICE::lock_door() { #ifdef MTLOCK struct mtop mt_com; + if (!is_tape()) return; mt_com.mt_op = MTLOCK; mt_com.mt_count = 1; d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com); @@ -1417,6 +1425,7 @@ void DEVICE::unlock_door() { #ifdef MTUNLOCK struct mtop mt_com; + if (!is_tape()) return; mt_com.mt_op = MTUNLOCK; mt_com.mt_count = 1; d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com); @@ -1497,7 +1506,7 @@ bool DEVICE::reposition(DCR *dcr, uint32_t rfile, uint32_t rblock) return fsr(rblock-block_num); } else { while (rblock > block_num) { - if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) { + if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) { berrno be; dev_errno = errno; Dmsg2(30, "Failed to find requested block on %s: ERR=%s", @@ -1812,10 +1821,13 @@ boffset_t DEVICE::lseek(DCR *dcr, boffset_t offset, int whence) return -1; } - +/* + * Truncate a volume. + */ bool DEVICE::truncate(DCR *dcr) /* We need the DCR for DVD-writing */ { struct stat st; + DEVICE *dev = this; Dmsg1(100, "truncate %s\n", print_name()); switch (dev_type) { @@ -1825,62 +1837,64 @@ bool DEVICE::truncate(DCR *dcr) /* We need the DCR for DVD-writing */ /* maybe we should rewind and write and eof ???? */ return true; /* we don't really truncate tapes */ case B_FILE_DEV: - if (ftruncate(m_fd, 0) != 0) { - berrno be; - Mmsg2(errmsg, _("Unable to truncate device %s. ERR=%s\n"), - print_name(), be.bstrerror()); - return false; - } - - /* - * Check for a successful ftruncate() and issue a work-around for devices - * (mostly cheap NAS) that don't support truncation. - * Workaround supplied by Martin Schmid as a solution to bug #1011. - * 1. close file - * 2. delete file - * 3. open new file with same mode - * 4. change ownership to original - */ - - if (fstat(m_fd, &st) != 0) { - berrno be; - Mmsg2(errmsg, _("Unable to stat device %s. ERR=%s\n"), - print_name(), be.bstrerror()); - return false; - } - - if (st.st_size != 0) { /* ftruncate() didn't work */ - POOL_MEM archive_name(PM_FNAME); - - pm_strcpy(archive_name, dev_name); - if (!IsPathSeparator(archive_name.c_str()[strlen(archive_name.c_str())-1])) { - pm_strcat(archive_name, "/"); + for ( ;; ) { + if (ftruncate(dev->m_fd, 0) != 0) { + berrno be; + Mmsg2(errmsg, _("Unable to truncate device %s. ERR=%s\n"), + print_name(), be.bstrerror()); + return false; } - pm_strcat(archive_name, dcr->VolumeName); - - Mmsg2(errmsg, _("Device %s doesn't support ftruncate(). Recreating file %s.\n"), - print_name(), archive_name.c_str()); - /* Close file and blow it away */ - ::close(m_fd); - ::unlink(archive_name.c_str()); - - /* Recreate the file -- of course, empty */ - set_mode(CREATE_READ_WRITE); - if ((m_fd = ::open(archive_name.c_str(), mode, st.st_mode)) < 0) { + /* + * Check for a successful ftruncate() and issue a work-around for devices + * (mostly cheap NAS) that don't support truncation. + * Workaround supplied by Martin Schmid as a solution to bug #1011. + * 1. close file + * 2. delete file + * 3. open new file with same mode + * 4. change ownership to original + */ + + if (fstat(dev->m_fd, &st) != 0) { berrno be; - dev_errno = errno; - Mmsg2(errmsg, _("Could not reopen: %s, ERR=%s\n"), archive_name.c_str(), - be.bstrerror()); - Dmsg1(100, "reopen failed: %s", errmsg); - Emsg0(M_FATAL, 0, errmsg); + Mmsg2(errmsg, _("Unable to stat device %s. ERR=%s\n"), + print_name(), be.bstrerror()); return false; } + + if (st.st_size != 0) { /* ftruncate() didn't work */ + POOL_MEM archive_name(PM_FNAME); - /* Reset proper owner */ - chown(archive_name.c_str(), st.st_uid, st.st_gid); + pm_strcpy(archive_name, dev_name); + if (!IsPathSeparator(archive_name.c_str()[strlen(archive_name.c_str())-1])) { + pm_strcat(archive_name, "/"); + } + pm_strcat(archive_name, dcr->VolumeName); + + Mmsg2(errmsg, _("Device %s doesn't support ftruncate(). Recreating file %s.\n"), + print_name(), archive_name.c_str()); + + /* Close file and blow it away */ + ::close(dev->m_fd); + ::unlink(archive_name.c_str()); + + /* Recreate the file -- of course, empty */ + dev->set_mode(CREATE_READ_WRITE); + if ((dev->m_fd = ::open(archive_name.c_str(), mode, st.st_mode)) < 0) { + berrno be; + dev_errno = errno; + Mmsg2(errmsg, _("Could not reopen: %s, ERR=%s\n"), archive_name.c_str(), + be.bstrerror()); + Dmsg1(100, "reopen failed: %s", errmsg); + Emsg0(M_FATAL, 0, errmsg); + return false; + } + + /* Reset proper owner */ + chown(archive_name.c_str(), st.st_uid, st.st_gid); + } + break; } - return true; } return false; @@ -2290,6 +2304,7 @@ dev_vol_name(DEVICE *dev) */ void DEVICE::term(void) { + DEVICE *dev = NULL; Dmsg1(900, "term dev: %s\n", print_name()); close(); if (dev_name) { @@ -2317,6 +2332,9 @@ void DEVICE::term(void) device->dev = NULL; } delete this; + if (dev) { + dev->term(); + } } /* diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 75473e9133..8104d241ee 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -317,7 +317,7 @@ public: int is_tape() const { return (dev_type == B_TAPE_DEV || dev_type == B_VTAPE_DEV); } int is_ftp() const { return dev_type == B_FTP_DEV; } - int is_file() const { return dev_type == B_FILE_DEV; } + int is_file() const { return (dev_type == B_FILE_DEV); } int is_fifo() const { return dev_type == B_FIFO_DEV; } int is_dvd() const { return dev_type == B_DVD_DEV; } int is_vtl() const { return dev_type == B_VTL_DEV; } @@ -485,6 +485,10 @@ inline const char *DEVICE::strerror() const { return errmsg; } inline const char *DEVICE::archive_name() const { return dev_name; } inline const char *DEVICE::print_name() const { return prt_name; } + +#define CHECK_BLOCK_NUMBERS true +#define NO_BLOCK_NUMBER_CHECK false + /* * Device Context (or Control) Record. * There is one of these records for each Job that is using @@ -590,6 +594,16 @@ public: bool do_unload(); bool do_load(bool is_writing); bool is_tape_position_ok(); + + /* Methods in block.c */ + bool write_block_to_device(); + bool write_block_to_dev(); + bool read_block_from_device(bool check_block_numbers); + bool read_block_from_dev(bool check_block_numbers); + + /* Methods in label.c */ + bool rewrite_volume_label(bool recycle); + }; /* diff --git a/bacula/src/stored/device.c b/bacula/src/stored/device.c index 7324864371..7f8366b613 100644 --- a/bacula/src/stored/device.c +++ b/bacula/src/stored/device.c @@ -146,7 +146,7 @@ bool fixup_device_block_write_error(DCR *dcr, int retries) * empty label_blk, and nothing will be written. */ Dmsg0(190, "write label block to dev\n"); - if (!write_block_to_dev(dcr)) { + if (!dcr->write_block_to_dev()) { berrno be; Pmsg1(0, _("write_block_to_device Volume label failed. ERR=%s"), be.bstrerror(dev->dev_errno)); @@ -181,7 +181,7 @@ bool fixup_device_block_write_error(DCR *dcr, int retries) /* Write overflow block to device */ Dmsg0(190, "Write overflow block to dev\n"); - if (!write_block_to_dev(dcr)) { + if (!dcr->write_block_to_dev()) { berrno be; Dmsg1(0, _("write_block_to_device overflow block failed. ERR=%s"), be.bstrerror(dev->dev_errno)); diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index f3eed0789b..ffba811bf1 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -515,7 +515,7 @@ static void label_volume_if_ok(DCR *dcr, char *oldname, case VOL_IO_ERROR: case VOL_NO_LABEL: if (!write_new_volume_label_to_dev(dcr, newname, poolname, - relabel, true /* write dvd now */)) { + relabel, true /* write dvd now */)) { dir->fsend(_("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror()); break; } diff --git a/bacula/src/stored/label.c b/bacula/src/stored/label.c index 4590a55e87..bf8bf65120 100644 --- a/bacula/src/stored/label.c +++ b/bacula/src/stored/label.c @@ -37,7 +37,7 @@ #include "stored.h" /* pull in Storage Deamon headers */ /* Forward referenced functions */ -static void create_volume_label_record(DCR *dcr, DEV_RECORD *rec); +static void create_volume_label_record(DCR *dcr, DEVICE *dev, DEV_RECORD *rec); /* * Read the volume label @@ -126,7 +126,7 @@ int read_dev_volume_label(DCR *dcr) empty_block(block); Dmsg0(130, "Big if statement in read_volume_label\n"); - if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) { + if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) { Mmsg(jcr->errmsg, _("Requested Volume \"%s\" on %s is not a Bacula " "labeled Volume, because: ERR=%s"), NPRT(VolName), dev->print_name(), dev->print_errmsg()); @@ -256,22 +256,23 @@ bail_out: * Returns: false on failure * true on success */ -bool write_volume_label_to_block(DCR *dcr) +static bool write_volume_label_to_block(DCR *dcr) { - DEV_RECORD rec; DEVICE *dev = dcr->dev; - JCR *jcr = dcr->jcr; DEV_BLOCK *block = dcr->block; + DEV_RECORD rec; + JCR *jcr = dcr->jcr; Dmsg0(130, "write Label in write_volume_label_to_block()\n"); + memset(&rec, 0, sizeof(rec)); rec.data = get_memory(SER_LENGTH_Volume_Label); empty_block(block); /* Volume label always at beginning */ - create_volume_label_record(dcr, &rec); + create_volume_label_record(dcr, dev, &rec); block->BlockNumber = 0; - if (!write_record_to_block(block, &rec)) { + if (!write_record_to_block(dcr, &rec)) { free_pool_memory(rec.data); Jmsg1(jcr, M_FATAL, 0, _("Cannot write Volume label to block for device %s\n"), dev->print_name()); @@ -295,13 +296,12 @@ bool write_volume_label_to_block(DCR *dcr) * This routine should be used only when labeling a blank tape. */ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, - const char *PoolName, bool relabel, bool dvdnow) + const char *PoolName, bool relabel, bool dvdnow) { - DEVICE * volatile dev = dcr->dev; - + DEVICE *dev = dcr->dev; + DEV_BLOCK *block = dcr->block; Dmsg0(150, "write_volume_label()\n"); - empty_block(dcr->block); if (*VolName == 0) { Pmsg0(0, "=== ERROR: write_new_volume_label_to_dev called with NULL VolName\n"); goto bail_out; @@ -331,58 +331,56 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, } } Dmsg1(150, "Label type=%d\n", dev->label_type); - if (!dev->rewind(dcr)) { - Dmsg2(130, "Bad status on %s from rewind: ERR=%s\n", dev->print_name(), dev->print_errmsg()); - if (!forge_on) { - goto bail_out; + + for ( ;; ) { + empty_block(block); + if (!dev->rewind(dcr)) { + Dmsg2(130, "Bad status on %s from rewind: ERR=%s\n", dev->print_name(), dev->print_errmsg()); + if (!forge_on) { + goto bail_out; + } } - } - /* Temporarily mark in append state to enable writing */ - dev->set_append(); + /* Temporarily mark in append state to enable writing */ + dev->set_append(); - /* Create PRE_LABEL or VOL_LABEL if DVD */ - create_volume_label(dev, VolName, PoolName, dvdnow); + /* Create PRE_LABEL or VOL_LABEL if DVD */ + create_volume_label(dev, VolName, PoolName, dvdnow); - /* - * If we have already detected an ANSI label, re-read it - * to skip past it. Otherwise, we write a new one if - * so requested. - */ - if (dev->label_type != B_BACULA_LABEL) { - if (read_ansi_ibm_label(dcr) != VOL_OK) { - dev->rewind(dcr); + /* + * If we have already detected an ANSI label, re-read it + * to skip past it. Otherwise, we write a new one if + * so requested. + */ + if (dev->label_type != B_BACULA_LABEL) { + if (read_ansi_ibm_label(dcr) != VOL_OK) { + dev->rewind(dcr); + goto bail_out; + } + } else if (!write_ansi_ibm_labels(dcr, ANSI_VOL_LABEL, VolName)) { goto bail_out; } - } else if (!write_ansi_ibm_labels(dcr, ANSI_VOL_LABEL, VolName)) { - goto bail_out; - } - - create_volume_label_record(dcr, dcr->rec); - dcr->rec->Stream = 0; - dcr->rec->maskedStream = 0; - if (!write_record_to_block(dcr->block, dcr->rec)) { - Dmsg2(130, "Bad Label write on %s: ERR=%s\n", dev->print_name(), dev->print_errmsg()); - goto bail_out; - } else { - Dmsg2(130, "Wrote label of %d bytes to %s\n", dcr->rec->data_len, dev->print_name()); - } + create_volume_label_record(dcr, dev, dcr->rec); + dcr->rec->Stream = 0; + dcr->rec->maskedStream = 0; - Dmsg0(130, "Call write_block_to_dev()\n"); - if (!write_block_to_dev(dcr)) { - Dmsg2(130, "Bad Label write on %s: ERR=%s\n", dev->print_name(), dev->print_errmsg()); - goto bail_out; - } + if (!write_record_to_block(dcr, dcr->rec)) { + Dmsg2(130, "Bad Label write on %s: ERR=%s\n", dev->print_name(), dev->print_errmsg()); + goto bail_out; + } else { + Dmsg2(130, "Wrote label of %d bytes to %s\n", dcr->rec->data_len, dev->print_name()); + } - /* Now commit block to DVD if we should write now */ - if (dev->is_dvd() && dvdnow) { - Dmsg1(150, "New VolName=%s\n", dev->VolCatInfo.VolCatName); - if (!dvd_write_part(dcr)) { - Dmsg2(130, "Bad DVD write on %s: ERR=%s\n", dev->print_name(), dev->print_errmsg()); + Dmsg0(130, "Call write_block_to_dev()\n"); + if (!dcr->write_block_to_dev()) { + Dmsg2(130, "Bad Label write on %s: ERR=%s\n", dev->print_name(), dev->print_errmsg()); goto bail_out; } + break; } + dev = dcr->dev; + Dmsg0(130, " Wrote block to device\n"); @@ -420,10 +418,9 @@ bail_out: * Returns: true if OK * false if unable to write it */ -bool rewrite_volume_label(DCR *dcr, bool recycle) +bool DCR::rewrite_volume_label(bool recycle) { - DEVICE *dev = dcr->dev; - JCR *jcr = dcr->jcr; + DCR *dcr = this; if (!dev->open(dcr, OPEN_READ_WRITE)) { Jmsg3(jcr, M_WARNING, 0, _("Open device %s Volume \"%s\" failed: ERR=%s\n"), @@ -457,7 +454,6 @@ bool rewrite_volume_label(DCR *dcr, bool recycle) } if (recycle) { Dmsg1(150, "Doing recycle. Vol=%s\n", dcr->VolumeName); -// volume_unused(dcr); /* mark volume unused */ if (!dev->truncate(dcr)) { Jmsg2(jcr, M_FATAL, 0, _("Truncate error on device %s: ERR=%s\n"), dev->print_name(), dev->print_errmsg()); @@ -487,7 +483,7 @@ bool rewrite_volume_label(DCR *dcr, bool recycle) /* Attempt write to check write permission */ Dmsg1(200, "Attempt to write to device fd=%d.\n", dev->fd()); - if (!write_block_to_dev(dcr)) { + if (!dcr->write_block_to_dev()) { Jmsg2(jcr, M_ERROR, 0, _("Unable to write device %s: ERR=%s\n"), dev->print_name(), dev->print_errmsg()); Dmsg0(200, "===ERROR write block to dev\n"); @@ -540,11 +536,10 @@ bool rewrite_volume_label(DCR *dcr, bool recycle) * Assumes that the dev->VolHdr structure is properly * initialized. */ -static void create_volume_label_record(DCR *dcr, DEV_RECORD *rec) +static void create_volume_label_record(DCR *dcr, DEVICE *dev, DEV_RECORD *rec) { ser_declare; struct date_time dt; - DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; char buf[100]; @@ -583,7 +578,7 @@ static void create_volume_label_record(DCR *dcr, DEV_RECORD *rec) ser_string(dev->VolHdr.LabelProg); ser_string(dev->VolHdr.ProgVersion); ser_string(dev->VolHdr.ProgDate); - + ser_end(rec->data, SER_LENGTH_Volume_Label); bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName)); rec->data_len = ser_length(rec->data); @@ -738,13 +733,13 @@ bool write_session_label(DCR *dcr, int label) */ if (!can_write_record_to_block(block, rec)) { Dmsg0(150, "Cannot write session label to block.\n"); - if (!write_block_to_device(dcr)) { + if (!dcr->write_block_to_device()) { Dmsg0(130, "Got session label write_block_to_dev error.\n"); free_record(rec); return false; } } - if (!write_record_to_block(block, rec)) { + if (!write_record_to_block(dcr, rec)) { free_record(rec); return false; } diff --git a/bacula/src/stored/mac.c b/bacula/src/stored/mac.c index 0797b244e8..330ea8d2d0 100644 --- a/bacula/src/stored/mac.c +++ b/bacula/src/stored/mac.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2006-2011 Free Software Foundation Europe e.V. + Copyright (C) 2006-2012 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -122,7 +122,7 @@ ok_out: Dmsg1(100, "ok=%d\n", ok); if (ok || dev->can_write()) { /* Flush out final partial block of this session */ - if (!write_block_to_device(jcr->dcr)) { + if (!jcr->dcr->write_block_to_device()) { Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"), dev->print_name(), dev->bstrerror()); Dmsg0(100, _("Set ok=FALSE after write_block_to_device.\n")); @@ -238,10 +238,10 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) jcr->JobId, FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len); - while (!write_record_to_block(jcr->dcr->block, rec)) { + while (!write_record_to_block(jcr->dcr, rec)) { Dmsg4(200, "!write_record_to_block blkpos=%u:%u len=%d rem=%d\n", dev->file, dev->block_num, rec->data_len, rec->remainder); - if (!write_block_to_device(jcr->dcr)) { + if (!jcr->dcr->write_block_to_device()) { Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n", dev->print_name(), dev->bstrerror()); Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"), diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index c77da4c256..f59bb6ae37 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -265,7 +265,7 @@ read_volume: */ recycle = strcmp(dev->VolCatInfo.VolCatStatus, "Recycle") == 0; if (dev->VolHdr.LabelType == PRE_LABEL || recycle) { - if (!rewrite_volume_label(dcr, recycle)) { + if (!dcr->rewrite_volume_label(recycle)) { mark_volume_in_error(); goto mount_next_vol; } diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index 9aaee10d71..7958564043 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2010 Free Software Foundation Europe e.V. + Copyright (C) 2000-2012 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -80,16 +80,9 @@ DEV_BLOCK *dup_block(DEV_BLOCK *eblock); void init_block_write(DEV_BLOCK *block); void empty_block(DEV_BLOCK *block); void free_block(DEV_BLOCK *block); -bool write_block_to_device(DCR *dcr); -bool write_block_to_dev(DCR *dcr); void print_block_read_errors(JCR *jcr, DEV_BLOCK *block); void ser_block_header(DEV_BLOCK *block); -#define CHECK_BLOCK_NUMBERS true -#define NO_BLOCK_NUMBER_CHECK false -bool read_block_from_device(DCR *dcr, bool check_block_numbers); -bool read_block_from_dev(DCR *dcr, bool check_block_numbers); - /* From butil.c -- utilities for SD tool programs */ void print_ls_output(const char *fname, const char *link, int type, struct stat *statp); JCR *setup_jcr(const char *name, char *dev_name, BSR *bsr, @@ -151,20 +144,18 @@ int read_dev_volume_label(DCR *dcr); int read_dvd_volume_label(DCR *dcr, bool write); void create_session_label(DCR *dcr, DEV_RECORD *rec, int label); void create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName, bool dvdnow); -bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, - const char *PoolName, bool relabel, bool dvdnow); #define ANSI_VOL_LABEL 0 #define ANSI_EOF_LABEL 1 #define ANSI_EOV_LABEL 2 bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName); int read_ansi_ibm_label(DCR *dcr); bool write_session_label(DCR *dcr, int label); -bool write_volume_label_to_block(DCR *dcr); -bool rewrite_volume_label(DCR *dcr, bool recycle); void dump_volume_label(DEVICE *dev); void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose); bool unser_volume_label(DEVICE *dev, DEV_RECORD *rec); bool unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec); +bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, + const char *PoolName, bool relabel, bool dvdnow); /* From locks.c */ void _lock_device(const char *file, int line, DEVICE *dev); @@ -200,7 +191,7 @@ void create_restore_volume_list(JCR *jcr); /* From record.c */ const char *FI_to_ascii(char *buf, int fi); const char *stream_to_ascii(char *buf, int stream, int fi); -bool write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec); +bool write_record_to_block(DCR *dcr, DEV_RECORD *rec); bool can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec); bool read_record_from_block(DCR *dcr, DEV_BLOCK *block, DEV_RECORD *rec); DEV_RECORD *new_record(); diff --git a/bacula/src/stored/read_record.c b/bacula/src/stored/read_record.c index d998ccb37a..078045d4ac 100644 --- a/bacula/src/stored/read_record.c +++ b/bacula/src/stored/read_record.c @@ -83,7 +83,7 @@ bool read_records(DCR *dcr, ok = false; break; } - if (!read_block_from_device(dcr, CHECK_BLOCK_NUMBERS)) { + if (!dcr->read_block_from_device(CHECK_BLOCK_NUMBERS)) { if (dev->at_eot()) { DEV_RECORD *trec = new_record(); Jmsg(jcr, M_INFO, 0, _("End of Volume at file %u on device %s, Volume \"%s\"\n"), @@ -119,7 +119,7 @@ bool read_records(DCR *dcr, * and pass it off to the callback routine, then continue * most likely reading the previous record. */ - read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK); + dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK); read_record_from_block(dcr, block, trec); handle_session_record(dev, trec, &sessrec); ok = record_cb(dcr, trec); diff --git a/bacula/src/stored/record.c b/bacula/src/stored/record.c index 32f09a9100..a28d9ef936 100644 --- a/bacula/src/stored/record.c +++ b/bacula/src/stored/record.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2001-2010 Free Software Foundation Europe e.V. + Copyright (C) 2001-2012 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -288,11 +288,14 @@ void free_record(DEV_RECORD *rec) * non-zero), and 2. The remaining bytes to write may not * all fit into the block. */ -bool write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec) +bool write_record_to_block(DCR *dcr, DEV_RECORD *rec) { ser_declare; uint32_t remlen; char buf1[100], buf2[100]; + DEV_BLOCK *block; + + block = dcr->block; remlen = block->buf_len - block->binbuf; diff --git a/bacula/src/stored/record.h b/bacula/src/stored/record.h index 04a93cb609..92da7d3513 100644 --- a/bacula/src/stored/record.h +++ b/bacula/src/stored/record.h @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2010 Free Software Foundation Europe e.V. + Copyright (C) 2000-2012 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -172,6 +172,7 @@ struct Volume_Label { char LabelProg[50]; /* Label program name */ char ProgVersion[50]; /* Program version */ char ProgDate[50]; /* Program build date/time */ + }; #define SER_LENGTH_Volume_Label 1024 /* max serialised length of volume label */ diff --git a/bacula/src/stored/spool.c b/bacula/src/stored/spool.c index b4098b215f..9cbb05ad77 100644 --- a/bacula/src/stored/spool.c +++ b/bacula/src/stored/spool.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2004-2011 Free Software Foundation Europe e.V. + Copyright (C) 2004-2012 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -295,7 +295,7 @@ static bool despool_data(DCR *dcr, bool commit) ok = false; break; } - ok = write_block_to_device(dcr); + ok = dcr->write_block_to_device(); if (!ok) { Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"), dcr->dev->print_name(), dcr->dev->bstrerror());