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.
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
15 [ "$SLOW" = "no" ] && EXCEPT_SLOW=""
17 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
18 . $LUSTRE/tests/test-framework.sh
20 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
25 TESTDIR=${TESTDIR:-$DIR/d0.$(basename $0 .sh)}
27 NODES_TO_USE=${NODES_TO_USE:-$CLIENTS}
29 [ -z $CLIENTS ] && NODES_TO_USE=$(hostname)
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)"))
40 NEW_ATIME="2001-01-01 GMT"
41 NEW_MTIME="2005-05-05 GMT"
44 test_GROUP=$(id -g -n)
46 SUMFILE=$TESTDIR/mdsum
50 log "===== $0 ====== "
52 check_and_setup_lustre
57 do_nodes $NODES_TO_USE "set $TRACE;
58 DIR=$TESTDIR/\\\$(hostname);
59 TESTFILE=\\\$DIR/$FILE;
62 rmdir \\\$DIR 2>/dev/null;
63 mkdir -p \\\$DIR" || return ${PIPESTATUS[0]}
68 log "Creating file(s) by mknod (2) ... "
70 do_nodes $NODES_TO_USE "set $TRACE;
71 TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
72 mcreate \\\$TESTFILE; " || return ${PIPESTATUS[0]}
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 ||
81 echo \\\$(hostname) | dd of=\\\$TESTFILE conv=notrunc 2>/dev/null ||
83 md5sum \\\$TESTFILE >> $SUMFILE; " || return ${PIPESTATUS[0]}
88 log "Checking file(s) data ... md5sum : "
91 do_nodesv $NODES_TO_USE "md5sum --check $SUMFILE" ||
92 return ${PIPESTATUS[0]}
97 log "Truncating file(s) ... "
99 do_nodes $NODES_TO_USE "set $TRACE;
100 TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
101 $TRUNCATE \\\$TESTFILE 0" || return ${PIPESTATUS[0]}
107 # check st_uid, st_gid, st_size, st_mode
109 local attr="$test_USER $test_GROUP $FILE_SIZE $CURRENT_MODE"
111 log "Checking file(s) attributes ... "
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\\\";
122 done " || return ${PIPESTATUS[0]}
127 log "Performing chmod 0$NEW_MODE ..."
129 do_nodes $NODES_TO_USE "set $TRACE;
130 TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
131 chmod $NEW_MODE \\\$TESTFILE" || return ${PIPESTATUS[0]}
133 CURRENT_MODE=$NEW_MODE
137 do_change_timestamps () {
138 log "Changing atime, mtime ..."
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]}
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)
153 local times="$atime $mtime"
155 log "Checking atime, mtime ... "
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 \\\";
166 exit \\\$RC" || return ${PIPESTATUS[0]}
171 log "Filling up directories ... files : f1 ... f$NUM_FILES) ... "
173 do_nodes $NODES_TO_USE "set $TRACE;
174 TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
176 DIR=$TESTDIR/\\\$(hostname);
177 for i in \\\$(seq $NUM_FILES) ; do
178 touch \\\$DIR/f\\\$i;
179 done " || return ${PIPESTATUS[0]}
183 check_dir_contents () {
184 local num_files=${1:-1}
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\\\";
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\\\";
203 exit \\\$RC " || return ${PIPESTATUS[0]}
207 do_partial_delete () {
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
217 done " || return ${PIPESTATUS[0]}
221 chmod 0777 $MOUNT || exit 1
222 mkdir -p $TESTDIR || exit 1
223 chmod 0777 $TESTDIR || exit 1
225 cleanup_prepare || error_exit "cleanup failed"
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"
235 # file attributes modification
236 log "File attributes modification."
237 do_chmod || error "chmod failed"
238 get_stat || error "wrong attributes after chmod"
240 do_change_timestamps || error "timestamps change failed"
241 do_check_timestamps || error "wrong timestamps"
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"
248 run_test 1 "create files (mknod), write and check data, truncate files"
251 do_fill_dir || error "dir creation failed"
252 check_dir_contents || error "dir contents check failed"
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"
258 run_test 2 "directory content create, check, delete files , check"
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}
266 [ ! -f "$WRITE_DISJOINT" ] && skip_env "write_disjoint not found"
269 generate_machine_file $NODES_TO_USE $machine_file
270 mpi_run ${MACHINEFILE_OPTION} $machine_file \
271 -np $(get_node_count ${NODES_TO_USE//,/ }) \
272 $WRITE_DISJOINT -f $disjoint_file -n $numloops ||
273 error "mpi_run failed"
277 run_test 3 "write_disjoint test"
281 check_and_cleanup_lustre