]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/findlib/find_one.c
Don't force job duplicate checking on copy and migration jobs.
[bacula/bacula] / bacula / src / findlib / find_one.c
index 38fbfa47b350c6de370d197d03870675cbfaf5dd..b2d7f988104192bf6b601d63498ae56c396527f9 100644 (file)
@@ -1,12 +1,12 @@
 /*
    Bacula® - The Network Backup Solution
 
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2010 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.
    This program is Free Software; you can redistribute it and/or
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    This program is Free Software; you can redistribute it and/or
-   modify it under the terms of version two of the GNU General Public
+   modify it under the terms of version three of the GNU Affero General Public
    License as published by the Free Software Foundation and included
    in the file LICENSE.
 
    License as published by the Free Software Foundation and included
    in the file LICENSE.
 
@@ -15,7 +15,7 @@
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    General Public License for more details.
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
+   You should have received a copy of the GNU Affero General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
@@ -34,8 +34,6 @@
 
    Thanks to the TAR programmers.
 
 
    Thanks to the TAR programmers.
 
-     Version $Id$
-
  */
 
 #include "bacula.h"
  */
 
 #include "bacula.h"
@@ -61,6 +59,9 @@ struct f_link {
     dev_t dev;                        /* device */
     ino_t ino;                        /* inode with device is unique */
     uint32_t FileIndex;               /* Bacula FileIndex of this file */
     dev_t dev;                        /* device */
     ino_t ino;                        /* inode with device is unique */
     uint32_t FileIndex;               /* Bacula FileIndex of this file */
+    int32_t digest_stream;            /* Digest type if needed */
+    uint32_t digest_len;              /* Digest len if needed */
+    char *digest;                     /* Checksum of the file if needed */
     char name[1];                     /* The name */
 };
 
     char name[1];                     /* The name */
 };
 
@@ -276,7 +277,7 @@ bool has_file_changed(JCR *jcr, FF_PKT *ff_pkt)
  * For incremental/diffential or accurate backups, we
  *   determine if the current file has changed.
  */
  * For incremental/diffential or accurate backups, we
  *   determine if the current file has changed.
  */
-static bool check_changes(JCR *jcr, FF_PKT *ff_pkt)
+bool check_changes(JCR *jcr, FF_PKT *ff_pkt)
 {
    /* in special mode (like accurate backup), the programmer can 
     * choose his comparison function.
 {
    /* in special mode (like accurate backup), the programmer can 
     * choose his comparison function.
@@ -299,6 +300,51 @@ static bool check_changes(JCR *jcr, FF_PKT *ff_pkt)
    return true;
 }
 
    return true;
 }
 
+static bool have_ignoredir(FF_PKT *ff_pkt)
+{
+   struct stat sb;
+   char tmp_name[MAXPATHLEN];
+   char *ignoredir;
+
+   /* Ensure that pointers are defined */
+   if (!ff_pkt->fileset || !ff_pkt->fileset->incexe) {
+      return false;
+   }
+   ignoredir = ff_pkt->fileset->incexe->ignoredir;
+   
+   if (ignoredir) {
+      if (strlen(ff_pkt->fname) + strlen(ignoredir) + 2 > MAXPATHLEN) {
+         return false;
+      }
+
+      strcpy(tmp_name, ff_pkt->fname);
+      strcat(tmp_name, "/");
+      strcat(tmp_name, ignoredir);
+      if (stat(tmp_name, &sb) == 0) {
+         Dmsg2(100, "Directory '%s' ignored (found %s)\n",
+               ff_pkt->fname, ignoredir);
+         return true;      /* Just ignore this directory */
+      } 
+   }
+   return false;
+}
+
+/* 
+ * When the current file is a hardlink, the backup code can compute
+ * the checksum and store it into the link_t structure.
+ */
+void
+ff_pkt_set_link_digest(FF_PKT *ff_pkt,
+                       int32_t digest_stream, const char *digest, uint32_t len)
+{
+   if (ff_pkt->linked && !ff_pkt->linked->digest) {     /* is a hardlink */
+      ff_pkt->linked->digest = (char *) bmalloc(len);
+      memcpy(ff_pkt->linked->digest, digest, len);
+      ff_pkt->linked->digest_len = len;
+      ff_pkt->linked->digest_stream = digest_stream;
+   }
+}
+
 /*
  * Find a single file.
  * handle_file is the callback for handling the file.
 /*
  * Find a single file.
  * handle_file is the callback for handling the file.
@@ -446,6 +492,9 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt,
              ff_pkt->type = FT_LNKSAVED;       /* Handle link, file already saved */
              ff_pkt->LinkFI = lp->FileIndex;
              ff_pkt->linked = 0;
              ff_pkt->type = FT_LNKSAVED;       /* Handle link, file already saved */
              ff_pkt->LinkFI = lp->FileIndex;
              ff_pkt->linked = 0;
