]> git.sur5r.net Git - bacula/bacula/commitdiff
kes Display open() errors except when polling. Previously too
authorKern Sibbald <kern@sibbald.com>
Wed, 21 May 2008 13:05:15 +0000 (13:05 +0000)
committerKern Sibbald <kern@sibbald.com>
Wed, 21 May 2008 13:05:15 +0000 (13:05 +0000)
     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.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@7004 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/baconfig.h
bacula/src/dird/autoprune.c
bacula/src/findlib/find_one.c
bacula/src/stored/acquire.c
bacula/src/stored/dircmd.c
bacula/src/stored/label.c
bacula/src/stored/mount.c
bacula/src/version.h
bacula/src/win32/compat/compat.cpp
bacula/technotes-2.3

index f965033d606cce62f5f714d79222ce2d5178a170..af2bf44e0bf633f7c397440b594ce2d1c2bc55a1 100644 (file)
 #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()
index 2b8e8cb91fa671da6d739da91ce8dac75b5ef48d..cc812c5cbba5e2d9f5dfd9737ff02f4ba212e934 100644 (file)
@@ -96,7 +96,7 @@ bool prune_volumes(JCR *jcr, bool InChanger, MEDIA_DBR *mr)
    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);
index 7c22ee0a4156957435fdd7ea301c6ed871bb51dd..c27060ca5d77c19a704284c6f4acd3d960decfee 100644 (file)
@@ -1,7 +1,7 @@
 /*
    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.
@@ -518,21 +518,21 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt,
        * (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 */
@@ -557,9 +557,11 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt,
        * 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.
@@ -597,10 +599,15 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt,
        * 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;
index fc72f8a7c244adef04b47d028cf8df4048983c58..d670beba2c07d8bb9198f10d492fec97af7337c3 100644 (file)
@@ -219,8 +219,10 @@ bool acquire_device_for_read(DCR *dcr)
        */
       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());
@@ -287,6 +289,10 @@ default_path:
             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 */
index b61e2e66305f9f7d29791aa808067dbf5291a10b..a6208244e59928797ab3da2a8fc7bc81de6f3367 100644 (file)
@@ -673,8 +673,8 @@ static bool mount_cmd(JCR *jcr)
             }
             /* 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");
@@ -730,8 +730,8 @@ static bool mount_cmd(JCR *jcr)
                }
             } 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);
index 3d791f4fb0e0a360ac3881c4e0e88434214cbf56..db385275393c1b1d80bb60c59929d603f11f852e 100644 (file)
@@ -339,6 +339,8 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName,
    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;
       }
    }
@@ -435,6 +437,8 @@ bool rewrite_volume_label(DCR *dcr, bool recycle)
    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);
index 6e5e1ff3fa3433d9a644d9b8cb9a59b378b56171..2f292de2091c3d28fd4cd36e465ac069f61ee6ce 100644 (file)
@@ -227,7 +227,7 @@ mount_next_vol:
       }
       /* 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"),
index 91ce8a93b074e448ff666c3dca603c8bb3013486..9f4b0157ed3db0eee66bb7d1232ffbdef49106fc 100644 (file)
@@ -4,8 +4,8 @@
 
 #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 */
index f224c93de3093705a891ea4a36a7ae1c72d943ff..2583ad290426c4ebc571db923517750cadd6f186 100644 (file)
@@ -685,6 +685,8 @@ statDir(const char *file, struct stat *sb)
       LocalFree((void *)err);
       errno = b_errno_win32;
       return -1;
+   } else {
+      FindClose(h);
    }
 
    sb->st_mode = 0777;               /* start with everything */
@@ -696,12 +698,23 @@ statDir(const char *file, struct stat *sb)
        sb->st_mode |= S_ISVTX; /* use sticky bit -> hidden */
    sb->st_mode |= S_IFDIR;
 
-   /* Use st_rdev to store reparse attribute */
-   sb->st_rdev = (*pdwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) ? 1 : 0; 
-   if (sb->st_rdev == 1 && *pdwReserved0 & IO_REPARSE_TAG_MOUNT_POINT) {
-      sb->st_rdev = 2;                /* mount point */
-   }
-
+   /* 
+    * Store reparse/mount point info in st_rdev.  Note a
+    *  Win32 reparse point (junction point) is like a link
+    *  though it can have many properties (directory link,
+    *  soft link, hard link, HSM, ...
+    *  A mount point is a reparse point where another volume
+    *  is mounted, so it is like a Unix mount point (change of
+    *  filesystem).
+    */
+   if (*pdwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+      if (*pdwReserved0 & IO_REPARSE_TAG_MOUNT_POINT) {
+         sb->st_rdev = WIN32_MOUNT_POINT;           /* mount point */
+      } else {
+         sb->st_rdev = WIN32_REPARSE_POINT;         /* reparse point */
+      }
+   }  
+   Dmsg2(100, "st_rdev=%d file=%s\n", sb->st_rdev, file);
    sb->st_size = *pnFileSizeHigh;
    sb->st_size <<= 32;
    sb->st_size |= *pnFileSizeLow;
