From 586608a4b10bbc8c989b995aa1b268460f44783b Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sun, 17 Jul 2005 08:50:15 +0000 Subject: [PATCH] - Fix name space pollution by OpenSSL 0.9.8 reported by Matthias Kurz -- applied his patch. - Fix bpipe.c so that it does not modify results pointer. ***FIXME*** calling sequence should be changed. - Remove some remaining references to dev_name. - Fix calls to mount_dev() and unmount_dev() to correspond to returned value (bool instead of int). - Try without success to make DVD writing work. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2207 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 20 ++++---- bacula/kes-1.37 | 13 +++++- bacula/scripts/dvd-writepart.in | 2 +- bacula/src/bacula.h | 19 ++++---- bacula/src/lib/bpipe.c | 11 ++++- bacula/src/stored/block.c | 14 +++--- bacula/src/stored/dev.c | 21 ++++++--- bacula/src/stored/dvd.c | 81 +++++++++++++++++++++------------ bacula/src/stored/mount.c | 2 +- bacula/src/version.h | 6 +-- 10 files changed, 118 insertions(+), 71 deletions(-) diff --git a/bacula/kernstodo b/bacula/kernstodo index fb63c65b80..67fc9569b6 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -11,14 +11,21 @@ Version 1.37 Kern (see below) ======================================================== Final items for 1.37 before release: -- --without-openssl breaks at least on Solaris. 1. Fix the remaining bugs that I am aware of and new ones that come up during testing. +- --without-openssl breaks at least on Solaris. +- bsr-opt-test fails. bsr deleted. Fix. +- Allow cancel of unknown Job +- State not saved when closing Win32 FD by icon +- Move Python daemon variables from Job to Bacula object. + WorkingDir, ConfigFile + 3. Document all the new features (about half done). -6. Build and test the Volume Shadow Copy (VSS) for Win32. 7. Write a bacula-web document 8. Take one more try at making DVD writing work. 9. Run the regression scripts on Solaris and FreeBSD +- Figure out how to package docs and gui programs. +- Test TLS. Document: - Document cleaning up the spool files. @@ -52,17 +59,13 @@ Document: do restores. + +For 1.39: 1.xx Major Projects: #3 Migration (Move, Copy, Archive Jobs) - (probably not this version) #7 Single Job Writing to Multiple Storage Devices - (probably not this version) - -For 1.39: - Reserve blocks other restore jobs when first cannot connect to SD -- no way to cancel in SD if Dir job canceled. -- Allow cancel of unknown Job -- State not saved when closing Win32 FD by icon - Add true/false to conf same as yes/no - For Windows disaster recovery see http://unattended.sf.net/ - regardless of the retention period, Bacula will not prune the @@ -1369,3 +1372,4 @@ Block Position: 0 - Finish TLS implementation. - Port limiting -m in iptables to prevent DoS attacks could cause broken pipes on Bacula. +6. Build and test the Volume Shadow Copy (VSS) for Win32. diff --git a/bacula/kes-1.37 b/bacula/kes-1.37 index 190c3062f4..05c83d6770 100644 --- a/bacula/kes-1.37 +++ b/bacula/kes-1.37 @@ -3,7 +3,18 @@ General: -Changes to 1.37.30: +Changes to 1.37.31: +17Jul05 +- Fix name space pollution by OpenSSL 0.9.8 reported by + Matthias Kurz -- applied his patch. +- Fix bpipe.c so that it does not modify results pointer. + ***FIXME*** calling sequence should be changed. +- Remove some remaining references to dev_name. +- Fix calls to mount_dev() and unmount_dev() to + correspond to returned value (bool instead of int). +- Try without success to make DVD writing work. + +Changes to 1.37.30 released 16 July 05: 14Jul05 - Fix "dir" command scanning field misalignment in wx-console. diff --git a/bacula/scripts/dvd-writepart.in b/bacula/scripts/dvd-writepart.in index 515daa8583..669d9a7a60 100644 --- a/bacula/scripts/dvd-writepart.in +++ b/bacula/scripts/dvd-writepart.in @@ -43,7 +43,7 @@ partnum=$1 dev=$2 filename=$3 -if test $partnum = 0 ; then +if test $partnum = 1 ; then arg="-Z" else arg="-M" diff --git a/bacula/src/bacula.h b/bacula/src/bacula.h index 88b685a341..e6eeabab09 100644 --- a/bacula/src/bacula.h +++ b/bacula/src/bacula.h @@ -3,24 +3,18 @@ * * Version $Id$ */ - /* Copyright (C) 2000-2005 Kern Sibbald This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. + modify it under the terms of the GNU General Public License + version 2 as amended with additional clauses defined in the + file LICENSE in the main source directory. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional details. */ @@ -113,10 +107,13 @@ #include #ifdef HAVE_OPENSSL +/* fight OpenSSL namespace pollution */ +#define STORE OSSL_STORE #include #include #include #include +#undef STORE #endif /* Local Bacula includes. Be sure to put all the system diff --git a/bacula/src/lib/bpipe.c b/bacula/src/lib/bpipe.c index 4a9eb97887..4962f5c7bb 100644 --- a/bacula/src/lib/bpipe.c +++ b/bacula/src/lib/bpipe.c @@ -318,9 +318,15 @@ int run_program_full_output(char *prog, int wait, POOLMEM *results) results[0] = 0; while (1) { + tmp[0] = 0; fgets(tmp, sizeof_pool_memory(tmp), bpipe->rfd); Dmsg1(800, "Run program fgets=%s", tmp); - pm_strcat(results, tmp); + /* ***FIXME**** + * we need to pass POOL_MEM &results as arg to ensure + * that change in address of results is passed back + */ + // pm_strcat(results, tmp); + bstrncat(results, tmp, sizeof_pool_memory(results)); if (feof(bpipe->rfd)) { stat1 = 0; Dmsg1(900, "Run program fgets stat=%d\n", stat1); @@ -329,7 +335,8 @@ int run_program_full_output(char *prog, int wait, POOLMEM *results) stat1 = ferror(bpipe->rfd); } if (stat1 < 0) { - Dmsg2(900, "Run program fgets stat=%d ERR=%s\n", stat1, strerror(errno)); + berrno be; + Dmsg2(200, "Run program fgets stat=%d ERR=%s\n", stat1, be.strerror()); break; } else if (stat1 != 0) { Dmsg1(900, "Run program fgets stat=%d\n", stat1); diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index 74edd99f94..ca6cbc8def 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -464,7 +464,7 @@ bool write_block_to_dev(DCR *dcr) max_cap = dev->VolCatInfo.VolCatMaxBytes; } Jmsg(jcr, M_INFO, 0, _("User defined maximum volume capacity %s exceeded on device %s.\n"), - edit_uint64_with_commas(max_cap, ed1), dev->dev_name); + edit_uint64_with_commas(max_cap, ed1), dev->print_name()); terminate_writing_volume(dcr); reread_last_block(dcr); /* DEBUG */ dev->dev_errno = ENOSPC; @@ -534,7 +534,7 @@ bool write_block_to_dev(DCR *dcr) } if (dev->dev_errno != ENOSPC) { Jmsg4(jcr, M_ERROR, 0, _("Write error at %u:%u on device %s. ERR=%s.\n"), - dev->file, dev->block_num, dev->dev_name, be.strerror()); + dev->file, dev->block_num, dev->print_name(), be.strerror()); } } else { dev->dev_errno = ENOSPC; /* out of space */ @@ -877,7 +877,7 @@ reread: if (looping > 1) { dev->dev_errno = EIO; Mmsg1(dev->errmsg, _("Block buffer size looping problem on device %s\n"), - dev->dev_name); + dev->print_name()); Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); block->read_len = 0; return false; @@ -925,7 +925,7 @@ reread: Dmsg1(200, "Read device got: ERR=%s\n", be.strerror()); block->read_len = 0; Mmsg4(dev->errmsg, _("Read error at file:blk %u:%u on device %s. ERR=%s.\n"), - dev->file, dev->block_num, dev->dev_name, be.strerror()); + dev->file, dev->block_num, dev->print_name(), be.strerror()); Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); if (dev->at_eof()) { /* EOF just seen? */ dev->set_eot(); /* yes, error => EOT */ @@ -938,7 +938,7 @@ reread: dev->block_num = 0; block->read_len = 0; Mmsg3(dev->errmsg, _("Read zero bytes at %u:%u on device %s.\n"), - dev->file, dev->block_num, dev->dev_name); + dev->file, dev->block_num, dev->print_name()); if (dev->at_eof()) { /* EOF already read? */ dev->set_eot(); /* yes, 2 EOFs => EOT */ return 0; @@ -951,7 +951,7 @@ reread: if (block->read_len < BLKHDR2_LENGTH) { dev->dev_errno = EIO; Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Very short block of %d bytes on device %s discarded.\n"), - dev->file, dev->block_num, block->read_len, dev->dev_name); + dev->file, dev->block_num, block->read_len, dev->print_name()); Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); dev->set_short_block(); block->read_len = block->binbuf = 0; @@ -1010,7 +1010,7 @@ reread: if (block->block_len > block->read_len) { dev->dev_errno = EIO; Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Short block of %d bytes on device %s discarded.\n"), - dev->file, dev->block_num, block->read_len, dev->dev_name); + dev->file, dev->block_num, block->read_len, dev->print_name()); Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); dev->set_short_block(); block->read_len = block->binbuf = 0; diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 0addd2c0fa..d75b03a3b1 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -282,10 +282,10 @@ DEVICE::open(DCR *dcr, int omode) if (is_tape() || is_fifo()) { open_tape_device(omode); } else if (is_dvd()) { - Dmsg1(100, "call open_dvd_device mode=%s\n", mode_to_str(mode)); + Dmsg1(100, "call open_dvd_device mode=%s\n", mode_to_str(omode)); open_dvd_device(dcr, omode); } else { - Dmsg1(100, "call open_file_device mode=%d\n", mode_to_str(mode)); + Dmsg1(100, "call open_file_device mode=%s\n", mode_to_str(omode)); open_file_device(omode); } return fd; @@ -475,15 +475,16 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode) part_size = 0; - if (mount_dev(this, 1) < 0) { + if (!mount_dev(this, 1)) { Mmsg(errmsg, _("Could not mount device %s.\n"), print_name()); Emsg0(M_FATAL, 0, errmsg); fd = -1; return; } - Dmsg3(29, "open dev: %s dev=%s mode=%s\n", is_dvd()?"DVD":"disk", - archive_name.c_str(), mode_to_str(omode)); + Dmsg5(29, "open dev: %s dev=%s mode=%s part=%d npart=%d\n", + is_dvd()?"DVD":"disk", archive_name.c_str(), mode_to_str(omode), + part, num_parts); openmode = omode; /* @@ -538,9 +539,15 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode) set_opened(); use_count = 1; update_pos_dev(this); /* update position */ + /* Just created Volume */ + if (omode == OPEN_READ_WRITE && part_size == 0) { + part++; + num_parts++; + VolCatInfo.VolCatParts = num_parts; + } } } - Dmsg4(29, "open dev: DVD fd=%d opened, part=%d/%d, part_size=%u\n", + Dmsg4(29, "open dev: DVD fd=%d opened, part=%d nump=%d, part_size=%u\n", fd, part, num_parts, part_size); if (is_open() && is_dvd() && (omode != OPEN_READ_ONLY) && (free_space_errno == 0 || num_parts == part)) { @@ -1623,7 +1630,7 @@ static void do_close(DEVICE *dev) close(dev->fd); } - if (unmount_dev(dev, 1) < 0) { + if (!unmount_dev(dev, 1)) { Dmsg1(0, "Cannot unmount device %s.\n", dev->print_name()); } diff --git a/bacula/src/stored/dvd.c b/bacula/src/stored/dvd.c index 72a915681c..e13357a684 100644 --- a/bacula/src/stored/dvd.c +++ b/bacula/src/stored/dvd.c @@ -58,8 +58,8 @@ static void add_file_and_part_name(DEVICE *dev, POOL_MEM &archive_name) } pm_strcat(archive_name, dev->VolCatInfo.VolCatName); - /* if part != 0, append .# to the filename (where # is the part number) */ - if (dev->part != 0) { + /* if part > 1, append .# to the filename (where # is the part number) */ + if (dev->part > 1) { pm_strcat(archive_name, "."); bsnprintf(partnumber, sizeof(partnumber), "%d", dev->part); pm_strcat(archive_name, partnumber); @@ -273,20 +273,19 @@ static bool dvd_write_part(DCR *dcr) DEVICE *dev = dcr->dev; Dmsg1(29, "dvd_write_part: device is %s\n", dev->print_name()); - if (unmount_dev(dev, 1) < 0) { + if (!unmount_dev(dev, 1)) { Dmsg0(29, "dvd_write_part: unable to unmount the device\n"); } POOL_MEM ocmd(PM_FNAME); - POOLMEM *results; + POOL_MEM results(PM_MESSAGE); char* icmd; int status; int timeout; int part; char ed1[50]; - results = get_pool_memory(PM_MESSAGE); - results[0] = 0; + results.c_str()[0] = 0; icmd = dev->device->write_part_command; /* @@ -296,27 +295,27 @@ static bool dvd_write_part(DCR *dcr) * to avoid zapping an existing filesystem. */ part = dev->part; - if (dev->is_mounted() && dev->part == 0) { - dev->part = 1; /* do not wipe out existing filesystem */ + if (dev->is_mounted() && dev->part < 2) { + dev->part = 2; /* do not wipe out existing filesystem */ } edit_device_codes_dev(dev, ocmd.c_str(), icmd); dev->part = part; - /* Wait at most the time a maximum size part is written in DVD 0.5x speed + /* + * Wait at most the time a maximum size part is written in DVD 0.5x speed * FIXME: Minimum speed should be in device configuration */ timeout = dev->max_open_wait + (dev->max_part_size/(1350*1024/2)); Dmsg2(29, "dvd_write_part: cmd=%s timeout=%d\n", ocmd.c_str(), timeout); - status = run_program_full_output(ocmd.c_str(), timeout, results); - Dmsg1(100, "results len=%d\n", strlen(results)); + status = run_program_full_output(ocmd.c_str(), timeout, results.c_str()); + Dmsg1(100, "results len=%d\n", strlen(results.c_str())); if (status != 0) { Mmsg1(dev->errmsg, "Error while writing current part to the DVD: %s", - results); + results.c_str()); Dmsg1(000, "%s", dev->errmsg); dev->dev_errno = EIO; - free_pool_memory(results); return false; } @@ -325,10 +324,10 @@ static bool dvd_write_part(DCR *dcr) make_spooled_dvd_filename(dev, archive_name); unlink(archive_name.c_str()); Dmsg1(29, "unlink(%s)\n", archive_name.c_str()); - free_pool_memory(results); update_free_space_dev(dev); Jmsg(dcr->jcr, M_INFO, 0, _("Remaining free space %s on %s\n"), edit_uint64_with_commas(dev->free_space, ed1), dev->print_name()); + Dmsg1(100, "results=%s\n", results.c_str()); return true; } @@ -340,12 +339,17 @@ static bool dvd_write_part(DCR *dcr) int open_next_part(DCR *dcr) { DEVICE *dev = dcr->dev; - - Dmsg5(29, "Enter: open_next_part part=%d npart=%d dev=%s vol=%s mode=%d\n", + + Dmsg5(29, "Enter: ==== open_next_part part=%d npart=%d dev=%s vol=%s mode=%d\n", dev->part, dev->num_parts, dev->print_name(), dev->VolCatInfo.VolCatName, dev->openmode); + if (!dev->is_dvd()) { + Dmsg1(000, "Device %s is not dvd!!!!\n", dev->print_name()); + return -1; + } + /* When appending, do not open a new part if the current is empty */ - if (dev->can_append() && (dev->part == dev->num_parts) && + if (dev->can_append() && (dev->part >= dev->num_parts) && (dev->part_size == 0)) { Dmsg0(29, "open_next_part exited immediately (dev->part_size == 0).\n"); return dev->fd; @@ -362,20 +366,24 @@ int open_next_part(DCR *dcr) * If we have a part open for write, then write it to * DVD before opening the next part. */ - if (dev->is_dvd() && (dev->part == dev->num_parts) && dev->can_append()) { + if (dev->is_dvd() && (dev->part >= dev->num_parts) && dev->can_append()) { if (!dvd_write_part(dcr)) { return -1; } } + if (dev->part > dev->num_parts) { + Dmsg2(000, "In open_next_part: part=%d nump=%d\n", dev->part, dev->num_parts); + ASSERT(dev->part <= dev->num_parts); + } dev->part_start += dev->part_size; dev->part++; Dmsg2(29, "part=%d num_parts=%d\n", dev->part, dev->num_parts); + /* I think this dev->can_append() should not be there */ if ((dev->num_parts < dev->part) && dev->can_append()) { POOL_MEM archive_name(PM_FNAME); struct stat buf; - /* * First check what is on DVD. If out part is there, we * are in trouble, so bail out. @@ -389,6 +397,7 @@ int open_next_part(DCR *dcr) } dev->num_parts = dev->part; + dev->VolCatInfo.VolCatParts = dev->part; make_spooled_dvd_filename(dev, archive_name); /* makes spool name */ /* Check if the next part exists in spool directory . */ @@ -404,7 +413,10 @@ int open_next_part(DCR *dcr) } } } - + if (dev->num_parts < dev->part) { + dev->num_parts = dev->part; + dev->VolCatInfo.VolCatParts = dev->part; + } Dmsg2(50, "Call dev->open(vol=%s, mode=%d", dev->VolCatInfo.VolCatName, dev->openmode); /* Open next part */ @@ -425,8 +437,10 @@ int open_next_part(DCR *dcr) int open_first_part(DCR *dcr, int mode) { DEVICE *dev = dcr->dev; - Dmsg3(29, "Enter: open_first_part dev=%s Vol=%s mode=%d\n", dev->dev_name, + + Dmsg3(29, "Enter: ==== open_first_part dev=%s Vol=%s mode=%d\n", dev->dev_name, dev->VolCatInfo.VolCatName, dev->openmode); + if (dev->fd >= 0) { close(dev->fd); } @@ -434,7 +448,7 @@ int open_first_part(DCR *dcr, int mode) dev->clear_opened(); dev->part_start = 0; - dev->part = 0; + dev->part = 1; Dmsg2(50, "Call dev->open(vol=%s, mode=%d)\n", dcr->VolCatInfo.VolCatName, mode); @@ -450,10 +464,12 @@ int open_first_part(DCR *dcr, int mode) /* Protected version of lseek, which opens the right part if necessary */ off_t lseek_dev(DEVICE *dev, off_t offset, int whence) { - int pos, openmode; + int openmode; DCR *dcr; + off_t pos; - if (dev->num_parts == 0) { /* If there is only one part, simply call lseek. */ + Dmsg0(100, "Enter lseek_dev\n"); + if (!dev->is_dvd() || dev->num_parts <= 1) { /* If there is only one part, simply call lseek. */ return lseek(dev->fd, offset, whence); } @@ -464,7 +480,8 @@ off_t lseek_dev(DEVICE *dev, off_t offset, int whence) if ((uint64_t)offset >= dev->part_start) { if ((uint64_t)(offset - dev->part_start) < dev->part_size) { /* We are staying in the current part, just seek */ - if ((pos = lseek(dev->fd, (off_t)(offset-dev->part_start), SEEK_SET)) < 0) { + offset -= dev->part_start; /* adjust for start of this part */ + if ((pos = lseek(dev->fd, offset, SEEK_SET)) < 0) { return pos; } else { return pos + dev->part_start; @@ -478,10 +495,12 @@ off_t lseek_dev(DEVICE *dev, off_t offset, int whence) return lseek_dev(dev, offset, SEEK_SET); } } else { - /* pos < dev->part_start : + /* + * pos < dev->part_start : * We need to access a previous part, * so just load the first one, and seek again - * until the right one is loaded */ + * until the right one is loaded + */ if (open_first_part(dcr, dev->openmode) < 0) { Dmsg0(100, "lseek_dev failed while trying to open the first part\n"); return -1; @@ -557,7 +576,8 @@ bool dvd_close_job(DCR *dcr) * that requires mount, it will be written to the device. */ if (dev->is_dvd() && jcr->write_part_after_job && (dev->part_size > 0)) { - Dmsg0(100, "Writing last part because write_part_after_job is set.\n"); + Dmsg1(100, "Writing last part=%d write_partafter_job is set.\n", + dev->part); if (dev->part < dev->num_parts) { Jmsg3(jcr, M_FATAL, 0, _("Error while writing, current part number is less than the total number of parts (%d/%d, device=%s)\n"), dev->part, dev->num_parts, dev->print_name()); @@ -566,14 +586,15 @@ bool dvd_close_job(DCR *dcr) } /* This should be !dvd_write_part(dcr) */ - if (ok && open_next_part(dcr) < 0) { -// if (ok && !dvd_write_part(dcr)) { +// if (ok && open_next_part(dcr) < 0) { + if (ok && !dvd_write_part(dcr)) { Jmsg2(jcr, M_FATAL, 0, _("Unable to write part %s: ERR=%s\n"), dev->print_name(), strerror_dev(dev)); dev->dev_errno = EIO; ok = false; } } + Dmsg1(200, "Set VolCatParts=%d\n", dev->num_parts); dev->VolCatInfo.VolCatParts = dev->num_parts; return ok; } diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index 6737da6c42..97e82cfc0d 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -442,7 +442,7 @@ void release_volume(DCR *dcr) if (dev->is_open()) { offline_or_rewind_dev(dev); } - Dmsg0(190, "===== release_volume ===\n"); + Dmsg0(190, "release_volume\n"); } /* diff --git a/bacula/src/version.h b/bacula/src/version.h index 8ebfb3f035..cb7cc7e033 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #undef VERSION -#define VERSION "1.37.30" -#define BDATE "14 July 2005" -#define LSMDATE "14Jul05" +#define VERSION "1.37.31" +#define BDATE "17 July 2005" +#define LSMDATE "17Jul05" /* Debug flags */ #undef DEBUG -- 2.39.5