[PATCHES] vfs_shadow_copy2: allow snapshots outside share's root
Uri Simchoni
uri at samba.org
Thu Oct 29 22:41:28 UTC 2015
Hi,
I may just be misconfiguring shadow_copy2 here, but it does seem like a
bug to me, so here's a fix and some tests.
I filed https://bugzilla.samba.org/show_bug.cgi?id=11580 where I
describe what kind of snapshot setup I'm using, and how I configure
shadow_copy2 for that.
- If there's a way to get this to work without the patch - I'd love to
stand corrected
- Haven't wrapped my mind around "snapshots everywhere" - need to verify
this isn't broken by the fix, however I figured I'd submit the patch
anyway to get feedback if it's a non-bug.
Thanks,
Uri.
-------------- next part --------------
From 4c72b4a9dd36a962bfb14826501e293834b64f75 Mon Sep 17 00:00:00 2001
From: Uri Simchoni <uri at samba.org>
Date: Thu, 29 Oct 2015 22:24:30 +0200
Subject: [PATCH 1/3] vfs_shadow_copy2: add a blackbox test for snapshots
inside the share
Add a blackbox test for listing previous versions of a file where
the snapshots reside inside the share directory.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11580
Signed-off-by: Uri Simchoni <uri at samba.org>
---
selftest/target/Samba3.pm | 42 ++++++++++++++++++++++++++++++
source3/script/tests/test_shadow_copy.sh | 44 ++++++++++++++++++++++++++++++++
source3/selftest/tests.py | 1 +
3 files changed, 87 insertions(+)
create mode 100755 source3/script/tests/test_shadow_copy.sh
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index f66aea7..a6dec44 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -807,6 +807,26 @@ map to guest = bad user
return $vars;
}
+sub create_snapshots($$$)
+{
+ my ($self, $path, $fname) = @_;
+
+ my @snapshots = ("\@GMT-2015.10.29-11.44.24",
+ "\@GMT-2016.10.29-11.44.24",
+ "\@GMT-2017.10.29-11.44.24");
+
+ foreach my $snap (@snapshots) {
+ mkdir("$path/$snap", 0777);
+ unless (open(SNAP_FILE, ">$path/$snap/$fname")) {
+ warn("Unable to open $path/$snap/$fname");
+ return undef;
+ }
+ close (SNAP_FILE);
+ }
+
+ return 1;
+}
+
sub stop_sig_term($$) {
my ($self, $pid) = @_;
kill("USR1", $pid) or kill("ALRM", $pid) or warn("Unable to kill $pid: $!");
@@ -1109,6 +1129,9 @@ sub provision($$$$$$$$)
my $manglenames_shrdir="$shrdir/manglenames";
push(@dirs,$manglenames_shrdir);
+ my $intsnap_shrdir="$shrdir/intsnap";
+ push(@dirs,$intsnap_shrdir);
+
# this gets autocreated by winbindd
my $wbsockdir="$prefix_abs/winbindd";
my $wbsockprivdir="$lockdir/winbindd_privileged";
@@ -1198,6 +1221,19 @@ sub provision($$$$$$$$)
my $manglename_target = "$manglenames_shrdir/foo:bar";
mkdir($manglename_target, 0777);
+ ##
+ ## create intsnap directory layout
+ ##
+ unless (open(SNAP_MAIN_FILE, ">$intsnap_shrdir/foo")) {
+ warn("Unable to open $intsnap_shrdir/foo");
+ return undef;
+ }
+ close(SNAP_MAIN_FILE);
+ mkdir("$intsnap_shrdir/.snapshots");
+ if (not defined($self->create_snapshots("$intsnap_shrdir/.snapshots", "foo"))) {
+ return undef;
+ }
+
my $conffile="$libdir/server.conf";
my $nss_wrapper_pl = "$ENV{PERL} $self->{srcdir}/lib/nss_wrapper/nss_wrapper.pl";
@@ -1502,6 +1538,12 @@ sub provision($$$$$$$$)
shell_snap:delete command = $fake_snap_pl --delete
# a relative path here fails, the snapshot dir is no longer found
shadow:snapdir = $shrdir/.snapshots
+
+[intsnap]
+ path = $intsnap_shrdir
+ comment = share with previous versions inside share root
+ vfs objects = shadow_copy2
+ shadow:mountpoint = $intsnap_shrdir
";
close(CONF);
diff --git a/source3/script/tests/test_shadow_copy.sh b/source3/script/tests/test_shadow_copy.sh
new file mode 100755
index 0000000..cabd161
--- /dev/null
+++ b/source3/script/tests/test_shadow_copy.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+#
+# Blackbox test for shadow_copy2 VFS.
+#
+
+if [ $# -lt 6 ]; then
+cat <<EOF
+Usage: test_shadow_copy SERVER SERVER_IP DOMAIN USERNAME PASSWORD SMBCLIENT
+EOF
+exit 1;
+fi
+
+SERVER=${1}
+SERVER_IP=${2}
+DOMAIN=${3}
+USERNAME=${4}
+PASSWORD=${5}
+SMBCLIENT=${6}
+shift 6
+SMBCLIENT="$VALGRIND ${SMBCLIENT}"
+ADDARGS="$*"
+
+incdir=`dirname $0`/../../../testprogs/blackbox
+. $incdir/subunit.sh
+
+failed=0
+
+# Test listing previous versions of a file
+test_count_versions()
+{
+ versions=`$SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$1" -I $SERVER_IP -c "allinfo foo" | grep "^create_time:" | wc -l`
+ if [ "$versions" = "4" ] ; then
+ true
+ else
+ echo "expected 4 versions of foo, got $versions"
+ false
+ fi
+}
+
+testit "counting previous versions inside share" \
+ test_count_versions intsnap || \
+ failed=`expr $failed + 1`
+
+exit $failed
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 048675a..6a4f69a 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -178,6 +178,7 @@ for env in ["fileserver"]:
plantestsuite("samba3.blackbox.preserve_case (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_preserve_case.sh"), '$SERVER', '$DOMAIN', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3])
plantestsuite("samba3.blackbox.dfree_command (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_dfree_command.sh"), '$SERVER', '$DOMAIN', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3])
plantestsuite("samba3.blackbox.valid_users (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_valid_users.sh"), '$SERVER', '$SERVER_IP', '$DOMAIN', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3])
+ plantestsuite("samba3.blackbox.shadow_copy2 (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_shadow_copy.sh"), '$SERVER', '$SERVER_IP', '$DOMAIN', '$USERNAME', '$PASSWORD', smbclient3])
#
# tar command tests
--
2.4.3
From 10138fca969d0d6e21af0f5cbb4bf30c97333d5f Mon Sep 17 00:00:00 2001
From: Uri Simchoni <uri at samba.org>
Date: Fri, 30 Oct 2015 00:10:17 +0200
Subject: [PATCH 2/3] vfs_shadow_copy2: fix case where snapshots are outside
the share
Adjust the connect path to the root of the share in the snapshot,
in order to not-regard snapshot files as "wide links" if the
snapshots are located outside the share's root dir.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11580
Signed-off-by: Uri Simchoni <uri at samba.org>
---
source3/modules/vfs_shadow_copy2.c | 55 +++++++++++++++++++++++---------------
1 file changed, 33 insertions(+), 22 deletions(-)
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 4d2ec54..bf3041a 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -1102,8 +1102,6 @@ static char *shadow_copy2_realpath(vfs_handle_struct *handle,
char *stripped = NULL;
char *tmp = NULL;
char *result = NULL;
- char *inserted = NULL;
- char *inserted_to, *inserted_end;
int saved_errno;
if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
@@ -1120,29 +1118,9 @@ static char *shadow_copy2_realpath(vfs_handle_struct *handle,
}
result = SMB_VFS_NEXT_REALPATH(handle, tmp);
- if (result == NULL) {
- goto done;
- }
-
- /*
- * Take away what we've inserted. This removes the @GMT-thingy
- * completely, but will give a path under the share root.
- */
- inserted = shadow_copy2_insert_string(talloc_tos(), handle, timestamp);
- if (inserted == NULL) {
- goto done;
- }
- inserted_to = strstr_m(result, inserted);
- if (inserted_to == NULL) {
- DEBUG(2, ("SMB_VFS_NEXT_REALPATH removed %s\n", inserted));
- goto done;
- }
- inserted_end = inserted_to + talloc_get_size(inserted) - 1;
- memmove(inserted_to, inserted_end, strlen(inserted_end)+1);
done:
saved_errno = errno;
- TALLOC_FREE(inserted);
TALLOC_FREE(tmp);
TALLOC_FREE(stripped);
errno = saved_errno;
@@ -1732,6 +1710,38 @@ static int shadow_copy2_get_real_filename(struct vfs_handle_struct *handle,
return ret;
}
+static const char *shadow_copy2_connectpath(struct vfs_handle_struct *handle,
+ const char *fname)
+{
+ time_t timestamp;
+ char *stripped = NULL;
+ char *tmp = NULL;
+ char *result = NULL;
+ int saved_errno;
+
+ if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
+ ×tamp, &stripped)) {
+ goto done;
+ }
+ if (timestamp == 0) {
+ return SMB_VFS_NEXT_CONNECTPATH(handle, fname);
+ }
+
+ tmp = shadow_copy2_convert(talloc_tos(), handle, "", timestamp);
+ if (tmp == NULL) {
+ goto done;
+ }
+
+ result = SMB_VFS_NEXT_REALPATH(handle, tmp);
+
+done:
+ saved_errno = errno;
+ TALLOC_FREE(tmp);
+ TALLOC_FREE(stripped);
+ errno = saved_errno;
+ return result;
+}
+
static uint64_t shadow_copy2_disk_free(vfs_handle_struct *handle,
const char *path, uint64_t *bsize,
uint64_t *dfree, uint64_t *dsize)
@@ -2033,6 +2043,7 @@ static struct vfs_fn_pointers vfs_shadow_copy2_fns = {
.chmod_acl_fn = shadow_copy2_chmod_acl,
.chflags_fn = shadow_copy2_chflags,
.get_real_filename_fn = shadow_copy2_get_real_filename,
+ .connectpath_fn = shadow_copy2_connectpath,
};
NTSTATUS vfs_shadow_copy2_init(void);
--
2.4.3
From f594891266e4374020c6d689b32fbeb8bea67a42 Mon Sep 17 00:00:00 2001
From: Uri Simchoni <uri at samba.org>
Date: Thu, 29 Oct 2015 23:03:13 +0200
Subject: [PATCH 3/3] vfs_shadow_copy2: add a blackbox test with snapshots
outside share
Add a blackbox test with snapshots located outside the share's root
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11580
Signed-off-by: Uri Simchoni <uri at samba.org>
---
selftest/target/Samba3.pm | 24 ++++++++++++++++++++++++
source3/script/tests/test_shadow_copy.sh | 4 ++++
2 files changed, 28 insertions(+)
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index a6dec44..3e19d7f 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -1132,6 +1132,11 @@ sub provision($$$$$$$$)
my $intsnap_shrdir="$shrdir/intsnap";
push(@dirs,$intsnap_shrdir);
+ my $extsnap_shrdir="$shrdir/extsnap";
+ push(@dirs,$extsnap_shrdir);
+ my $extsnap_snapdir="$shrdir/extsnap_snap";
+ push(@dirs,$extsnap_snapdir);
+
# this gets autocreated by winbindd
my $wbsockdir="$prefix_abs/winbindd";
my $wbsockprivdir="$lockdir/winbindd_privileged";
@@ -1234,6 +1239,18 @@ sub provision($$$$$$$$)
return undef;
}
+ ##
+ ## create extsnap directory layout
+ ##
+ unless (open(SNAP_MAIN_FILE, ">$extsnap_shrdir/foo")) {
+ warn("Unable to open $extsnap_shrdir/foo");
+ return undef;
+ }
+ close(SNAP_MAIN_FILE);
+ if (not defined($self->create_snapshots("$extsnap_snapdir", "foo"))) {
+ return undef;
+ }
+
my $conffile="$libdir/server.conf";
my $nss_wrapper_pl = "$ENV{PERL} $self->{srcdir}/lib/nss_wrapper/nss_wrapper.pl";
@@ -1544,6 +1561,13 @@ sub provision($$$$$$$$)
comment = share with previous versions inside share root
vfs objects = shadow_copy2
shadow:mountpoint = $intsnap_shrdir
+
+[extsnap]
+ path = $extsnap_shrdir
+ comment = share with previous versions outside share root
+ vfs objects = shadow_copy2
+ shadow:mountpoint = $extsnap_shrdir
+ shadow:snapdir = $extsnap_snapdir
";
close(CONF);
diff --git a/source3/script/tests/test_shadow_copy.sh b/source3/script/tests/test_shadow_copy.sh
index cabd161..baf59c5 100755
--- a/source3/script/tests/test_shadow_copy.sh
+++ b/source3/script/tests/test_shadow_copy.sh
@@ -41,4 +41,8 @@ testit "counting previous versions inside share" \
test_count_versions intsnap || \
failed=`expr $failed + 1`
+testit "counting previous versions outside share" \
+ test_count_versions extsnap || \
+ failed=`expr $failed + 1`
+
exit $failed
--
2.4.3
More information about the samba-technical
mailing list