@@ -711,7 +724,6 @@ statDir(const char *file, struct stat *sb)
    sb->st_atime = cvt_ftime_to_utime(*pftLastAccessTime);
    sb->st_mtime = cvt_ftime_to_utime(*pftLastWriteTime);
    sb->st_ctime = cvt_ftime_to_utime(*pftCreationTime);
-   FindClose(h);
 
    return 0;
 }
@@ -720,11 +732,10 @@ int
 fstat(int fd, struct stat *sb)
 {
    BY_HANDLE_FILE_INFORMATION info;
-   char tmpbuf[1024];
 
    if (!GetFileInformationByHandle((HANDLE)fd, &info)) {
        const char *err = errorString();
-       Dmsg2(99, "GetfileInformationByHandle(%s): %s\n", tmpbuf, err);
+       Dmsg1(99, "GetfileInformationByHandle: %s\n", err);
        LocalFree((void *)err);
        errno = b_errno_win32;
        return -1;
@@ -749,7 +760,11 @@ fstat(int fd, struct stat *sb)
    sb->st_mode |= S_IFREG;
 
    /* Use st_rdev to store reparse attribute */
-   sb->st_rdev = (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) ? 1 : 0; 
+   if  (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+      sb->st_rdev = WIN32_REPARSE_POINT;
+   }
+   Dmsg3(100, "st_rdev=%d sizino=%d ino=%lld\n", sb->st_rdev, sizeof(sb->st_ino),
+      (long long)sb->st_ino);
 
    sb->st_size = info.nFileSizeHigh;
    sb->st_size <<= 32;
@@ -768,8 +783,8 @@ stat2(const char *file, struct stat *sb)
 {
    HANDLE h;
    int rval = 0;
-   char tmpbuf[1024];
-   conv_unix_to_win32_path(file, tmpbuf, 1024);
+   char tmpbuf[5000];
+   conv_unix_to_win32_path(file, tmpbuf, 5000);
 
    DWORD attr = (DWORD)-1;
 
@@ -819,12 +834,11 @@ stat(const char *file, struct stat *sb)
    WIN32_FILE_ATTRIBUTE_DATA data;
    errno = 0;
 
-
    memset(sb, 0, sizeof(*sb));
 
    if (p_GetFileAttributesExW) {
       /* dynamically allocate enough space for UCS2 filename */
-      POOLMEM* pwszBuf = get_pool_memory (PM_FNAME);
+      POOLMEM *pwszBuf = get_pool_memory(PM_FNAME);
       make_win32_path_UTF8_2_wchar(&pwszBuf, file);
 
       BOOL b = p_GetFileAttributesExW((LPCWSTR)pwszBuf, GetFileExInfoStandard, &data);
@@ -833,6 +847,7 @@ stat(const char *file, struct stat *sb)
       if (!b) {
          return stat2(file, sb);
       }
+
    } else if (p_GetFileAttributesExA) {
       if (!p_GetFileAttributesExA(file, GetFileExInfoStandard, &data)) {
          return stat2(file, sb);
@@ -882,6 +897,8 @@ stat(const char *file, struct stat *sb)
         file[1] == ':' && file[2] != 0) {
       statDir(file, sb);
    }
+   Dmsg3(100, "sizino=%d ino=%lld file=%s\n", sizeof(sb->st_ino),
+                       (long long)sb->st_ino, file);
    return 0;
 }
 
@@ -2168,10 +2185,10 @@ utime(const char *fname, struct utimbuf *times)
     HANDLE h = INVALID_HANDLE_VALUE;
 
     if (p_CreateFileW) {
-      POOLMEM* pwszBuf = get_pool_memory(PM_FNAME);
-      make_win32_path_UTF8_2_wchar(&pwszBuf, tmpbuf);
+       POOLMEM* pwszBuf = get_pool_memory(PM_FNAME);
+       make_win32_path_UTF8_2_wchar(&pwszBuf, tmpbuf);
 
-      h = p_CreateFileW((LPCWSTR)pwszBuf,
+       h = p_CreateFileW((LPCWSTR)pwszBuf,
                         FILE_WRITE_ATTRIBUTES,
                         FILE_SHARE_WRITE|FILE_SHARE_READ|FILE_SHARE_DELETE,
                         NULL,
@@ -2179,9 +2196,9 @@ utime(const char *fname, struct utimbuf *times)
                         FILE_FLAG_BACKUP_SEMANTICS, // required for directories
                         NULL);
 
-      free_pool_memory(pwszBuf);
+       free_pool_memory(pwszBuf);
     } else if (p_CreateFileA) {
-      h = p_CreateFileA(tmpbuf,
+       h = p_CreateFileA(tmpbuf,
                         FILE_WRITE_ATTRIBUTES,
                         FILE_SHARE_WRITE|FILE_SHARE_READ|FILE_SHARE_DELETE,
                         NULL,
@@ -2191,11 +2208,11 @@ utime(const char *fname, struct utimbuf *times)
     }
 
     if (h == INVALID_HANDLE_VALUE) {
-        const char *err = errorString();
-        Dmsg2(99, "Cannot open file \"%s\" for utime(): ERR=%s", tmpbuf, err);
-        LocalFree((void *)err);
-        errno = b_errno_win32;
-        return -1;
+       const char *err = errorString();
+       Dmsg2(99, "Cannot open file \"%s\" for utime(): ERR=%s", tmpbuf, err);
+       LocalFree((void *)err);
+       errno = b_errno_win32;
+       return -1;
     }
 
     int rval = SetFileTime(h, NULL, &acc, &mod) ? 0 : -1;
@@ -2210,49 +2227,49 @@ utime(const char *fname, struct utimbuf *times)
 int
 file_open(const char *file, int flags, int mode)
 {
-    DWORD access = 0;
-    DWORD shareMode = 0;
-    DWORD create = 0;
-    DWORD msflags = 0;
-    HANDLE foo = INVALID_HANDLE_VALUE;
-    const char *remap = file;
-
-    if (flags & O_WRONLY) access = GENERIC_WRITE;
-    else if (flags & O_RDWR) access = GENERIC_READ|GENERIC_WRITE;
-    else access = GENERIC_READ;
-
-    if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
-       create = CREATE_NEW;
-    else if ((flags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
-       create = CREATE_ALWAYS;
-    else if (flags & O_CREAT)
-       create = OPEN_ALWAYS;
-    else if (flags & O_TRUNC)
-       create = TRUNCATE_EXISTING;
-    else 
-       create = OPEN_EXISTING;
-
-    shareMode = 0;
-
-    if (flags & O_APPEND) {
-        printf("open...APPEND not implemented yet.");
-        exit(-1);
-    }
+   DWORD access = 0;
+   DWORD shareMode = 0;
+   DWORD create = 0;
+   DWORD msflags = 0;
+   HANDLE foo = INVALID_HANDLE_VALUE;
+   const char *remap = file;
+
+   if (flags & O_WRONLY) access = GENERIC_WRITE;
+   else if (flags & O_RDWR) access = GENERIC_READ|GENERIC_WRITE;
+   else access = GENERIC_READ;
+
+   if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+      create = CREATE_NEW;
+   else if ((flags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
+      create = CREATE_ALWAYS;
+   else if (flags & O_CREAT)
+      create = OPEN_ALWAYS;
+   else if (flags & O_TRUNC)
+      create = TRUNCATE_EXISTING;
+   else 
+      create = OPEN_EXISTING;
+
+   shareMode = 0;
+
+   if (flags & O_APPEND) {
+      printf("open...APPEND not implemented yet.");
+      exit(-1);
+   }
 
-    if (p_CreateFileW) {
-       POOLMEM* pwszBuf = get_pool_memory(PM_FNAME);
-       make_win32_path_UTF8_2_wchar(&pwszBuf, file);
+   if (p_CreateFileW) {
+      POOLMEM* pwszBuf = get_pool_memory(PM_FNAME);
+      make_win32_path_UTF8_2_wchar(&pwszBuf, file);
 
-       foo = p_CreateFileW((LPCWSTR) pwszBuf, access, shareMode, NULL, create, msflags, NULL);
-       free_pool_memory(pwszBuf);
-    } else if (p_CreateFileA)
-       foo = CreateFile(file, access, shareMode, NULL, create, msflags, NULL);
+      foo = p_CreateFileW((LPCWSTR) pwszBuf, access, shareMode, NULL, create, msflags, NULL);
+      free_pool_memory(pwszBuf);
+   } else if (p_CreateFileA)
+      foo = CreateFile(file, access, shareMode, NULL, create, msflags, NULL);
 
-    if (INVALID_HANDLE_VALUE == foo) {
-        errno = b_errno_win32;
-        return(int) -1;
-    }
-    return (int)foo;
+   if (INVALID_HANDLE_VALUE == foo) {
+      errno = b_errno_win32;
+      return (int)-1;
+   }
+   return (int)foo;
 
 }
 
index ce1cb87467cb11d9aed599b746a98c45a37758c4..1272046672766c8e4b6b81cf91b155d66b45a19b 100644 (file)
@@ -24,6 +24,15 @@ Add long term statistics job table
 
 
 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).