From 748c9bbc0d9beb22a656e7a7375129883fe59405 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Fri, 8 Jul 2005 15:46:39 +0000 Subject: [PATCH] - Correct a NULL pointer reference in the mount command. - Correct typo in Copyright - Add detection of EOM for IBM drives (i.e. errno == ENOSPC) git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2182 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/ChangeLog | 110 ++++++++++++++++++ bacula/kes-1.37 | 4 +- bacula/src/stored/dev.c | 230 ++++++++++++++++++------------------- bacula/src/stored/dev.h | 9 +- bacula/src/stored/dircmd.c | 2 +- bacula/src/version.h | 4 +- 6 files changed, 238 insertions(+), 121 deletions(-) diff --git a/bacula/ChangeLog b/bacula/ChangeLog index aab0112de7..f2e3d5539a 100644 --- a/bacula/ChangeLog +++ b/bacula/ChangeLog @@ -1,4 +1,114 @@ +Changes to 1.37.28: +08Jul05 +- Correct a NULL pointer reference in the mount command. +- Correct typo in Copyright +- Add detection of EOM for IBM drives (i.e. errno == ENOSPC) +07Jul05 +- Remove temp file created in mtx-changer script. +- Make fsf_dev() into a class method. +06Jul05 +- Modify mtx-changer.in script to return slot:barcode for + Volumes that are loaded in the drives. +- Correct some more places where dev->is_blocked() needs + to be checked in dircmd.c in SD. +- Update doc. +05Jul05 +- Add code to ensure that reserved but unused volumes + are freed. +- Correct how Volumes are mounted and handled so that the SD + does not get stuck if multiple volumes are used (recycling, + relabling, ...) +- Correct bug where you could relabel a volume while it + was being acquired -- created chaos. +04Jul05 +- Correct seg fault caused by open() calling sequence change. +03Jul05 +- Add new rc-chio-changer script by Rudolf Cejka to + examples/autochangers +- Apply Rudolf's changes to bacula.in +- Expand the space from 8 to 10 characters in editing + file sizes for restore and dir of catalog, otherwise + GB sizes are truncated -- fixes bug report. +- Modify wx-console to know about 10 character widths. +- Allow decending into top level directory if "recurse=no" + is set. Fixes a bug report. +- Install pthreadVCE.dll when installing console or wx-console + on Win32 systems. Fixes bug report. +02Jul05 +- Tweak dvd-writepart script to prevent door from opening/closing + so much. +- Remove GROUP BY in several PostgreSQL commands to prevent error. + Resolves bug report. +- Ensure that < as first character of filename list is not treated + as a directory for restore. +- Add debug to heartbeat in FD as it seems to go into an + infinite loop from time to time during SD failure in DVD writing. +- Add more debug code to dvd writing. +- Attempt not to destroy existing fs on DVD. +30Jun05 +- Detect device mounted for DVD and suppress be sure to + mount message after label. +- Set Cleaning tape status to "Cleaning" and force no + MediaType. +- Get DVD writing working with new standard Bacula open() + code. +- Rename get_filename() to make more sense. +- Detect "is already mounted on" on mount command so to avoid + error if device is already mounted. +- Eliminated guess_name() code. It may be necessary to + add it back later. +- Eliminate seg fault from printing invalid results. +- Make dvd_write_part() bool. + +29Jun05 +- Attempt to fix DVD writing by eliminating a number of the + DVD subroutines to simplify. +- Modify DEVICE::open() to take dcr as first argument. This + will permit providing more info to DVD opening. +- Fix scanning for time/size items which in some cases + ate the next line. +- Eliminate read_dvd_volume_label(). New code (not yet written) + *must* open dvd appropriately before calling + read_dev_volume_label. +- Modify open_first_part() open_next_part() to take DCR as + argument. +- Make label command from console work on DVDs. +- Make mount command from console work on DVDs. + Unmount does not work yet. + +Changes to 1.37.27: +27Jun05 +- Add Database vendor to CatalogRes tuple for Python. +- Update doc +- Implement DoesVolumeExist(Vol) for Python. +- Prevent python command from seg faulting if no arg given. + +Changes to 1.37.26: +26Jun05 +- Add set_mode method in DEVICE. +- Correct set_mode method in DEVICE +- Add more DVD debug info +23Jun05 +- Check for incorrect duration and size modifiers in conf files. +22Jun05: +- Make Version a tuple (version, build-date) +- Add CatalogRes tuple (DBName, Address, User, Password, + Socket, Port) +- Add Version, ConfigFile, and WorkingDir as Python attributes + in the Director. +- Implement code (principally for Win32) that on failure to + create a file, it will cd into the directory and attempt + to create the file using a relative path. This avoids creating + files with paths which fail on Win32. +- Fix parsing of times and sizes with decimal numbers. +- Make free_volume_list() in SD work if vol list is not + initialized (./bacula-sd -t). +21Jun05: +- Add debug error printout when open() fails. +- If open() of DVD fails in mount.c, return false. +- Split open() code for DVD into separate subroutine in dev.c + Changes to 1.37.25 released on 20 Jun 05: 20Jun05: - Fix bug where Storage daemon gets confused about what diff --git a/bacula/kes-1.37 b/bacula/kes-1.37 index 6d292ff814..4a821b655f 100644 --- a/bacula/kes-1.37 +++ b/bacula/kes-1.37 @@ -4,9 +4,11 @@ General: Changes to 1.37.28: -07Jul05 +08Jul05 +- Correct a NULL pointer reference in the mount command. - Correct typo in Copyright - Add detection of EOM for IBM drives (i.e. errno == ENOSPC) +07Jul05 - Remove temp file created in mtx-changer script. - Make fsf_dev() into a class method. 06Jul05 diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 9c6a5e5e1a..0addd2c0fa 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -86,9 +86,6 @@ void update_free_space_dev(DEVICE* dev); /* Forward referenced functions */ void set_os_device_parameters(DEVICE *dev); static bool dev_get_os_pos(DEVICE *dev, struct mtget *mt_stat); -static void open_tape_device(DCR *dcr, int mode); -static void open_file_device(DCR *dcr, int mode); -static void open_dvd_device(DCR *dcr, int mode); static char *mode_to_str(int mode); /* @@ -265,10 +262,10 @@ init_dev(JCR *jcr, DEVRES *device) * (archive_name) with the VolName concatenated. */ int -DEVICE::open(DCR *dcr, int mode) +DEVICE::open(DCR *dcr, int omode) { if (is_open()) { - if (openmode == mode) { + if (openmode == omode) { return fd; } else { ::close(fd); /* use system close so correct mode will be used on open */ @@ -279,17 +276,17 @@ DEVICE::open(DCR *dcr, int mode) } Dmsg4(29, "open dev: tape=%d dev_name=%s vol=%s mode=%s\n", is_tape(), - dev_name, VolCatInfo.VolCatName, mode_to_str(mode)); + dev_name, VolCatInfo.VolCatName, mode_to_str(omode)); state &= ~(ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF); label_type = B_BACULA_LABEL; if (is_tape() || is_fifo()) { - open_tape_device(dcr, mode); + open_tape_device(omode); } else if (is_dvd()) { Dmsg1(100, "call open_dvd_device mode=%s\n", mode_to_str(mode)); - open_dvd_device(dcr, mode); + open_dvd_device(dcr, omode); } else { Dmsg1(100, "call open_file_device mode=%d\n", mode_to_str(mode)); - open_file_device(dcr, mode); + open_file_device(omode); } return fd; } @@ -318,32 +315,32 @@ void DEVICE::set_mode(int new_mode) } } -static void open_tape_device(DCR *dcr, int mode) +void DEVICE::open_tape_device(int omode) { - DEVICE *dev = dcr->dev; int nonblocking = 0;; - dev->file_size = 0; + file_size = 0; int timeout; int ioerrcnt = 10; Dmsg0(29, "open dev: device is tape\n"); - dev->set_mode(mode); - timeout = dev->max_open_wait; + set_mode(omode); + timeout = max_open_wait; errno = 0; - if (dev->open_nowait) { + if (open_nowait) { /* Set wait counters to zero for no wait */ timeout = ioerrcnt = 0; /* Open drive in non-block mode */ nonblocking = O_NONBLOCK; } - if (dev->is_fifo() && timeout) { + if (is_fifo() && timeout) { /* Set open timer */ - dev->tid = start_thread_timer(pthread_self(), timeout); + tid = start_thread_timer(pthread_self(), timeout); } /* If busy retry each second for max_open_wait seconds */ open_again: - Dmsg1(500, "Try open %s\n", dev->dev_name); - while ((dev->fd = open(dev->dev_name, dev->mode, MODE_RW+nonblocking)) < 0) { + Dmsg1(500, "Try open %s\n", dev_name); + /* Use system open() */ + while ((fd = ::open(dev_name, mode, MODE_RW+nonblocking)) < 0) { berrno be; Dmsg2(500, "Open error errno=%d ERR=%s\n", errno, be.strerror()); if (errno == EINTR || errno == EAGAIN) { @@ -352,7 +349,7 @@ open_again: } /* Busy wait for specified time (default = 5 mins) */ if (errno == EBUSY && timeout-- > 0) { - Dmsg2(100, "Device %s busy. ERR=%s\n", dev->print_name(), be.strerror()); + Dmsg2(100, "Device %s busy. ERR=%s\n", print_name(), be.strerror()); bmicrosleep(1, 0); continue; } @@ -362,91 +359,91 @@ open_again: Dmsg0(500, "Continue open\n"); continue; } - dev->dev_errno = errno; - Mmsg2(dev->errmsg, _("Unable to open device %s: ERR=%s\n"), - dev->print_name(), be.strerror(dev->dev_errno)); + dev_errno = errno; + Mmsg2(errmsg, _("Unable to open device %s: ERR=%s\n"), + print_name(), be.strerror(dev_errno)); /* Stop any open timer we set */ - if (dev->tid) { - stop_thread_timer(dev->tid); - dev->tid = 0; + if (tid) { + stop_thread_timer(tid); + tid = 0; } - Emsg0(M_FATAL, 0, dev->errmsg); + Emsg0(M_FATAL, 0, errmsg); break; } - if (dev->fd >= 0) { + if (fd >= 0) { /* If opened in non-block mode, close it an open it normally */ if (nonblocking) { nonblocking = 0; - close(dev->fd); + ::close(fd); /* use system close() */ goto open_again; } - dev->openmode = mode; /* save open mode */ - dev->dev_errno = 0; - dev->state |= ST_OPENED; - dev->use_count = 1; - update_pos_dev(dev); /* update position */ - set_os_device_parameters(dev); /* do system dependent stuff */ + openmode = mode; /* save open mode */ + dev_errno = 0; + set_opened(); + use_count = 1; + update_pos_dev(this); /* update position */ + set_os_device_parameters(this); /* do system dependent stuff */ Dmsg0(500, "Open OK\n"); } /* Stop any open() timer we started */ - if (dev->tid) { - stop_thread_timer(dev->tid); - dev->tid = 0; + if (tid) { + stop_thread_timer(tid); + tid = 0; } - Dmsg1(29, "open dev: tape %d opened\n", dev->fd); + Dmsg1(29, "open dev: tape %d opened\n", fd); } /* * Open a file device */ -static void open_file_device(DCR *dcr, int mode) +void DEVICE::open_file_device(int omode) { - DEVICE *dev = dcr->dev; POOL_MEM archive_name(PM_FNAME); /* * Handle opening of File Archive (not a tape) */ - Dmsg3(29, "Enter: open_file_dev: %s dev=%s mode=%s\n", dev->is_dvd()?"DVD":"disk", - archive_name.c_str(), mode_to_str(mode)); + Dmsg3(29, "Enter: open_file_dev: %s dev=%s mode=%s\n", is_dvd()?"DVD":"disk", + archive_name.c_str(), mode_to_str(omode)); - if (dev->VolCatInfo.VolCatName[0] == 0) { - Mmsg(dev->errmsg, _("Could not open file device %s. No Volume name given.\n"), - dev->print_name()); - dev->fd = -1; + if (VolCatInfo.VolCatName[0] == 0) { + Mmsg(errmsg, _("Could not open file device %s. No Volume name given.\n"), + print_name()); + fd = -1; return; } - pm_strcpy(archive_name, dev->dev_name); + pm_strcpy(archive_name, dev_name); if (archive_name.c_str()[strlen(archive_name.c_str())-1] != '/') { pm_strcat(archive_name, "/"); } - pm_strcat(archive_name, dev->VolCatInfo.VolCatName); + pm_strcat(archive_name, VolCatInfo.VolCatName); - Dmsg3(29, "open dev: %s dev=%s mode=%s\n", dev->is_dvd()?"DVD":"disk", - archive_name.c_str(), mode_to_str(mode)); - dev->openmode = mode; + Dmsg3(29, "open dev: %s dev=%s mode=%s\n", is_dvd()?"DVD":"disk", + archive_name.c_str(), mode_to_str(omode)); + openmode = omode; - dev->set_mode(mode); + set_mode(omode); /* If creating file, give 0640 permissions */ - Dmsg3(29, "mode=%s open(%s, 0x%x, 0640)\n", mode, archive_name.c_str(), - mode_to_str(dev->mode)); - if ((dev->fd = open(archive_name.c_str(), dev->mode, 0640)) < 0) { + Dmsg3(29, "mode=%s open(%s, 0x%x, 0640)\n", mode_to_str(omode), + archive_name.c_str(), mode); + /* Use system open() */ + if ((fd = ::open(archive_name.c_str(), mode, 0640)) < 0) { berrno be; - dev->dev_errno = errno; - Mmsg2(dev->errmsg, _("Could not open: %s, ERR=%s\n"), archive_name.c_str(), + dev_errno = errno; + Mmsg2(errmsg, _("Could not open: %s, ERR=%s\n"), archive_name.c_str(), be.strerror()); - Dmsg1(29, "open failed: %s", dev->errmsg); - Emsg0(M_FATAL, 0, dev->errmsg); + Dmsg1(29, "open failed: %s", errmsg); + Emsg0(M_FATAL, 0, errmsg); } else { - dev->dev_errno = 0; - dev->state |= ST_OPENED; - dev->use_count = 1; - update_pos_dev(dev); /* update position */ + dev_errno = 0; + set_opened(); + use_count = 1; + update_pos_dev(this); /* update position */ } Dmsg5(29, "open dev: %s fd=%d opened, part=%d/%d, part_size=%u\n", - dev->is_dvd()?"DVD":"disk", dev->fd, dev->part, dev->num_parts, - dev->part_size); + is_dvd()?"DVD":"disk", fd, part, num_parts, + part_size); } /* @@ -454,99 +451,100 @@ static void open_file_device(DCR *dcr, int mode) * has the desired Volume name, but there is NO assurance that * any other field of VolCatInfo is correct. */ -static void open_dvd_device(DCR *dcr, int mode) +void DEVICE::open_dvd_device(DCR *dcr, int omode) { - DEVICE *dev = dcr->dev; POOL_MEM archive_name(PM_FNAME); struct stat filestat; /* * Handle opening of DVD Volume */ - Dmsg3(29, "Enter: open_dvd_dev: %s dev=%s mode=%s\n", dev->is_dvd()?"DVD":"disk", - archive_name.c_str(), mode_to_str(mode)); + Dmsg3(29, "Enter: open_dvd_dev: %s dev=%s mode=%s\n", is_dvd()?"DVD":"disk", + archive_name.c_str(), mode_to_str(omode)); - if (dev->VolCatInfo.VolCatName[0] == 0) { - Mmsg(dev->errmsg, _("Could not open file device %s. No Volume name given.\n"), - dev->print_name()); - dev->fd = -1; + if (VolCatInfo.VolCatName[0] == 0) { + Mmsg(errmsg, _("Could not open file device %s. No Volume name given.\n"), + print_name()); + fd = -1; return; } - if (dev->part == 0) { - dev->file_size = 0; + if (part == 0) { + file_size = 0; } - dev->part_size = 0; + part_size = 0; - if (mount_dev(dev, 1) < 0) { - Mmsg(dev->errmsg, _("Could not mount device %s.\n"), - dev->print_name()); - Emsg0(M_FATAL, 0, dev->errmsg); - dev->fd = -1; + if (mount_dev(this, 1) < 0) { + 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", dev->is_dvd()?"DVD":"disk", - archive_name.c_str(), mode_to_str(mode)); - dev->openmode = mode; + Dmsg3(29, "open dev: %s dev=%s mode=%s\n", is_dvd()?"DVD":"disk", + archive_name.c_str(), mode_to_str(omode)); + openmode = omode; /* * If we are not trying to access the last part, set mode to * OPEN_READ_ONLY as writing would be an error. */ - if (dev->part < dev->num_parts) { - mode = OPEN_READ_ONLY; + if (part < num_parts) { + omode = OPEN_READ_ONLY; } - dev->set_mode(mode); + set_mode(omode); /* * If we are opening it read-only, it is *probably* on the * DVD, so try the DVD first, otherwise look in the spool dir. */ - if (mode == OPEN_READ_ONLY) { - make_mounted_dvd_filename(dev, archive_name); + if (omode == OPEN_READ_ONLY) { + make_mounted_dvd_filename(this, archive_name); } else { - make_spooled_dvd_filename(dev, archive_name); + make_spooled_dvd_filename(this, archive_name); } /* If creating file, give 0640 permissions */ - Dmsg3(29, "mode=%s open(%s, 0x%x, 0640)\n", mode_to_str(mode), - archive_name.c_str(), dev->mode); - if ((dev->fd = open(archive_name.c_str(), dev->mode, 0640)) < 0) { + Dmsg3(29, "mode=%s open(%s, 0x%x, 0640)\n", mode_to_str(omode), + archive_name.c_str(), mode); + /* Use system open() */ + if ((fd = ::open(archive_name.c_str(), mode, 0640)) < 0) { berrno be; - dev->dev_errno = errno; - Mmsg2(dev->errmsg, _("Could not open: %s, ERR=%s\n"), archive_name.c_str(), + dev_errno = errno; + Mmsg2(errmsg, _("Could not open: %s, ERR=%s\n"), archive_name.c_str(), be.strerror()); - Dmsg1(29, "open failed: %s", dev->errmsg); - if (mode == OPEN_READ_ONLY) { - make_spooled_dvd_filename(dev, archive_name); - dev->fd = open(archive_name.c_str(), dev->mode, 0640); /* try on spool */ + Dmsg1(29, "open failed: %s", errmsg); + if (omode == OPEN_READ_ONLY) { + make_spooled_dvd_filename(this, archive_name); + /* Use system open() */ + fd = ::open(archive_name.c_str(), mode, 0640); /* try on spool */ } } - if (dev->fd >= 0) { + if (fd >= 0) { /* Get size of file */ - if (fstat(dev->fd, &filestat) < 0) { + if (fstat(fd, &filestat) < 0) { berrno be; - dev->dev_errno = errno; - Mmsg2(dev->errmsg, _("Could not fstat: %s, ERR=%s\n"), archive_name.c_str(), + dev_errno = errno; + Mmsg2(errmsg, _("Could not fstat: %s, ERR=%s\n"), archive_name.c_str(), be.strerror()); - Dmsg1(29, "open failed: %s", dev->errmsg); - close(dev->fd); - dev->fd = -1; + Dmsg1(29, "open failed: %s", errmsg); + /* Use system close() */ + ::close(fd); + fd = -1; } else { - dev->part_size = filestat.st_size; - dev->dev_errno = 0; - dev->state |= ST_OPENED; - dev->use_count = 1; - update_pos_dev(dev); /* update position */ + part_size = filestat.st_size; + dev_errno = 0; + set_opened(); + use_count = 1; + update_pos_dev(this); /* update position */ } } Dmsg4(29, "open dev: DVD fd=%d opened, part=%d/%d, part_size=%u\n", - dev->fd, dev->part, dev->num_parts, dev->part_size); - if (dev->is_open() && dev->is_dvd() && (mode != OPEN_READ_ONLY) && - (dev->free_space_errno == 0 || dev->num_parts == dev->part)) { - update_free_space_dev(dev); + fd, part, num_parts, part_size); + if (is_open() && is_dvd() && (omode != OPEN_READ_ONLY) && + (free_space_errno == 0 || num_parts == part)) { + update_free_space_dev(this); } } diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 9422733674..726ec18939 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -320,12 +320,19 @@ public: void unblock(); /* in dev.c */ void close(); /* in dev.c */ int open(DCR *dcr, int mode); /* in dev.c */ - void set_mode(int mode); /* in dev.c */ + void set_blocked(int block) { dev_blocked = block; }; int get_blocked() const { return dev_blocked; }; const char *print_blocked() const; /* in dev.c */ bool is_blocked() const { return dev_blocked != BST_NOT_BLOCKED; }; + +private: + void set_mode(int omode); /* in dev.c */ + void open_tape_device(int omode); /* in dev.c */ + void open_file_device(int omode); /* in dev.c */ + void open_dvd_device(DCR *dcr, int omode); /* in dev.c */ + }; /* Note, these return int not bool! */ diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index bb54778218..43397cae5e 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -606,7 +606,7 @@ static bool mount_cmd(JCR *jcr) dev->print_name()); } } else if (dev->is_tape()) { - if (dev->open(NULL, OPEN_READ_WRITE) < 0) { + if (dev->open(dcr, OPEN_READ_WRITE) < 0) { bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"), strerror_dev(dev)); break; diff --git a/bacula/src/version.h b/bacula/src/version.h index a9b40e5fad..4ca58bef97 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #undef VERSION #define VERSION "1.37.28" -#define BDATE "07 July 2005" -#define LSMDATE "07Jul05" +#define BDATE "08 July 2005" +#define LSMDATE "08Jul05" /* Debug flags */ #undef DEBUG -- 2.39.5