#define NPRT(x) (x)?(x):_("*None*")
#if defined(HAVE_WIN32)
+
+#define WIN32_REPARSE_POINT 1
+#define WIN32_MOUNT_POINT 2
+
void InitWinAPIWrapper();
#define OSDependentInit() InitWinAPIWrapper()
POOL_MEM query(PM_MESSAGE);
UAContext *ua;
bool ok = false;
- char ed1[50], ed2[100], ed3[50];
+ char ed1[50], ed2[100];
POOL_DBR spr;
Dmsg1(050, "Prune volumes PoolId=%d\n", jcr->jr.PoolId);
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2008 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.
* (or what is defined for IgnoreDir in this fileset) exists
*/
if (ff_pkt->ignoredir != NULL) {
- struct stat sb;
- char fname[MAXPATHLEN];
+ struct stat sb;
+ char fname[MAXPATHLEN];
- if (strlen(ff_pkt->fname) + strlen("/") +
- strlen(ff_pkt->ignoredir) + 1 > MAXPATHLEN)
- return 1; /* Is this wisdom? */
+ if (strlen(ff_pkt->fname) + strlen("/") +
+ strlen(ff_pkt->ignoredir) + 1 > MAXPATHLEN)
+ return 1; /* Is this wisdom? */
- strcpy(fname, ff_pkt->fname);
- strcat(fname, "/");
- strcat(fname, ff_pkt->ignoredir);
- if (stat(fname, &sb) == 0) {
+ strcpy(fname, ff_pkt->fname);
+ strcat(fname, "/");
+ strcat(fname, ff_pkt->ignoredir);
+ if (stat(fname, &sb) == 0) {
Dmsg2(100, "Directory '%s' ignored (found %s)\n",
- ff_pkt->fname, ff_pkt->ignoredir);
+ ff_pkt->fname, ff_pkt->ignoredir);
return 1; /* Just ignore this directory */
- }
+ }
}
/* Build a canonical directory name with a trailing slash in link var */
* We have set st_rdev to 1 if it is a reparse point, otherwise 0,
* if st_rdev is 2, it is a mount point
*/
- if (have_win32_api() && ff_pkt->statp.st_rdev == 1) {
+#if defined(HAVE_WIN32)
+ if (ff_pkt->statp.st_rdev == WIN32_REPARSE_POINT) {
ff_pkt->type = FT_REPARSE;
}
+#endif
/*
* Note, we return the directory to the calling program (handle_file)
* when we first see the directory (FT_DIRBEGIN.
* to cross, or we may be restricted by a list of permitted
* file systems.
*/
+ bool is_win32_mount_point = false;
+#if defined(HAVE_WIN32)
+ is_win32_mount_point = ff_pkt->statp.st_rdev == WIN32_MOUNT_POINT;
+#endif
if (!top_level && ff_pkt->flags & FO_NO_RECURSION) {
ff_pkt->type = FT_NORECURSE;
recurse = false;
- } else if (!top_level && parent_device != ff_pkt->statp.st_dev) {
+ } else if (!top_level && (parent_device != ff_pkt->statp.st_dev ||
+ is_win32_mount_point)) {
if(!(ff_pkt->flags & FO_MULTIFS)) {
ff_pkt->type = FT_NOFSCHG;
recurse = false;
*/
Dmsg1(100, "bstored: open vol=%s\n", dcr->VolumeName);
if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
- Jmsg3(jcr, M_WARNING, 0, _("Read open device %s Volume \"%s\" failed: ERR=%s\n"),
- dev->print_name(), dcr->VolumeName, dev->bstrerror());
+ if (!dev->poll) {
+ Jmsg3(jcr, M_WARNING, 0, _("Read open device %s Volume \"%s\" failed: ERR=%s\n"),
+ dev->print_name(), dcr->VolumeName, dev->bstrerror());
+ }
goto default_path;
}
Dmsg1(50, "opened dev %s OK\n", dev->print_name());
if (dev->open(dcr, OPEN_READ_ONLY) >= 0) {
continue;
}
+ if (!dev->poll) {
+ Jmsg3(jcr, M_WARNING, 0, _("Read open device %s Volume \"%s\" failed: ERR=%s\n"),
+ dev->print_name(), dcr->VolumeName, dev->bstrerror());
+ }
}
/* Mount a specific volume and no other */
}
/* We freed the device, so reopen it and wake any waiting threads */
if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
- dir->fsend(_("3901 open device failed: ERR=%s\n"),
- dev->bstrerror());
+ dir->fsend(_("3901 Unable to open device %s: ERR=%s\n"),
+ dev->print_name(), dev->bstrerror());
if (dev->blocked() == BST_UNMOUNTED) {
/* We blocked the device, so unblock it */
Dmsg0(100, "Unmounted. Unblocking device\n");
}
} else if (dev->is_tape()) {
if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
- dir->fsend(_("3901 open device failed: ERR=%s\n"),
- dev->bstrerror());
+ dir->fsend(_("3901 Unable to open device %s: ERR=%s\n"),
+ dev->print_name(), dev->bstrerror());
break;
}
read_label(dcr);
if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
/* If device is not tape, attempt to create it */
if (dev->is_tape() || dev->open(dcr, CREATE_READ_WRITE) < 0) {
+ Jmsg3(dcr->jcr, M_WARNING, 0, _("Open device %s Volume \"%s\" failed: ERR=%s\n"),
+ dev->print_name(), dcr->VolumeName, dev->bstrerror());
goto bail_out;
}
}
JCR *jcr = dcr->jcr;
if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
+ Jmsg3(jcr, M_WARNING, 0, _("Open device %s Volume \"%s\" failed: ERR=%s\n"),
+ dev->print_name(), dcr->VolumeName, dev->bstrerror());
return false;
}
Dmsg2(190, "set append found freshly labeled volume. fd=%d dev=%x\n", dev->fd(), dev);
}
/* If DVD, ignore the error, very often you cannot open the device
* (when there is no DVD, or when the one inserted is a wrong one) */
- if (dev->poll || dev->is_dvd() || dev->is_removable()) {
+ if (dev->poll || dev->is_dvd()) {
goto mount_next_vol;
} else {
Jmsg(jcr, M_ERROR, 0, _("Could not open device %s: ERR=%s\n"),
#undef VERSION
#define VERSION "2.3.21"
-#define BDATE "20 May 2008"
-#define LSMDATE "20May08"
+#define BDATE "21 May 2008"
+#define LSMDATE "21May08"
#define PROG_COPYRIGHT "Copyright (C) %d-2008 Free Software Foundation Europe e.V.\n"
#define BYEAR "2008" /* year for copyright messages in progs */
General:
+21May08
+kes Display open() errors except when polling. Previously too
+ many were suppressed. This should fix bug #1070.
+kes Fix Win32 reparse points. Bacula will not recurse into any
+ reparse point directory, including mount points, unless the
+ directory is explicitly mentioned at the top level (same as
+ with Unix). A file that is linked to another file will be
+ backed up -- much as Unix does for hardlinked files.
+ This fixes bug #1041.
20May08
kes Remove double quotes from ChangeLog and ReleaseNotes
kes Remove StorageId test when pruning and recycling (Eric's changes).