common: add infrastructure for renameat2 syscall tests

The renameat2() syscall was merged into 3.15-rc (merge commit:
7df934526c0b).

This adds the shared infrastructure for the actual test scripts.

Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
Miklos Szeredi
2014-04-14 10:34:51 +10:00
committed by Dave Chinner
parent a0e2d8ecc0
commit 413f501b53
5 changed files with 236 additions and 1 deletions
+1
View File
@@ -106,6 +106,7 @@
/src/aio-dio-regress/aio-io-setup-with-nonwritable-context-pointer
/src/aio-dio-regress/aiodio_sparse2
/src/cloner
/src/renameat2
# dmapi/ binaries
/dmapi/src/common/cmd/read_invis
+129
View File
@@ -0,0 +1,129 @@
######
#
# renameat2 helpers
#
#-----------------------------------------------------------------------
# Copyright (c) 2014 Miklos Szeredi. All Rights Reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it would be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# 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
# along with this program; if not, write the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#-----------------------------------------------------------------------
#
#
# Setup source or dest
#
_setup_one()
{
local path=$1
local type=$2
case $type in
none) ;;
regu) echo foo > $path;;
symb) ln -s foo $path;;
dire) mkdir $path;;
tree) mkdir $path; echo foo > $path/bar;;
esac
}
#
# Cleanup source or dest
#
_cleanup_one()
{
local path=$1
if test -d $path; then
rm -f $path/bar
rmdir $path
else
rm -f $path
fi
}
#
# Check type of source or destination
#
_showtype_one()
{
local path=$1
if test -e $path -o -h $path; then
if test -d $path -a -e $path/bar; then
echo -n "tree"
else
echo -n `stat -c %F $path | cut -b-4`
fi
else
echo -n "none"
fi
}
#
# This runs renameat2 on all combinations of source and dest
#
_rename_tests_source_dest()
{
local source=$1
local dest=$2
local options=$3
for stype in none regu symb dire tree; do
for dtype in none regu symb dire tree; do
echo -n "$options $stype/$dtype -> "
_setup_one $source $stype
_setup_one $dest $dtype
src/renameat2 $source $dest $flags
if test $? == 0; then
_showtype_one $source
echo -n "/"
_showtype_one $dest
echo "."
fi
_cleanup_one $source
_cleanup_one $dest
done
done
}
#
# This runs _rename_tests_source_dest() for both same-directory and
# cross-directory renames
#
_rename_tests()
{
local testdir=$1
local flags=$2
#same directory renames
_rename_tests_source_dest $testdir/src $testdir/dst "samedir "
#cross directory renames
mkdir $testdir/x $testdir/y
_rename_tests_source_dest $testdir/x/src $testdir/y/dst "crossdir"
rmdir $testdir/x $testdir/y
}
#
# This checks whether the renameat2 syscall is supported
#
_requires_renameat2()
{
if test ! -x src/renameat2; then
_notrun "renameat2 binary not found"
fi
if ! src/renameat2 -t; then
_notrun "kernel doesn't support renameat2 syscall"
fi
}
+2
View File
@@ -76,6 +76,8 @@ in
;;
esac
AC_CHECK_FUNCS([renameat2])
AC_CONFIG_HEADER(include/config.h)
AC_CONFIG_FILES([include/builddefs])
AC_OUTPUT
+2 -1
View File
@@ -18,7 +18,8 @@ LINUX_TARGETS = xfsctl bstat t_mtab getdevicesize preallo_rw_pattern_reader \
locktest unwritten_mmap bulkstat_unlink_test t_stripealign \
bulkstat_unlink_test_modified t_dir_offset t_futimens t_immutable \
stale_handle pwrite_mmap_blocked t_dir_offset2 seek_sanity_test \
seek_copy_test t_readdir_1 t_readdir_2 fsync-tester nsexec cloner
seek_copy_test t_readdir_1 t_readdir_2 fsync-tester nsexec cloner \
renameat2
SUBDIRS =
+102
View File
@@ -0,0 +1,102 @@
/*
* Copyright (c) 2014, Miklos Szeredi <mszeredi@suse.cz>
* This file is published under GPL2+.
*
* This is a trivial wrapper around the renameat2 syscall.
*/
#include "global.h"
#ifndef HAVE_RENAMEAT2
#include <sys/syscall.h>
#if !defined(SYS_renameat2) && defined(__x86_64__)
#define SYS_renameat2 316
#endif
static int renameat2(int dfd1, const char *path1,
int dfd2, const char *path2,
unsigned int flags)
{
#ifdef SYS_renameat2
return syscall(SYS_renameat2, dfd1, path1, dfd2, path2, flags);
#else
errno = ENOSYS;
return -1;
#endif
}
#endif
#ifndef RENAME_NOREPLACE
#define RENAME_NOREPLACE (1 << 0) /* Don't overwrite target */
#endif
#ifndef RENAME_EXCHANGE
#define RENAME_EXCHANGE (1 << 1) /* Exchange source and dest */
#endif
#ifndef RENAME_WHITEOUT
#define RENAME_WHITEOUT (1 << 2) /* Whiteout source */
#endif
int main(int argc, char *argv[])
{
int ret;
int c;
const char *path1 = NULL;
const char *path2 = NULL;
unsigned int flags = 0;
int test = 0;
for (c = 1; c < argc; c++) {
if (argv[c][0] == '-') {
switch (argv[c][1]) {
case 't':
test = 1;
break;
case 'n':
flags |= RENAME_NOREPLACE;
break;
case 'x':
flags |= RENAME_EXCHANGE;
break;
case 'w':
flags |= RENAME_WHITEOUT;
break;
default:
goto usage;
}
} else if (!path1) {
path1 = argv[c];
} else if (!path2) {
path2 = argv[c];
} else {
goto usage;
}
}
if (!test && (!path1 || !path2))
goto usage;
ret = renameat2(AT_FDCWD, path1, AT_FDCWD, path2, flags);
if (ret == -1) {
if (test) {
if (errno == ENOSYS || errno == EINVAL)
return 1;
else
return 0;
}
perror("");
return 1;
}
return 0;
usage:
fprintf(stderr,
"usage: %s [-t] [-n|-x|-w] path1 path2\n"
" -t test\n"
" -n noreplace\n"
" -x exchange\n"
" -w whiteout\n", argv[0]);
return 1;
}