From 66ace548f550d22280ee3a55e2ee4db837e266fb Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Tue, 26 Apr 2005 19:46:01 +0000 Subject: [PATCH] - Make SD re-open a device with the right permissions if it was previously opened with something different. This should allow reading read-only Volumes under all circumstances. - Implement restore of a single directory. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1962 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/ReleaseNotes | 9 +++++- bacula/autoconf/configure.in | 2 +- bacula/configure | 2 +- bacula/kernstodo | 17 ++++++----- bacula/src/stored/dev.c | 28 +++++++---------- bacula/src/stored/dev.h | 2 +- bacula/src/stored/device.c | 58 +++++++++++++++++------------------- bacula/src/stored/dircmd.c | 4 +-- 8 files changed, 60 insertions(+), 62 deletions(-) diff --git a/bacula/ReleaseNotes b/bacula/ReleaseNotes index c3cb43ee48..4a3ae4a93b 100644 --- a/bacula/ReleaseNotes +++ b/bacula/ReleaseNotes @@ -19,13 +19,18 @@ Major Changes: - New communications protocol between DIR and SD to reserve drives. The DIR and SD are no longer compatible with 1.36 or lower versions. -- Preliminary Python Event support has been added. See below for +- Python Event support has been added. See below for configuration and details. - DVD writing support, using parts, and a lot of new directives in the Device resource of the Storage configuration file. - Seven new options keywords in a FileSet resource: ignorecase, fstype, hfsplussupport, wilddir, wildfile, regexdir, and regexfile. See below for details. +- Restore of all files for a Job or set of jobs even if the file + records have been removed from the catalog. +- Restore of a directory (non-recursive, i.e. only one level). +- Support for Unicode filenames on Win32. +- Support for TLS (ssl) between all the daemon connections. New Directives: - New Run directive in Job resource of DIR. It permits @@ -139,6 +144,8 @@ Other Items: (http://fy.chalmers.se/~appro/linux/DVD+RW/). - Part files support: File volumes can now be splitted in multiple files, called "parts". + +NOTE THE FOLLOWING IS NOW OUT OF DATE!!!! - Python scripting support: A Python script will be called at particular points or conditions in Bacula called Events. The currently defined Events are called: diff --git a/bacula/autoconf/configure.in b/bacula/autoconf/configure.in index 92b3246d07..89858a2cec 100644 --- a/bacula/autoconf/configure.in +++ b/bacula/autoconf/configure.in @@ -66,7 +66,7 @@ AC_PATH_PROG(PYTHON, python, python) AC_PATH_PROG(GROWISOFS, growisofs, growisofs) AC_PATH_PROG(DVDRWMEDIAINFO, dvd+rw-mediainfo, dvd+rw-mediainfo) AC_PATH_PROG(PKGCONFIG, pkg-config, pkg-config) -AC_PATH_PROG(WXCONFIG, wx-config, /opt/gnome/bin/wx-config) +AC_PATH_PROG(WXCONFIG, wx-config, wx-config) AC_PATH_PROG(CDRECORD, cdrecord, cdrecord) AC_PATH_PROG(PIDOF, pidof, pidof) AC_PROG_AWK diff --git a/bacula/configure b/bacula/configure index 2b315d8626..88b90e7d11 100755 --- a/bacula/configure +++ b/bacula/configure @@ -3986,7 +3986,7 @@ do done done - test -z "$ac_cv_path_WXCONFIG" && ac_cv_path_WXCONFIG="/opt/gnome/bin/wx-config" + test -z "$ac_cv_path_WXCONFIG" && ac_cv_path_WXCONFIG="wx-config" ;; esac fi diff --git a/bacula/kernstodo b/bacula/kernstodo index eb65aeae6a..b16c3f199b 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -32,6 +32,8 @@ Autochangers: - Make "update slots" when pointing to Autochanger, remove all Volumes from other drives. "update slots all-drives"? +Document: +- Pruning with Admin job. For 1.37: - Python: @@ -47,12 +49,7 @@ For 1.37: - If drive is opened read/write, close it and re-open read-only if doing a restore, and vice-versa. -- SD crashes after a tape restore then doing a backup. -- Implement some way to turn off automatic pruning in Jobs. -- Implement a way an Admin Job can prune, possibly multiple - clients -- Python script? - Implement "NewVolumeEachJob = yes|no" in Dir. -- Look at Preben's acl.c error handling code. - Implement Maximum Job Spool Size - Remove all old Device resource code in Dir and code to pass it back in SD -- better, rework it to pass back device statistics. @@ -61,8 +58,6 @@ For 1.37: - Check locking of resources -- be sure to lock devices where previously resources were locked. - Add global lock on all devices when creating a device structure. -- Look at adding full Volume and Pool information to a Volume - label so that bscan can get *all* the info. - Fix FD JobType to be set before RunBeforeJob in FD. @@ -73,6 +68,8 @@ Ideas: - Autorestart on crash. Maybe in 1.37: +- Look at adding full Volume and Pool information to a Volume + label so that bscan can get *all* the info. - If the user puts "Purge Oldest Volume = yes" or "Recycle Oldest Volume = yes" and there is only one volume in the pool, refuse to do it -- otherwise he fills the Volume, then immediately starts reusing it. @@ -1323,3 +1320,9 @@ Block Position: 0 - Look at dird_conf.c:1000: warning: `int size' might be used uninitialized in this function - Indicate when a Job is purged/pruned during restore. +- Implement some way to turn off automatic pruning in Jobs. +- Implement a way an Admin Job can prune, possibly multiple + clients -- Python script? +- Look at Preben's acl.c error handling code. +- SD crashes after a tape restore then doing a backup. + diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index a6fbbe17aa..b758b2373c 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -281,20 +281,11 @@ int open_dev(DEVICE *dev, char *VolName, int mode) { if (dev->is_open()) { - /* - * *****FIXME***** how to handle two threads wanting - * different volumes mounted???? E.g. one is waiting - * for the next volume to be mounted, and a new job - * starts and snatches up the device. - */ - if (VolName && strcmp(dev->VolCatInfo.VolCatName, VolName) != 0) { - return -1; + if (dev->openmode == mode) { + return dev->fd; + } else { + close(dev->fd); /* close so correct mode will be used */ } - dev->use_count++; - Mmsg2(dev->errmsg, _("WARNING!!!! device %s opened %d times!!!\n"), - dev->print_name(), dev->use_count); - Emsg1(M_WARNING, 0, "%s", dev->errmsg); - return dev->fd; } if (VolName) { bstrncpy(dev->VolCatInfo.VolCatName, VolName, sizeof(dev->VolCatInfo.VolCatName)); @@ -321,6 +312,7 @@ static void open_tape_device(DEVICE *dev, int mode) int timeout; int ioerrcnt = 10; Dmsg0(29, "open_dev: device is tape\n"); + if (mode == OPEN_READ_WRITE) { dev->mode = O_RDWR | O_BINARY; } else if (mode == OPEN_READ_ONLY) { @@ -376,16 +368,17 @@ open_again: break; } if (dev->fd >= 0) { - if (mode != 0) { - /* If opened in non-block mode, close it an open it normally */ - mode = 0; + /* If opened in non-block mode, close it an open it normally */ + if (nonblocking) { + nonblocking = 0; close(dev->fd); 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 */ + update_pos_dev(dev); /* update position */ set_os_device_parameters(dev); /* do system dependent stuff */ Dmsg0(500, "Open OK\n"); } @@ -1557,6 +1550,7 @@ static void do_close(DEVICE *dev) dev->tid = 0; } dev->use_count = 0; + dev->openmode = 0; } /* diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 9439d781ca..724ce2e1c4 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -189,7 +189,7 @@ public: /* New access control in process of being implemented */ brwlock_t lock; /* New mutual exclusion lock */ - int use_count; /* usage count on this device */ + int use_count; /* usage count on this device 0 or 1 */ int fd; /* file descriptor */ int capabilities; /* capabilities mask */ int state; /* state mask */ diff --git a/bacula/src/stored/device.c b/bacula/src/stored/device.c index 7653c2d6a3..939ac7e9ff 100644 --- a/bacula/src/stored/device.c +++ b/bacula/src/stored/device.c @@ -264,21 +264,19 @@ bool first_open_device(DEVICE *dev) return true; } - if (!dev->is_open()) { - int mode; - if (dev_cap(dev, CAP_STREAM)) { - mode = OPEN_WRITE_ONLY; - } else { - mode = OPEN_READ_WRITE; - } - Dmsg0(129, "Opening device.\n"); - dev->open_nowait = true; - if (open_dev(dev, NULL, mode) < 0) { - Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg); - dev->open_nowait = false; - unlock_device(dev); - return false; - } + int mode; + if (dev_cap(dev, CAP_STREAM)) { + mode = OPEN_WRITE_ONLY; + } else { + mode = OPEN_READ_WRITE; + } + Dmsg0(129, "Opening device.\n"); + dev->open_nowait = true; + if (open_dev(dev, NULL, mode) < 0) { + Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg); + dev->open_nowait = false; + unlock_device(dev); + return false; } Dmsg1(129, "open_dev %s OK\n", dev->print_name()); dev->open_nowait = false; @@ -293,23 +291,21 @@ bool open_device(DCR *dcr) { DEVICE *dev = dcr->dev; /* Open device */ - if (!dev->is_open()) { - int mode; - if (dev_cap(dev, CAP_STREAM)) { - mode = OPEN_WRITE_ONLY; - } else { - mode = OPEN_READ_WRITE; - } - if (open_dev(dev, dcr->VolCatInfo.VolCatName, mode) < 0) { - /* If polling, ignore the error */ - if (!dev->poll) { - Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device %s: ERR=%s\n"), - dev->print_name(), strerror_dev(dev)); - Pmsg2(000, "Unable to open archive %s: ERR=%s\n", - dev->print_name(), strerror_dev(dev)); - } - return false; + int mode; + if (dev_cap(dev, CAP_STREAM)) { + mode = OPEN_WRITE_ONLY; + } else { + mode = OPEN_READ_WRITE; + } + if (open_dev(dev, dcr->VolCatInfo.VolCatName, mode) < 0) { + /* If polling, ignore the error */ + if (!dev->poll) { + Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device %s: ERR=%s\n"), + dev->print_name(), strerror_dev(dev)); + Pmsg2(000, "Unable to open archive %s: ERR=%s\n", + dev->print_name(), strerror_dev(dev)); } + return false; } return true; } diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index e00cc4fcdd..5884e57559 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -610,7 +610,7 @@ static bool mount_cmd(JCR *jcr) } } else { if (!dev->is_tape()) { - bnet_fsend(dir, _("3906 cannot mount non-tape.\n")); + /* Nothing to do */ break; } if (open_dev(dev, NULL, OPEN_READ_WRITE) < 0) { @@ -667,7 +667,6 @@ static bool unmount_cmd(JCR *jcr) } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) { Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting, dev->dev_blocked); - open_dev(dev, NULL, 0); /* fake open for close */ offline_or_rewind_dev(dev); force_close_dev(dev); dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP; @@ -694,7 +693,6 @@ static bool unmount_cmd(JCR *jcr) /* block_device(dev, BST_UNMOUNTED); replace with 2 lines below */ dev->dev_blocked = BST_UNMOUNTED; dev->no_wait_id = 0; - open_dev(dev, NULL, 0); /* fake open for close */ offline_or_rewind_dev(dev); force_close_dev(dev); bnet_fsend(dir, _("3002 Device %s unmounted.\n"), -- 2.39.5