+             ff_pkt->digest = lp->digest;
+             ff_pkt->digest_stream = lp->digest_stream;
+             ff_pkt->digest_len = lp->digest_len;
              rtn_stat = handle_file(jcr, ff_pkt, top_level);
              Dmsg3(400, "FT_LNKSAVED FI=%d LinkFI=%d file=%s\n", 
                 ff_pkt->FileIndex, lp->FileIndex, lp->name);
              rtn_stat = handle_file(jcr, ff_pkt, top_level);
              Dmsg3(400, "FT_LNKSAVED FI=%d LinkFI=%d file=%s\n", 
                 ff_pkt->FileIndex, lp->FileIndex, lp->name);
@@ -455,6 +504,9 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt,
       /* File not previously dumped. Chain it into our list. */
       len = strlen(fname) + 1;
       lp = (struct f_link *)bmalloc(sizeof(struct f_link) + len);
       /* File not previously dumped. Chain it into our list. */
       len = strlen(fname) + 1;
       lp = (struct f_link *)bmalloc(sizeof(struct f_link) + len);
+      lp->digest = NULL;                /* set later */
+      lp->digest_stream = 0;            /* set later */
+      lp->digest_len = 0;               /* set later */
       lp->ino = ff_pkt->statp.st_ino;
       lp->dev = ff_pkt->statp.st_dev;
       lp->FileIndex = 0;                  /* set later */
       lp->ino = ff_pkt->statp.st_ino;
       lp->dev = ff_pkt->statp.st_dev;
       lp->FileIndex = 0;                  /* set later */
@@ -528,44 +580,12 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt,
       bool recurse = true;
       bool volhas_attrlist = ff_pkt->volhas_attrlist;    /* Remember this if we recurse */
 
       bool recurse = true;
       bool volhas_attrlist = ff_pkt->volhas_attrlist;    /* Remember this if we recurse */
 
-      /*
-       * If we are using Win32 (non-portable) backup API, don't check
-       *  access as everything is more complicated, and
-       *  in principle, we should be able to access everything.
-       */
-      if (!have_win32_api() || (ff_pkt->flags & FO_PORTABLE)) {
-         if (access(fname, R_OK) == -1 && geteuid() != 0) {
-            /* Could not access() directory */
-            ff_pkt->type = FT_NOACCESS;
-            ff_pkt->ff_errno = errno;
-            rtn_stat = handle_file(jcr, ff_pkt, top_level);
-            if (ff_pkt->linked) {
-               ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
-            }
-            return rtn_stat;
-         }
-      }
-
       /*
        * Ignore this directory and everything below if the file .nobackup
        * (or what is defined for IgnoreDir in this fileset) exists
        */
       /*
        * Ignore this directory and everything below if the file .nobackup
        * (or what is defined for IgnoreDir in this fileset) exists
        */
