[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Sat Oct 5 05:52:02 MDT 2013


The branch, master has been updated
       via  8fe1f40 samba_backup: fix bug, add command line parameter, improve error messages
       via  6ccbc13 shadow_copy2: use stored mount_point instead of recalculating.
       via  935120d shadow_copy2: improve debug in shadow_copy2_convert() in snapdirseverywhere mode
       via  9ab8937 shadow_copy2: fix shadow_copy2_convert() in the classical case.
       via  86988db shadow_copy2: add some blank lines for visual separation to shadow_copy2_convert()
       via  249e9b4 shadow_copy2: initialize "converted" string to null in shadow_copy2_convert()
       via  4b8d9c6 shadow_copy2: fix shadow_copy2_strip_snapshot() in the classical case
       via  afcb84e shadow_copy2: add some debug to shadow_copy2_strip_snapshot()
       via  3d053b1 shadow_copy2: add comments explaining decisions in shadow_copy2_strip_snapshot()
       via  38e1085 shadow_copy2: introduce shadow_copy2_snapshot_path()
       via  4cc5140 shadow_copy2: factor shadow_copy2_posix_gmt_string() out of shadow_copy2_insert_string()
       via  304a0f5 shadow_copy2: shadow_copy2_insert_string(): do not prepend a "/" in absolute mode
       via  e86923e shadow_copy2: make shadow_copy2_find_snapdir() return const char *
       via  dbdb436 shadow_copy2: in the classical case, use configured path in shadow_copy2_find_snapdir()
       via  ea898ea shadow_copy2: implement disk_free
       via  c4f9954 shadow_copy2: log resulting config at the end of shadow_copy2_connect()
       via  a7ca55c shadow_copy2: add snapshot_basepath to the config.
       via  d34dc1b shadow_copy2: add rel_connectpath to config.
       via  2d5a3af shadow_copy2: introduce "shadow:mountpoint" option
       via  ed751b9 shadow_copy2: re-add the basedir option.
       via  1e887fc shadow_copy2: disable "snapdir:crossmountpoints" if the snapdir is absolute.
       via  8439549 shadow_copy2: introduce the bool "snapdir_absolute" in the config.
       via  1ecef57 shadow_copy2: introduce config struct and function shadow_copy2_connect()
       via  6da7375 shadow_copy2: add comment explaining the SMB level GMT format pattern
       via  5c900fd shadow_copy2: add comment block explaining shadow_copy2_convert()
       via  5da5512 shadow_copy2: add comment block explaining shadow_copy2_insert_string()
       via  b90d1e6 shadow_copy2: add comment block explaining shadow_copy2_find_snapdir()
       via  5b494b3 shadow_copy2: add header comment explaining have_snapdir()
       via  9361824 shadow_copy2: add comment header describing shadow_copy2_strip_snapshot()
       via  01cb889 shadow_copy2: break overly long lines in shadow_copy2_snapshot_to_gmt()
      from  8b51eab Revert "Support UPN_DNS_INFO in the PAC"

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 8fe1f405e915c1f37a810371a86ed39cfc7eddbe
Author: Brian Martin <bmartin at martinconsulting.com>
Date:   Wed Sep 25 17:01:24 2013 -0700

    samba_backup: fix bug, add command line parameter, improve error messages
    
    Also remove .bak suffix from tdb/ldb backups for more consistent restore procedures
    
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Matthieu Patou <mat at matws.net>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Sat Oct  5 13:51:34 CEST 2013 on sn-devel-104

commit 6ccbc1347d3240fc3c874a1957b654456fb6234c
Author: Michael Adam <obnox at samba.org>
Date:   Fri May 31 00:46:01 2013 +0200

    shadow_copy2: use stored mount_point instead of recalculating.
    
    In the case of snapdirseverywhere but NOT crossmountpoints.
    
    This spares stat calls.
    And is the only correct thing to do if the mount point was
    specified in the configuration.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 935120dbc01890e313e2902b13141d4a13fe96d5
Author: Michael Adam <obnox at samba.org>
Date:   Fri May 31 00:45:16 2013 +0200

    shadow_copy2: improve debug in shadow_copy2_convert() in snapdirseverywhere mode
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 9ab89371c8eddad2f274736b508866e2a92b74a3
Author: Michael Adam <obnox at samba.org>
Date:   Thu May 23 16:23:03 2013 +0200

    shadow_copy2: fix shadow_copy2_convert() in the classical case.
    
    I.e. the non-snapdirseverywhere case.
    This in particular fixes the case of a snapdir hierarchy
    that is parallel to the share or mountpoint and not subordinate.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 86988db1f0ebd170d2bc91b6ed78f8845bfd270c
Author: Michael Adam <obnox at samba.org>
Date:   Wed May 29 15:06:22 2013 +0200

    shadow_copy2: add some blank lines for visual separation to shadow_copy2_convert()
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 249e9b4a34d8959bd94735c1921ecfc24d6a2705
Author: Michael Adam <obnox at samba.org>
Date:   Tue May 28 16:59:25 2013 +0200

    shadow_copy2: initialize "converted" string to null in shadow_copy2_convert()
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 4b8d9c65f45db426716763629f1e22b0eb859a99
Author: Michael Adam <obnox at samba.org>
Date:   Wed May 29 17:16:23 2013 +0200

    shadow_copy2: fix shadow_copy2_strip_snapshot() in the classical case
    
    I.e., fix detection of already converted names.
    
    This is done by using the shadow_copy2_snapshot_path() function
    and comparing if the input string starts with that.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit afcb84e69f46671030710bdda1c8798235b9ace7
Author: Michael Adam <obnox at samba.org>
Date:   Wed May 29 23:57:30 2013 +0200

    shadow_copy2: add some debug to shadow_copy2_strip_snapshot()
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 3d053b1ab3e0b918509e06086a54834a9ae9cdb7
Author: Michael Adam <obnox at samba.org>
Date:   Wed May 29 17:14:49 2013 +0200

    shadow_copy2: add comments explaining decisions in shadow_copy2_strip_snapshot()
    
    This should make it more easy to understand what the cases are.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 38e108563d7e9e14203bf4dabfda09bd1408e980
Author: Michael Adam <obnox at samba.org>
Date:   Fri May 31 00:18:52 2013 +0200

    shadow_copy2: introduce shadow_copy2_snapshot_path()
    
    This builds the posix snapshot path for the connection
    at the provided timestamp. For the non-snapdirseverywhere case.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 4cc5140bbe207f08d9b4fb0d119e74cc839e55dd
Author: Michael Adam <obnox at samba.org>
Date:   Thu May 30 23:51:02 2013 +0200

    shadow_copy2: factor shadow_copy2_posix_gmt_string() out of shadow_copy2_insert_string()
    
    for re-use..
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 304a0f531caa5f33f205739470f17e983d25a6b5
Author: Michael Adam <obnox at samba.org>
Date:   Wed May 29 17:12:21 2013 +0200

    shadow_copy2: shadow_copy2_insert_string(): do not prepend a "/" in absolute mode
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit e86923eb52633c5b6133c45678355ce69bb43a54
Author: Michael Adam <obnox at samba.org>
Date:   Tue May 28 17:01:20 2013 +0200

    shadow_copy2: make shadow_copy2_find_snapdir() return const char *
    
    instead of char *. This eliminates compiler warnings.
    snapdir is a const string in all occasions.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit dbdb436a80e2fb75d9fd8ae17192702123c3b530
Author: Michael Adam <obnox at samba.org>
Date:   Thu May 23 16:21:46 2013 +0200

    shadow_copy2: in the classical case, use configured path in shadow_copy2_find_snapdir()
    
    There is no point in searching for snapdir if not in snapdirseverywhere mode.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit ea898ea1ac1cc9364c5b7396db3902aeb114cfb8
Author: Michael Adam <obnox at samba.org>
Date:   Sat Jun 1 02:14:41 2013 +0200

    shadow_copy2: implement disk_free
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit c4f9954ebb04da94a5bcd2cb328fb2fbaf9fa062
Author: Michael Adam <obnox at samba.org>
Date:   Fri May 31 17:17:27 2013 +0200

    shadow_copy2: log resulting config at the end of shadow_copy2_connect()
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit a7ca55c8da6fbe6452a7a0bfc3c84b5941b8aa27
Author: Michael Adam <obnox at samba.org>
Date:   Fri Oct 4 00:07:15 2013 +0200

    shadow_copy2: add snapshot_basepath to the config.
    
    This is the absolute version of snapdir.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit d34dc1b0025d18afc9ce638c7000b702f98b5d03
Author: Michael Adam <obnox at samba.org>
Date:   Fri Oct 4 00:04:06 2013 +0200

    shadow_copy2: add rel_connectpath to config.
    
    This is the share root, relative to the basedir.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 2d5a3af4bc44d13877a26fa1857b3ceafe138de8
Author: Michael Adam <obnox at samba.org>
Date:   Fri May 31 16:36:33 2013 +0200

    shadow_copy2: introduce "shadow:mountpoint" option
    
    Possiblity to explicitly set the share's mount point.
    This is useful mainly for debugging and testing purposes.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit ed751b9ee49d8e4a319759640321e8b49be4f154
Author: Michael Adam <obnox at samba.org>
Date:   Thu May 30 17:26:44 2013 +0200

    shadow_copy2: re-add the basedir option.
    
    Disable basedir if it is not an absolute path or if
    snapdirseverywhere or crossmountpoints is enabled.
    
    Pair-Programmed-With: Björn Baumbach <bb at sernet.de>
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Signed-off-by: Björn Baumbach <bb at sernet.de>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 1e887fcda097b93a879df726f2b7c2c8d3c4cf54
Author: Michael Adam <obnox at samba.org>
Date:   Thu May 30 13:19:50 2013 +0200

    shadow_copy2: disable "snapdir:crossmountpoints" if the snapdir is absolute.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 843954989cbec6640d2565d0d23a48f296740a23
Author: Michael Adam <obnox at samba.org>
Date:   Wed May 29 17:10:51 2013 +0200

    shadow_copy2: introduce the bool "snapdir_absolute" in the config.
    
    Not exposed but to be used internally.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 1ecef5743583cf617f5506bc2fca3baa70cfb9b3
Author: Michael Adam <obnox at samba.org>
Date:   Fri May 24 01:35:44 2013 +0200

    shadow_copy2: introduce config struct and function shadow_copy2_connect()
    
    This moves the parsing of the config to a central place.
    So users of configuation don't need to call lp_parm_... all the time.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 6da7375cd881f85f2873578db7fcfb368deab94f
Author: Michael Adam <obnox at samba.org>
Date:   Wed May 29 17:11:44 2013 +0200

    shadow_copy2: add comment explaining the SMB level GMT format pattern
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5c900fd930edd45e9f23b36c1e68e5c2d8b96867
Author: Michael Adam <obnox at samba.org>
Date:   Wed May 29 01:13:57 2013 +0200

    shadow_copy2: add comment block explaining shadow_copy2_convert()
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5da5512985cf65c09abb33abaf5e8dc28167dac3
Author: Michael Adam <obnox at samba.org>
Date:   Fri May 24 17:20:42 2013 +0200

    shadow_copy2: add comment block explaining shadow_copy2_insert_string()
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit b90d1e6ac06fd4c1aaaceadcb711800499334117
Author: Michael Adam <obnox at samba.org>
Date:   Fri May 24 00:01:14 2013 +0200

    shadow_copy2: add comment block explaining shadow_copy2_find_snapdir()
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5b494b3dea559f632d57c9d33172e46e459e852f
Author: Michael Adam <obnox at samba.org>
Date:   Thu May 23 23:59:49 2013 +0200

    shadow_copy2: add header comment explaining have_snapdir()
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 9361824ddd291cb0e543a5a0829246831fcb9e84
Author: Michael Adam <obnox at samba.org>
Date:   Thu May 23 23:32:15 2013 +0200

    shadow_copy2: add comment header describing shadow_copy2_strip_snapshot()
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 01cb88977da5bc44443407b100345531d047c77c
Author: Michael Adam <obnox at samba.org>
Date:   Fri Oct 4 13:15:34 2013 +0200

    shadow_copy2: break overly long lines in shadow_copy2_snapshot_to_gmt()
    
    According to coding guidelines.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/include/smb.h              |   10 +-
 source3/modules/vfs_shadow_copy2.c |  632 ++++++++++++++++++++++++++++++++----
 source4/scripting/bin/samba_backup |   52 ++-
 3 files changed, 620 insertions(+), 74 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/smb.h b/source3/include/smb.h
index 1288222..0d07f71 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -567,7 +567,15 @@ Offset  Data			length.
 #define NOTIFY_ACTION_REMOVED_STREAM 7
 #define NOTIFY_ACTION_MODIFIED_STREAM 8
 
-/* timestamp format used in "previous versions" */
+/*
+ * Timestamp format used in "previous versions":
+ * The is the windows-level format of the @GMT- token.
+ * It is a fixed format not to be confused with the
+ * format for the POSIX-Level token of the shadow_copy2
+ * VFS module that can be configured via the "shadow:format"
+ * configuration option but defaults to the same format.
+ * See the shadow_copy2 module.
+ */
 #define GMT_NAME_LEN 24 /* length of a @GMT- name */
 #define GMT_FORMAT "@GMT-%Y.%m.%d-%H.%M.%S"
 
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index aa7e50f..ebc50e9 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -107,6 +107,22 @@
 #include <ccan/hash/hash.h>
 #include "util_tdb.h"
 
+struct shadow_copy2_config {
+	char *gmt_format;
+	bool use_sscanf;
+	bool use_localtime;
+	char *snapdir;
+	bool snapdirseverywhere;
+	bool crossmountpoints;
+	bool fixinodes;
+	char *sort_order;
+	bool snapdir_absolute;
+	char *basedir;
+	char *mount_point;
+	char *rel_connectpath; /* share root, relative to the basedir */
+	char *snapshot_basepath; /* the absolute version of snapdir */
+};
+
 static bool shadow_copy2_find_slashes(TALLOC_CTX *mem_ctx, const char *str,
 				      size_t **poffsets,
 				      unsigned *pnum_offsets)
@@ -141,51 +157,143 @@ static bool shadow_copy2_find_slashes(TALLOC_CTX *mem_ctx, const char *str,
 	return true;
 }
 
-static char *shadow_copy2_insert_string(TALLOC_CTX *mem_ctx,
-					struct vfs_handle_struct *handle,
-					time_t snapshot)
+/**
+ * Given a timstamp, build the posix level GTM-tag string
+ * based on the configurable format.
+ */
+static size_t shadow_copy2_posix_gmt_string(struct vfs_handle_struct *handle,
+					    time_t snapshot,
+					    char *snaptime_string,
+					    size_t len)
 {
-	const char *fmt;
 	struct tm snap_tm;
-	fstring snaptime_string;
 	size_t snaptime_len;
+	struct shadow_copy2_config *config;
 
-	fmt = lp_parm_const_string(SNUM(handle->conn), "shadow",
-				   "format", GMT_FORMAT);
+	SMB_VFS_HANDLE_GET_DATA(handle, config, struct shadow_copy2_config,
+				return 0);
 
-	if (lp_parm_bool(SNUM(handle->conn), "shadow", "sscanf", false)) {
-		snaptime_len = snprintf(snaptime_string, sizeof(snaptime_string), fmt,
-				   (unsigned long)snapshot);
+	if (config->use_sscanf) {
+		snaptime_len = snprintf(snaptime_string,
+					len,
+					config->gmt_format,
+					(unsigned long)snapshot);
 		if (snaptime_len <= 0) {
 			DEBUG(10, ("snprintf failed\n"));
-			return NULL;
+			return snaptime_len;
 		}
 	} else {
-		if (lp_parm_bool(SNUM(handle->conn), "shadow", "localtime", false)) {
+		if (config->use_localtime) {
 			if (localtime_r(&snapshot, &snap_tm) == 0) {
 				DEBUG(10, ("gmtime_r failed\n"));
-				return NULL;
+				return -1;
 			}
 		} else {
 			if (gmtime_r(&snapshot, &snap_tm) == 0) {
 				DEBUG(10, ("gmtime_r failed\n"));
-				return NULL;
+				return -1;
 			}
 		}
-		snaptime_len = strftime(snaptime_string, sizeof(snaptime_string), fmt,
-				   &snap_tm);
+		snaptime_len = strftime(snaptime_string,
+					len,
+					config->gmt_format,
+					&snap_tm);
 		if (snaptime_len == 0) {
 			DEBUG(10, ("strftime failed\n"));
-			return NULL;
+			return 0;
 		}
 	}
-	return talloc_asprintf(mem_ctx, "/%s/%s",
-			       lp_parm_const_string(
-				       SNUM(handle->conn), "shadow", "snapdir",
-				       ".snapshots"),
-			       snaptime_string);
+
+	return snaptime_len;
+}
+
+/**
+ * Given a timstamp, build the string to insert into a path
+ * as a path component for creating the local path to the
+ * snapshot at the given timestamp of the input path.
+ *
+ * In the case of a parallel snapdir (specified with an
+ * absolute path), this is the inital portion of the
+ * local path of any snapshot file. The complete path is
+ * obtained by appending the portion of the file's path
+ * below the share root's mountpoint.
+ */
+static char *shadow_copy2_insert_string(TALLOC_CTX *mem_ctx,
+					struct vfs_handle_struct *handle,
+					time_t snapshot)
+{
+	fstring snaptime_string;
+	size_t snaptime_len = 0;
+	char *result = NULL;
+	struct shadow_copy2_config *config;
+
+	SMB_VFS_HANDLE_GET_DATA(handle, config, struct shadow_copy2_config,
+				return NULL);
+
+	snaptime_len = shadow_copy2_posix_gmt_string(handle,
+						     snapshot,
+						     snaptime_string,
+						     sizeof(snaptime_string));
+	if (snaptime_len <= 0) {
+		return NULL;
+	}
+
+	if (config->snapdir_absolute) {
+		result = talloc_asprintf(mem_ctx, "%s/%s",
+					 config->snapdir, snaptime_string);
+	} else {
+		result = talloc_asprintf(mem_ctx, "/%s/%s",
+					 config->snapdir, snaptime_string);
+	}
+	if (result == NULL) {
+		DEBUG(1, (__location__ " talloc_asprintf failed\n"));
+	}
+
+	return result;
 }
 
+/**
+ * Build the posix snapshot path for the connection
+ * at the given timestamp, i.e. the absolute posix path
+ * that contains the snapshot for this file system.
+ *
+ * This only applies to classical case, i.e. not
+ * to the "snapdirseverywhere" mode.
+ */
+static char *shadow_copy2_snapshot_path(TALLOC_CTX *mem_ctx,
+					struct vfs_handle_struct *handle,
+					time_t snapshot)
+{
+	fstring snaptime_string;
+	size_t snaptime_len = 0;
+	char *result = NULL;
+	struct shadow_copy2_config *config;
+
+	SMB_VFS_HANDLE_GET_DATA(handle, config, struct shadow_copy2_config,
+				return NULL);
+
+	snaptime_len = shadow_copy2_posix_gmt_string(handle,
+						     snapshot,
+						     snaptime_string,
+						     sizeof(snaptime_string));
+	if (snaptime_len <= 0) {
+		return NULL;
+	}
+
+	result = talloc_asprintf(mem_ctx, "%s/%s",
+				 config->snapshot_basepath, snaptime_string);
+	if (result == NULL) {
+		DEBUG(1, (__location__ " talloc_asprintf failed\n"));
+	}
+
+	return result;
+}
+
+/**
+ * Strip a snapshot component from an filename as
+ * handed in via the smb layer.
+ * Returns the parsed timestamp and the stripped filename.
+ */
 static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
 					struct vfs_handle_struct *handle,
 					const char *name,
@@ -198,12 +306,19 @@ static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
 	char *q;
 	char *stripped;
 	size_t rest_len, dst_len;
+	struct shadow_copy2_config *config;
+
+	SMB_VFS_HANDLE_GET_DATA(handle, config, struct shadow_copy2_config,
+				return false);
+
+	DEBUG(10, (__location__ ": enter path '%s'\n", name));
 
 	p = strstr_m(name, "@GMT-");
 	if (p == NULL) {
 		goto no_snapshot;
 	}
 	if ((p > name) && (p[-1] != '/')) {
+		/* the GMT-token does not start a path-component */
 		goto no_snapshot;
 	}
 	q = strptime(p, GMT_FORMAT, &tm);
@@ -216,6 +331,7 @@ static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
 		goto no_snapshot;
 	}
 	if ((p == name) && (q[0] == '\0')) {
+		/* the name consists of only the GMT token */
 		if (pstripped != NULL) {
 			stripped = talloc_strdup(mem_ctx, "");
 			if (stripped == NULL) {
@@ -227,6 +343,14 @@ static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
 		return true;
 	}
 	if (q[0] != '/') {
+		/*
+		 * The GMT token is either at the end of the path
+		 * or it is not a complete path component, i.e. the
+		 * path component continues after the gmt-token.
+		 *
+		 * TODO: Is this correct? Or would the GMT tag as the
+		 * last component be a valid input?
+		 */
 		goto no_snapshot;
 	}
 	q += 1;
@@ -234,8 +358,7 @@ static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
 	rest_len = strlen(q);
 	dst_len = (p-name) + rest_len;
 
-	if (lp_parm_bool(SNUM(handle->conn), "shadow", "snapdirseverywhere",
-			 false)) {
+	if (config->snapdirseverywhere) {
 		char *insert;
 		bool have_insert;
 		insert = shadow_copy2_insert_string(talloc_tos(), handle,
@@ -245,11 +368,49 @@ static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
 			return false;
 		}
 
+		DEBUG(10, (__location__ ": snapdirseverywhere mode.\n"
+			   "path '%s'.\n"
+			   "insert string '%s'\n", name, insert));
+
 		have_insert = (strstr(name, insert+1) != NULL);
-		TALLOC_FREE(insert);
 		if (have_insert) {
+			DEBUG(10, (__location__ ": insert string '%s' found in "
+				   "path '%s' found in snapdirseverywhere mode "
+				   "==> already converted\n", insert, name));
+			TALLOC_FREE(insert);
 			goto no_snapshot;
 		}
+		TALLOC_FREE(insert);
+	} else {
+		char *snapshot_path;
+		char *s;
+
+		snapshot_path = shadow_copy2_snapshot_path(talloc_tos(),
+							   handle,
+							   timestamp);
+		if (snapshot_path == NULL) {
+			errno = ENOMEM;
+			return false;
+		}
+
+		DEBUG(10, (__location__ " path: '%s'.\n"
+			   "snapshot path: '%s'\n", name, snapshot_path));
+
+		s = strstr(name, snapshot_path);
+		if (s == name) {
+			/*
+			 * this starts with "snapshot_basepath/GMT-Token"
+			 * so it is already a converted absolute
+			 * path. Don't process further.
+			 */
+			DEBUG(10, (__location__ ": path '%s' starts with "
+				   "snapshot path '%s' (not in "
+				   "snapdirseverywhere mode) ==> "
+				   "already converted\n", name, snapshot_path));
+			talloc_free(snapshot_path);
+			goto no_snapshot;
+		}
+		talloc_free(snapshot_path);
 	}
 
 	if (pstripped != NULL) {
@@ -304,6 +465,11 @@ static char *shadow_copy2_find_mount_point(TALLOC_CTX *mem_ctx,
 	return path;
 }
 
+/**
+ * Convert from a name as handed in via the SMB layer
+ * and a timestamp into the local path of the snapshot
+ * of the provided file at the provided time.
+ */
 static char *shadow_copy2_convert(TALLOC_CTX *mem_ctx,
 				  struct vfs_handle_struct *handle,
 				  const char *name, time_t timestamp)
@@ -319,6 +485,55 @@ static char *shadow_copy2_convert(TALLOC_CTX *mem_ctx,
 	size_t insertlen;
 	int i, saved_errno;
 	size_t min_offset;
+	struct shadow_copy2_config *config;
+
+	SMB_VFS_HANDLE_GET_DATA(handle, config, struct shadow_copy2_config,
+				return NULL);
+
+	DEBUG(10, ("converting '%s'\n", name));
+
+	if (!config->snapdirseverywhere) {
+		int ret;
+		char *snapshot_path;
+
+		snapshot_path = shadow_copy2_snapshot_path(talloc_tos(),
+							   handle,
+							   timestamp);
+		if (snapshot_path == NULL) {
+			goto fail;
+		}
+
+		if (config->rel_connectpath == NULL) {
+			converted = talloc_asprintf(mem_ctx, "%s/%s",
+						    snapshot_path, name);
+		} else {
+			converted = talloc_asprintf(mem_ctx, "%s/%s/%s",
+						    snapshot_path,
+						    config->rel_connectpath,
+						    name);
+		}
+		if (converted == NULL) {
+			goto fail;
+		}
+
+		ZERO_STRUCT(converted_fname);
+		converted_fname.base_name = converted;
+
+		ret = SMB_VFS_NEXT_LSTAT(handle, &converted_fname);
+		DEBUG(10, ("Trying[not snapdirseverywhere] %s: %d (%s)\n",
+			   converted,
+			   ret, ret == 0 ? "ok" : strerror(errno)));
+		if (ret == 0) {
+			DEBUG(10, ("Found %s\n", converted));
+			result = converted;
+			converted = NULL;
+			goto fail;
+		} else {
+			errno = ENOENT;
+			goto fail;
+		}
+		/* never reached ... */
+	}
 
 	path = talloc_asprintf(mem_ctx, "%s/%s", handle->conn->connectpath,
 			       name);
@@ -328,18 +543,18 @@ static char *shadow_copy2_convert(TALLOC_CTX *mem_ctx,
 	}
 	pathlen = talloc_get_size(path)-1;
 
-	DEBUG(10, ("converting %s\n", path));
-
 	if (!shadow_copy2_find_slashes(talloc_tos(), path,
 				       &slashes, &num_slashes)) {
 		goto fail;
 	}
+
 	insert = shadow_copy2_insert_string(talloc_tos(), handle, timestamp);
 	if (insert == NULL) {
 		goto fail;
 	}
 	insertlen = talloc_get_size(insert)-1;
-	converted = talloc_array(mem_ctx, char, pathlen + insertlen + 1);
+
+	converted = talloc_zero_array(mem_ctx, char, pathlen + insertlen + 1);
 	if (converted == NULL) {
 		goto fail;
 	}
@@ -361,17 +576,8 @@ static char *shadow_copy2_convert(TALLOC_CTX *mem_ctx,
 
 	min_offset = 0;
 
-	if (!lp_parm_bool(SNUM(handle->conn), "shadow", "crossmountpoints",
-			  false)) {
-		char *mount_point;
-
-		mount_point = shadow_copy2_find_mount_point(talloc_tos(),
-							    handle);
-		if (mount_point == NULL) {
-			goto fail;
-		}
-		min_offset = strlen(mount_point);
-		TALLOC_FREE(mount_point);
+	if (!config->crossmountpoints) {
+		min_offset = strlen(config->mount_point);
 	}
 
 	memcpy(converted, path, pathlen+1);
@@ -399,7 +605,8 @@ static char *shadow_copy2_convert(TALLOC_CTX *mem_ctx,
 
 		ret = SMB_VFS_NEXT_LSTAT(handle, &converted_fname);
 
-		DEBUG(10, ("Trying %s: %d (%s)\n", converted,
+		DEBUG(10, ("Trying[snapdirseverywhere] %s: %d (%s)\n",
+			   converted,
 			   ret, ret == 0 ? "ok" : strerror(errno)));
 		if (ret == 0) {
 			/* success */
@@ -446,7 +653,12 @@ fail:
 static void convert_sbuf(vfs_handle_struct *handle, const char *fname,
 			 SMB_STRUCT_STAT *sbuf)
 {
-	if (lp_parm_bool(SNUM(handle->conn), "shadow", "fixinodes", False)) {
+	struct shadow_copy2_config *config;
+
+	SMB_VFS_HANDLE_GET_DATA(handle, config, struct shadow_copy2_config,
+				return);
+
+	if (config->fixinodes) {
 		/* some snapshot systems, like GPFS, return the name
 		   device:inode for the snapshot files as the current
 		   files. That breaks the 'restore' button in the shadow copy
@@ -958,17 +1170,25 @@ done:
 	return result;
 }
 
+/**
+ * Check whether a given directory contains a
+ * snapshot directory as direct subdirectory.
+ * If yes, return the path of the snapshot-subdir,
+ * otherwise return NULL.
+ */
 static char *have_snapdir(struct vfs_handle_struct *handle,
 			  const char *path)
 {
 	struct smb_filename smb_fname;
 	int ret;
+	struct shadow_copy2_config *config;
+
+	SMB_VFS_HANDLE_GET_DATA(handle, config, struct shadow_copy2_config,
+				return NULL);
 
 	ZERO_STRUCT(smb_fname);
-	smb_fname.base_name = talloc_asprintf(
-		talloc_tos(), "%s/%s", path,
-		lp_parm_const_string(SNUM(handle->conn), "shadow", "snapdir",
-				     ".snapshots"));
+	smb_fname.base_name = talloc_asprintf(talloc_tos(), "%s/%s",
+					      path, config->snapdir);
 	if (smb_fname.base_name == NULL) {
 		return NULL;
 	}
@@ -981,12 +1201,27 @@ static char *have_snapdir(struct vfs_handle_struct *handle,
 	return NULL;
 }
 
-static char *shadow_copy2_find_snapdir(TALLOC_CTX *mem_ctx,
-				       struct vfs_handle_struct *handle,
-				       struct smb_filename *smb_fname)
+/**
+ * Find the snapshot directory (if any) for the given
+ * filename (which is relative to the share).
+ */
+static const char *shadow_copy2_find_snapdir(TALLOC_CTX *mem_ctx,
+					     struct vfs_handle_struct *handle,
+					     struct smb_filename *smb_fname)
 {
 	char *path, *p;
-	char *snapdir;
+	const char *snapdir;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list