summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalph Boehme <slow@samba.org>2021-07-06 07:24:00 +0200
committerKarolin Seeger <kseeger@samba.org>2021-08-17 09:08:36 +0000
commit262d09c511a66562f397af099cfdef588813d1ab (patch)
tree3c2aa0a4c340bdceaefcad63158189d523b4e8c4
parent9d6d585ca00f7d001932fab8fc16b6a72ec3ec89 (diff)
downloadsamba-262d09c511a66562f397af099cfdef588813d1ab.tar.gz
selftest: add a test for shadow:fixinodes
This will fail with Failed to open file \@GMT-2015.10.31-19.40.30\subdir\hardlink. NT_STATUS_ACCESS_DENIED The open is failing in openat_pathref_fsp(): [2021/07/06 04:58:17.677104, 10, pid=95070, effective(1000, 1000), real(1000, 0)] ../../source3/smbd/files.c:541(openat_pathref_fsp) openat_pathref_fsp: file [subdir/hardlink {@GMT-2015.10.31-19.40.30}] - dev/ino mismatch. Old (dev=64770, ino=3826943444). New (dev=64770, ino=1746568660). [2021/07/06 04:58:17.677114, 10, pid=95070, effective(1000, 1000), real(1000, 0)] ../../source3/smbd/files.c:568(openat_pathref_fsp) openat_pathref_fsp: Opening pathref for [subdir/hardlink {@GMT-2015.10.31-19.40.30}] failed: NT_STATUS_ACCESS_DENIED The reason is subtle: shadow_copy2 calculates inode numbers of snapshot files based on the path of the file. The result of that when doing a path based stat() from filename_convert() was [2021/07/06 04:58:17.676159, 10, pid=95070, effective(1000, 1000), real(1000, 0)] ../../source3/smbd/filename.c:1945(filename_convert_internal) filename_convert_internal: XXX smb_fname [subdir/hardlink {@GMT-2015.10.31-19.40.30}] (dev=64770, ino=3826943444). which is the "Old" inode shown above. Later in the open code called from openat_pathref_fsp() -> fd_openat() -> non_widelink_open() since 4.14 we call SMB_VFS_FSTAT() where fsp->fsp_name will be set to the new relative *basename* of the file: [2021/07/06 04:58:17.676917, 10, pid=95070, effective(1000, 1000), real(1000, 0), class=vfs] ../../source3/modules/vfs_default.c:1302(vfswrap_fstat) vfswrap_fstat: XXX fsp [hardlink {@GMT-2015.10.31-19.40.30}] (dev=64770, ino=3826943444) So for stat() the hash function in called with the full path relative to the share root: subdir/hardlink while for fstat() the hash function will used hardlink BUG: https://bugzilla.samba.org/show_bug.cgi?id=14756 Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org> (cherry picked from commit 4a7e483c516cf2b9767919a764f05c43f4620cd7)
-rw-r--r--selftest/knownfail.d/samba3.blackbox.shadow_copy_torture1
-rwxr-xr-xsource3/script/tests/test_shadow_copy_torture.sh26
2 files changed, 27 insertions, 0 deletions
diff --git a/selftest/knownfail.d/samba3.blackbox.shadow_copy_torture b/selftest/knownfail.d/samba3.blackbox.shadow_copy_torture
new file mode 100644
index 00000000000..aa68c3f3bbe
--- /dev/null
+++ b/selftest/knownfail.d/samba3.blackbox.shadow_copy_torture
@@ -0,0 +1 @@
+^samba3.blackbox.shadow_copy_torture.fix inodes with hardlink\(fileserver\)
diff --git a/source3/script/tests/test_shadow_copy_torture.sh b/source3/script/tests/test_shadow_copy_torture.sh
index bfb698dd9c9..1185ad5da11 100755
--- a/source3/script/tests/test_shadow_copy_torture.sh
+++ b/source3/script/tests/test_shadow_copy_torture.sh
@@ -34,6 +34,9 @@ build_files()
destdir=$1
echo "$content" > $destdir/foo
+
+ mkdir -p $WORKDIR/subdir/
+ touch $WORKDIR/subdir/hardlink
}
# build a snapshots directory
@@ -46,6 +49,9 @@ build_snapshots()
mkdir -p $snapdir/$SNAPSHOT
build_files $snapdir/$SNAPSHOT
+
+ mkdir -p $snapdir/$SNAPSHOT/subdir
+ ln "$WORKDIR"/subdir/hardlink "$snapdir"/$SNAPSHOT/subdir/hardlink
}
build_stream_on_snapshot()
@@ -124,6 +130,24 @@ test_shadow_copy_openroot()
failed=`expr $failed + 1`
}
+test_shadow_copy_fix_inodes()
+{
+ local msg
+
+ msg=$1
+
+ #delete snapshots from previous tests
+ find $WORKDIR -name ".snapshots" -exec rm -rf {} \; 1>/dev/null 2>&1
+ build_snapshots
+
+ out=$($SMBCLIENT \
+ -U $USERNAME%$PASSWORD \
+ "//$SERVER/shadow_write" \
+ -c "open $SNAPSHOT/subdir/hardlink") || failed=`expr $failed + 1`
+ echo $out
+ echo $out | grep "hardlink: for read/write fnum 1" || return 1
+}
+
build_files $WORKDIR
# test open for writing and write behaviour of snapshoted files
@@ -133,4 +157,6 @@ test_shadow_copy_stream "reading stream of snapshotted file"
test_shadow_copy_openroot "opening root of shadow copy share"
+testit "fix inodes with hardlink" test_shadow_copy_fix_inodes || failed=`expr $failed + 1`
+
exit $failed