common: check if a given rename flag is supported in _require_renameat2
[xfstests-dev.git] / common / renameat2
1 ##/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2014 Miklos Szeredi.  All Rights Reserved.
4 #
5 # renameat2 helpers
6
7 # Setup source or dest
8 #
9 _setup_one()
10 {
11         local path=$1
12         local type=$2
13
14         case $type in
15                 none)   ;;
16                 regu)   echo foo > $path;;
17                 symb)   ln -s foo $path;;
18                 dire)   mkdir $path;;
19                 tree)   mkdir $path; echo foo > $path/bar;;
20         esac
21 }
22
23 #
24 # Cleanup source or dest
25 #
26 _cleanup_one()
27 {
28         local path=$1
29
30         if test -d $path; then
31                 rm -f $path/bar
32                 rmdir $path
33         else
34                 rm -f $path
35         fi
36 }
37
38 #
39 # Check type of source or destination
40 #
41 _showtype_one()
42 {
43         local path=$1
44
45         if test -e $path -o -h $path; then
46                 if test -d $path -a -e $path/bar; then
47                         echo -n "tree"
48                 else
49                         echo -n `stat -c %F $path | cut -b-4`
50                 fi
51         else
52                 echo -n "none"
53         fi
54 }
55
56 #
57 # This runs renameat2 on all combinations of source and dest
58 #
59 _rename_tests_source_dest()
60 {
61         local source=$1
62         local dest=$2
63         local options=$3
64
65         for stype in none regu symb dire tree; do
66                 for dtype in none regu symb dire tree; do
67                         echo -n "$options $stype/$dtype -> "
68                         _setup_one $source $stype
69                         _setup_one $dest $dtype
70                         src/renameat2 $source $dest $flags
71                         if test $? == 0; then
72                                 _showtype_one $source
73                                 echo -n "/"
74                                 _showtype_one $dest
75                                 echo "."
76                         fi
77                         _cleanup_one $source
78                         _cleanup_one $dest
79                 done
80         done
81 }
82
83 #
84 # This runs _rename_tests_source_dest() for both same-directory and
85 # cross-directory renames
86 #
87 _rename_tests()
88 {
89         local testdir=$1
90         local flags=$2
91
92         #same directory renames
93         _rename_tests_source_dest $testdir/src $testdir/dst     "samedir "
94
95         #cross directory renames
96         mkdir $testdir/x $testdir/y
97         _rename_tests_source_dest $testdir/x/src $testdir/y/dst "crossdir"
98         rmdir $testdir/x $testdir/y
99 }
100
101 #
102 # This checks whether the renameat2 syscall is supported
103 #
104 _require_renameat2()
105 {
106         local flags=$1
107         local rename_dir=$TEST_DIR/$$
108         local cmd=""
109
110         if test ! -x src/renameat2; then
111                 _notrun "renameat2 binary not found"
112         fi
113
114         mkdir $rename_dir
115         touch $rename_dir/foo
116         case $flags in
117         "noreplace")
118                 cmd="-n $rename_dir/foo $rename_dir/bar"
119                 ;;
120         "exchange")
121                 touch $rename_dir/bar
122                 cmd="-x $rename_dir/foo $rename_dir/bar"
123                 ;;
124         "whiteout")
125                 touch $rename_dir/bar
126                 cmd="-w $rename_dir/foo $rename_dir/bar"
127                 ;;
128         "")
129                 cmd=""
130                 ;;
131         *)
132                 rm -rf $rename_dir
133                 _fail "_require_renameat2: only support noreplace,exchange,whiteout rename flags"
134                 ;;
135         esac
136         if ! src/renameat2 -t $cmd; then
137                 rm -rf $rename_dir
138                 _notrun "kernel doesn't support renameat2 syscall"
139         fi
140         rm -rf $rename_dir
141 }