-      if (ff_pkt->ignoredir != NULL) {
-         struct stat sb;
-         char fname[MAXPATHLEN];
-
-         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) {
-            Dmsg2(100, "Directory '%s' ignored (found %s)\n",
-               ff_pkt->fname, ff_pkt->ignoredir);
-            return 1;      /* Just ignore this directory */
-         }
+      if (have_ignoredir(ff_pkt)) {
+         return 1; /* Just ignore this directory */
       }
 
       /* Build a canonical directory name with a trailing slash in link var */
       }
 
       /* Build a canonical directory name with a trailing slash in link var */
@@ -591,8 +611,27 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt,
        *  if st_rdev is 2, it is a mount point 
        */
 #if defined(HAVE_WIN32)
        *  if st_rdev is 2, it is a mount point 
        */
 #if defined(HAVE_WIN32)
+      /*
+       * A reparse point (WIN32_REPARSE_POINT)
+       *  is something special like one of the following: 
+       *  IO_REPARSE_TAG_DFS              0x8000000A
+       *  IO_REPARSE_TAG_DFSR             0x80000012
+       *  IO_REPARSE_TAG_HSM              0xC0000004
+       *  IO_REPARSE_TAG_HSM2             0x80000006
+       *  IO_REPARSE_TAG_SIS              0x80000007
+       *  IO_REPARSE_TAG_SYMLINK          0xA000000C
+       *
+       * A junction point is a:
+       *  IO_REPARSE_TAG_MOUNT_POINT      0xA0000003
+       * which can be either a link to a Volume (WIN32_MOUNT_POINT)
+       * or a link to a directory (WIN32_JUNCTION_POINT)
+       *
+       * Ignore WIN32_REPARSE_POINT and WIN32_JUNCTION_POINT
+       */
       if (ff_pkt->statp.st_rdev == WIN32_REPARSE_POINT) {
          ff_pkt->type = FT_REPARSE;
       if (ff_pkt->statp.st_rdev == WIN32_REPARSE_POINT) {
          ff_pkt->type = FT_REPARSE;
+      } else if (ff_pkt->statp.st_rdev == WIN32_JUNCTION_POINT) {
+         ff_pkt->type = FT_JUNCTION;
       }
 #endif 
       /*
       }
 #endif 
       /*
@@ -604,7 +643,8 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt,
        * in the directory is seen (i.e. the FT_DIREND).
        */
       rtn_stat = handle_file(jcr, ff_pkt, top_level);
        * in the directory is seen (i.e. the FT_DIREND).
        */
       rtn_stat = handle_file(jcr, ff_pkt, top_level);
-      if (rtn_stat < 1 || ff_pkt->type == FT_REPARSE) {   /* ignore or error status */
+      if (rtn_stat < 1 || ff_pkt->type == FT_REPARSE ||
+          ff_pkt->type == FT_JUNCTION) {   /* ignore or error status */
          free(link);
          return rtn_stat;
       }
          free(link);
          return rtn_stat;
       }
@@ -793,16 +833,19 @@ int term_find_one(FF_PKT *ff)
 
    for (i =0 ; i < LINK_HASHTABLE_SIZE; i ++) {
    /* Free up list of hard linked files */
 
    for (i =0 ; i < LINK_HASHTABLE_SIZE; i ++) {
    /* Free up list of hard linked files */
-       lp = ff->linkhash[i];
-       while (lp) {
-      lc = lp;
-      lp = lp->next;
-      if (lc) {
-         free(lc);
-         count++;
+      lp = ff->linkhash[i];
+      while (lp) {
+         lc = lp;
+         lp = lp->next;
+         if (lc) {
+            if (lc->digest) {
+               free(lc->digest);
+            }
+            free(lc);
+            count++;
+         }
       }
       }
-   }
-       ff->linkhash[i] = NULL;
+      ff->linkhash[i] = NULL;
    }
    free(ff->linkhash);
    ff->linkhash = NULL;
    }
    free(ff->linkhash);
    ff->linkhash = NULL;