mirror of
https://github.com/ostreedev/ostree.git
synced 2024-12-22 17:35:55 +03:00
08eaf66827
If you lchown("symlink") then we were incorrectly trying to chown the symlink target, rather than the symlink itself. In particular, this cause cp -a to fail for a broken symlink. Additionally, it was using the symlink target when verifying writability, rather than the symlink itself. To fix this, we need pass AT_SYMLINK_NOFOLLOW in these cases. In general, the kernel itself will always resolve any symlinks for us before calling into the fuse backend, so we should really never do any symlink following in the fuse fs itself. So, we pro-actively add NOFOLLOW flags to a few other places: truncate: In reality this will never be hit, because the kernel will resolve symlinks before calling us. access: It seems the current fuse implementation never calls this (faccessat w/AT_SYMLINK_NOFOLLOW never reaches the fuse fs) but if this ever is implemented this is the correct behaviour. We would ideally do `chmod` but this is not implemented on current kernels. Because we're not multi-threaded, this is OK anyways. Further, our write verification wasn't correctly handling the case of hardlinked symlinks, which can occur for `bare` checkouts but *not* `bare-user` which the tests were using. Change to `bare` mode to verify that. Closes: #1137 Approved by: alexlarsson
117 lines
4.0 KiB
Bash
Executable File
117 lines
4.0 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Copyright (C) 2016 Colin Walters <walters@verbum.org>
|
|
#
|
|
# This library is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU Lesser General Public
|
|
# License as published by the Free Software Foundation; either
|
|
# version 2 of the License, or (at your option) any later version.
|
|
#
|
|
# This library is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
# Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public
|
|
# License along with this library; if not, write to the
|
|
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
# Boston, MA 02111-1307, USA.
|
|
|
|
set -euo pipefail
|
|
|
|
. $(dirname $0)/libtest.sh
|
|
|
|
skip_without_fuse
|
|
skip_without_user_xattrs
|
|
|
|
setup_test_repository "bare"
|
|
|
|
echo "1..7"
|
|
|
|
cd ${test_tmpdir}
|
|
mkdir mnt
|
|
# The default content set amazingly doesn't have a non-broken link
|
|
ln -s firstfile files/firstfile-link
|
|
$OSTREE commit -b test2 --tree=dir=files
|
|
$OSTREE checkout -H test2 checkout-test2
|
|
|
|
rofiles-fuse checkout-test2 mnt
|
|
cleanup_fuse() {
|
|
fusermount -u ${test_tmpdir}/mnt || true
|
|
}
|
|
trap cleanup_fuse EXIT
|
|
assert_file_has_content mnt/firstfile first
|
|
echo "ok mount"
|
|
|
|
# Test open(O_TRUNC) directly and via symlink
|
|
for path in firstfile{,-link}; do
|
|
if cp /dev/null mnt/${path} 2>err.txt; then
|
|
assert_not_reached "inplace mutation ${path}"
|
|
fi
|
|
assert_file_has_content err.txt "Read-only file system"
|
|
assert_file_has_content mnt/firstfile first
|
|
assert_file_has_content checkout-test2/firstfile first
|
|
done
|
|
echo "ok failed inplace mutation (open O_TRUNCATE)"
|
|
|
|
# Test chmod
|
|
if chmod 0600 mnt/firstfile 2>err.txt; then
|
|
assert_not_reached "chmod inplace"
|
|
fi
|
|
assert_file_has_content err.txt "chmod:.*Read-only file system"
|
|
# Test chown with regfiles and symlinks
|
|
for path in firstfile baz/alink; do
|
|
if chown -h $(id -u) mnt/${path} 2>err.txt; then
|
|
assert_not_reached "chown inplace ${path}"
|
|
fi
|
|
assert_file_has_content err.txt "chown:.*Read-only file system"
|
|
done
|
|
# And test via dereferencing a symlink
|
|
if chown $(id -u) mnt/firstfile-link 2>err.txt; then
|
|
assert_not_reached "chown inplace firstfile-link"
|
|
fi
|
|
assert_file_has_content err.txt "chown:.*Read-only file system"
|
|
echo "ok failed mutation chmod + chown"
|
|
|
|
# Test creating new files, using chown + chmod on them as well
|
|
echo anewfile-for-fuse > mnt/anewfile-for-fuse
|
|
assert_file_has_content mnt/anewfile-for-fuse anewfile-for-fuse
|
|
assert_file_has_content checkout-test2/anewfile-for-fuse anewfile-for-fuse
|
|
ln -s anewfile-for-fuse mnt/anewfile-for-fuse-link
|
|
# And also test modifications through a symlink
|
|
echo writevialink > mnt/anewfile-for-fuse-link
|
|
for path in anewfile-for-fuse{,-link}; do
|
|
assert_file_has_content mnt/${path} writevialink
|
|
done
|
|
chown $(id -u) mnt/anewfile-for-fuse-link
|
|
|
|
mkdir mnt/newfusedir
|
|
for i in $(seq 5); do
|
|
echo ${i}-morenewfuse-${i} > mnt/newfusedir/test-morenewfuse.${i}
|
|
chmod 0600 mnt/newfusedir/test-morenewfuse.${i}
|
|
chown $(id -u) mnt/newfusedir/test-morenewfuse.${i}
|
|
done
|
|
assert_file_has_content checkout-test2/newfusedir/test-morenewfuse.3 3-morenewfuse-3
|
|
echo "ok new content"
|
|
|
|
rm mnt/baz/cow
|
|
assert_not_has_file checkout-test2/baz/cow
|
|
rm mnt/baz/another -rf
|
|
assert_not_has_dir checkout-test2/baz/another
|
|
|
|
echo "ok deletion"
|
|
|
|
${CMD_PREFIX} ostree --repo=repo commit -b test2 -s fromfuse --link-checkout-speedup --tree=dir=checkout-test2
|
|
|
|
echo "ok commit"
|
|
|
|
${CMD_PREFIX} ostree --repo=repo checkout -U test2 mnt/test2-checkout-copy-fallback
|
|
assert_file_has_content mnt/test2-checkout-copy-fallback/anewfile-for-fuse writevialink
|
|
|
|
if ${CMD_PREFIX} ostree --repo=repo checkout -UH test2 mnt/test2-checkout-copy-hardlinked 2>err.txt; then
|
|
assert_not_reached "Checking out via hardlinks across mountpoint unexpectedly succeeded!"
|
|
fi
|
|
assert_file_has_content err.txt "Unable to do hardlink checkout across devices"
|
|
|
|
echo "ok checkout copy fallback"
|