+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
/* 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);
/*
* (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 */
}
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;
}
}
}
-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) {
}
/* 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;
}
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);
}
/*
* 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);
}
}