Whamcloud - gitweb
LU-9219 tests: add missing mgs reformat to conf-sanity/56
[fs/lustre-release.git] / lustre / tests / metadata-updates.sh
1 #!/bin/bash
2
3 # A Metadata Update Test tests that
4 # metadata updates are properly completed when
5 # multiple clients create/delete files and modify the attributes of files.
6
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 #Bug number for excepting test
12 ALWAYS_EXCEPT="$METADATA_UPDATES_EXCEPT"
13 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT LIST
14
15 [ "$SLOW" = "no" ] && EXCEPT_SLOW=""
16
17 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
18 . $LUSTRE/tests/test-framework.sh
19 init_test_env $@
20 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
21 init_logging
22
23 TRACE=${TRACE:-"+x"}
24
25 TESTDIR=${TESTDIR:-$DIR/d0.$(basename $0 .sh)}
26
27 NODES_TO_USE=${NODES_TO_USE:-$CLIENTS}
28
29 [ -z $CLIENTS ] && NODES_TO_USE=$(hostname)
30
31 # hostname could differ from a network interface
32 # configured for NODES_TO_USE, bug 23961
33 # the test dir on each host is created based on `hostname` of this host
34 HOSTS=$(comma_list $(do_nodes $NODES_TO_USE "echo \\\$(hostname)"))
35
36 FILE=testfile
37 FILE_SIZE=1024
38 CURRENT_MODE=0644
39 NEW_MODE=0222
40 NEW_ATIME="2001-01-01 GMT"
41 NEW_MTIME="2005-05-05 GMT"
42
43 test_USER=$(id -u -n)
44 test_GROUP=$(id -g -n)
45
46 SUMFILE=$TESTDIR/mdsum
47
48 NUM_FILES=1000
49
50 log "===== $0 ====== "
51
52 check_and_setup_lustre
53 build_test_filter
54
55 cleanup_prepare () {
56
57         do_nodes $NODES_TO_USE "set $TRACE;
58         DIR=$TESTDIR/\\\$(hostname);
59         TESTFILE=\\\$DIR/$FILE;
60         rm -f \\\$TESTFILE;
61         rm -f $SUMFILE;
62         rmdir \\\$DIR 2>/dev/null;
63         mkdir -p \\\$DIR" || return ${PIPESTATUS[0]}
64         return 0;
65 }
66
67 do_mknod () {
68         log "Creating file(s) by mknod (2) ... "
69
70         do_nodes $NODES_TO_USE "set $TRACE;
71         TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
72         mcreate \\\$TESTFILE; " || return ${PIPESTATUS[0]}
73         return 0
74 }
75
76 do_write () {
77         do_nodes $NODES_TO_USE "set $TRACE;
78         TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
79         dd if=/dev/zero of=\\\$TESTFILE bs=$FILE_SIZE count=1 2>/dev/null ||
80                 exit 54;
81         echo \\\$(hostname) | dd of=\\\$TESTFILE conv=notrunc 2>/dev/null ||
82                 exit 55;
83         md5sum \\\$TESTFILE >> $SUMFILE; " || return ${PIPESTATUS[0]}
84         return 0
85 }
86
87 do_check_data () {
88         log "Checking file(s) data ... md5sum : "
89         cat $SUMFILE
90
91         do_nodesv $NODES_TO_USE "md5sum --check $SUMFILE" ||
92                 return ${PIPESTATUS[0]}
93         return 0
94 }
95
96 do_truncate () {
97         log "Truncating file(s) ... "
98
99         do_nodes $NODES_TO_USE "set $TRACE;
100         TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
101         $TRUNCATE \\\$TESTFILE 0" || return ${PIPESTATUS[0]}
102
103         FILE_SIZE=0
104         return 0
105 }
106
107 # check st_uid, st_gid, st_size, st_mode
108 get_stat () {
109         local attr="$test_USER $test_GROUP $FILE_SIZE $CURRENT_MODE"
110
111         log "Checking file(s) attributes ... "
112
113         do_nodesv $NODES_TO_USE "set $TRACE;
114 for HOST in ${HOSTS//,/ } ; do
115     TESTFILE=$TESTDIR/\\\$HOST/$FILE;
116     tmp=\\\$(stat -c \\\"%U %G %s 0%a\\\" \\\$TESTFILE);
117     echo \\\"\\\$TESTFILE [ uid gid size mode ] expected : $attr ;  got : \\\$tmp \\\";
118     if [ x\\\"\\\$tmp\\\" != x\\\"$attr\\\" ] ; then
119         echo \\\"Wrong file attributes\\\";
120         exit 56;
121     fi;
122 done " || return ${PIPESTATUS[0]}
123         return 0
124 }
125
126 do_chmod () {
127         log "Performing chmod 0$NEW_MODE ..."
128
129         do_nodes $NODES_TO_USE "set $TRACE;
130         TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
131         chmod $NEW_MODE \\\$TESTFILE" || return ${PIPESTATUS[0]}
132
133         CURRENT_MODE=$NEW_MODE
134         return 0
135 }
136
137 do_change_timestamps () {
138         log "Changing atime, mtime ..."
139
140         do_nodes $NODES_TO_USE " set $TRACE;
141         TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
142         touch -c --date=\\\"$NEW_ATIME\\\" -a \\\$TESTFILE;
143         touch -c --date=\\\"$NEW_MTIME\\\" -m \\\$TESTFILE " ||
144                 return ${PIPESTATUS[0]}
145         return 0
146 }
147
148 # check st_atime, st_mtime
149 do_check_timestamps () {
150         local atime=$(date --date="$NEW_ATIME" +%s)
151         local mtime=$(date --date="$NEW_MTIME" +%s)
152
153         local times="$atime $mtime"
154
155         log "Checking atime, mtime ... "
156
157         do_nodesv $NODES_TO_USE "set $TRACE;
158 for HOST in ${HOSTS//,/ } ; do
159     TESTFILE=$TESTDIR/\\\$HOST/$FILE;
160     tmp=\\\$(stat -c \\\"%X %Y\\\" \\\$TESTFILE);
161     if [ x\\\"\\\$tmp\\\" != x\\\"$times\\\" ] ; then
162        echo \\\"\\\$TESTFILE [ atime mtime ] expected : $times ;  got : \\\$tmp \\\";
163        RC=57;
164     fi;
165 done;
166 exit \\\$RC" || return ${PIPESTATUS[0]}
167         return 0
168 }
169
170 do_fill_dir () {
171         log "Filling up directories ... files : f1 ... f$NUM_FILES) ... "
172
173         do_nodes $NODES_TO_USE "set $TRACE;
174         TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
175         rm -f \\\$TESTFILE;
176         DIR=$TESTDIR/\\\$(hostname);
177         for i in \\\$(seq $NUM_FILES) ; do
178                 touch \\\$DIR/f\\\$i;
179         done " || return ${PIPESTATUS[0]}
180         return 0
181 }
182
183 check_dir_contents () {
184         local num_files=${1:-1}
185
186         log "Directory contents should exist: f$num_files ... f$NUM_FILES)"
187         do_nodes $NODES_TO_USE "set $TRACE;
188 for HOST in ${HOSTS//,/ } ; do
189     DIR=$TESTDIR/\\\$HOST;
190     for i in \\\$(seq $NUM_FILES -1 $num_files) ; do
191         if ! [ -f \\\$DIR/f\\\$i ] ; then
192             echo \\\"ERROR: file \\\$DIR/f\\\$i should exist\\\";
193             RC=1;
194         fi;
195     done;
196     for i in \\\$(seq $(($num_files - 1 ))) ; do
197         if [ -f \\\$DIR/f\\\$i ] ; then
198             echo \\\"ERROR: deleted file \\\$DIR/f\\\$i exists\\\";
199             RC=1;
200         fi;
201     done;
202 done;
203 exit \\\$RC " || return ${PIPESTATUS[0]}
204         return 0
205 }
206
207 do_partial_delete () {
208         local num_files=$1
209
210         log "Deleting files ... f1 ... f$num_files ... "
211         do_nodes $NODES_TO_USE "set $TRACE;
212 DIR=$TESTDIR/\\\$(hostname);
213 for i in \\\$(seq $num_files) ; do
214     if ! rm -f \\\$DIR/f\\\$i ; then
215         exit 1;
216     fi;
217 done " || return ${PIPESTATUS[0]}
218         return 0
219 }
220
221 chmod 0777 $MOUNT   || exit 1
222 mkdir -p $TESTDIR   || exit 1
223 chmod 0777 $TESTDIR || exit 1
224
225 cleanup_prepare     || error_exit "cleanup failed"
226
227 test_1(){
228         log "Create files (mknod (2)) and write data"
229         do_mknod || error "mknod failed"
230         do_write || error "write data failed"
231         log "Check data and file attributes."
232         do_check_data || error "md5sum verification failed"
233         get_stat || error "attributes check failed"
234
235         # file attributes modification
236         log "File attributes modification."
237         do_chmod || error "chmod failed"
238         get_stat || error "wrong attributes after chmod"
239
240         do_change_timestamps || error "timestamps change failed"
241         do_check_timestamps || error "wrong timestamps"
242
243         # truncate file(s) to 0 size, check new file size
244         log "Truncate file(s) to 0 size, check new file size."
245         do_truncate || error "truncate failed"
246         get_stat || error "wrong attributes after truncate"
247 }
248 run_test 1 "create files (mknod), write and check data, truncate files"
249
250 test_2() {
251         do_fill_dir || error "dir creation failed"
252         check_dir_contents || error "dir contents check failed"
253
254         do_partial_delete $(($NUM_FILES / 2)) || error "delete failed"
255         check_dir_contents $(($NUM_FILES / 2 + 1)) ||
256                 error "dir contents check after delete failed"
257 }
258 run_test 2 "directory content create, check, delete files , check"
259
260 test_3() {
261         WRITE_DISJOINT=${WRITE_DISJOINT:-$(which write_disjoint 2> /dev/null)} || true
262         disjoint_file=$TESTDIR/$tfile
263         machine_file=${MACHINEFILE:-$TMP/$(basename $0 .sh).machines}
264         numloops=1000
265
266         if [ ! -f "$WRITE_DISJOINT" ]; then
267                 skip_env "$0 : write_disjoint not found "
268                 return
269         fi
270
271         set $TRACE
272         generate_machine_file $NODES_TO_USE $machine_file
273         mpi_run ${MACHINEFILE_OPTION} $machine_file \
274                 -np $(get_node_count ${NODES_TO_USE//,/ }) \
275                 $WRITE_DISJOINT -f $disjoint_file -n $numloops ||
276                         error "mpi_run failed"
277
278         rm -f $machine_file
279 }
280 run_test 3 "write_disjoint test"
281
282 complete $SECONDS
283 rm -rf $TESTDIR
284 check_and_cleanup_lustre
285 exit_status