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.
9 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
10 . $LUSTRE/tests/test-framework.sh
12 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
16 TESTDIR=${TESTDIR:-$DIR/d0.$(basename $0 .sh)}
18 NODES_TO_USE=${NODES_TO_USE:-$CLIENTS}
20 [ -z $CLIENTS ] && NODES_TO_USE=$(hostname)
26 NEW_ATIME="2001-01-01 GMT"
27 NEW_MTIME="2005-05-05 GMT"
32 SUMFILE=$TESTDIR/mdsum
36 WRITE_DISJOINT=${WRITE_DISJOINT:-$(which write_disjoint 2> /dev/null)} || true
37 WRITE_DISJOINT_FILE=$TESTDIR/f0.write_disjoint_file
40 log "===== $0 ====== "
42 check_and_setup_lustre
46 do_nodes $NODES_TO_USE "set $TRACE;
47 DIR=$TESTDIR/\\\$(hostname);
48 TESTFILE=\\\$DIR/$FILE;
51 rmdir \\\$DIR 2>/dev/null;
52 mkdir -p \\\$DIR" || return ${PIPESTATUS[0]}
57 echo "Creating file(s) by mknod (2) ... "
59 do_nodes $NODES_TO_USE "set $TRACE;
60 TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
61 mcreate \\\$TESTFILE; " || return ${PIPESTATUS[0]}
66 do_nodes $NODES_TO_USE "set $TRACE;
67 TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
68 dd if=/dev/zero of=\\\$TESTFILE bs=$FILE_SIZE count=1 2>/dev/null || exit 54;
69 echo \\\$(hostname) | dd of=\\\$TESTFILE conv=notrunc 2>/dev/null || exit 55;
70 md5sum \\\$TESTFILE >> $SUMFILE; " || return ${PIPESTATUS[0]}
75 echo "Checking file(s) data ... md5sum : "
78 do_nodesv $NODES_TO_USE "md5sum --check $SUMFILE" || \
79 return ${PIPESTATUS[0]}
84 echo "Truncating file(s) ... "
86 do_nodes $NODES_TO_USE "set $TRACE;
87 TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
88 truncate \\\$TESTFILE 0" || return ${PIPESTATUS[0]}
94 # check st_uid, st_gid, st_size, st_mode
96 local attr="$test_UID $test_GID $FILE_SIZE $CURRENT_MODE"
98 echo "Checking file(s) attributes ... "
100 do_nodesv $NODES_TO_USE "set $TRACE;
101 for HOST in ${NODES_TO_USE//,/ } ; do
102 TESTFILE=$TESTDIR/\\\$HOST/$FILE;
103 tmp=\\\$(stat -c \\\"%u %g %s 0%a\\\" \\\$TESTFILE);
104 echo \\\"\\\$TESTFILE [ uid gid size mode ] expected : $attr ; got : \\\$tmp \\\";
105 if [ x\\\"\\\$tmp\\\" != x\\\"$attr\\\" ] ; then
106 echo \\\"Wrong file attributes\\\";
109 done " || return ${PIPESTATUS[0]}
114 echo "Performing chmod 0$NEW_MODE ..."
116 do_nodes $NODES_TO_USE "set $TRACE;
117 TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
118 chmod $NEW_MODE \\\$TESTFILE" || return ${PIPESTATUS[0]}
120 CURRENT_MODE=$NEW_MODE
124 do_change_timestamps () {
125 echo "Changing atime, mtime ..."
127 do_nodes $NODES_TO_USE " set $TRACE;
128 TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
129 touch -c --date=\\\"$NEW_ATIME\\\" -a \\\$TESTFILE;
130 touch -c --date=\\\"$NEW_MTIME\\\" -m \\\$TESTFILE " || return ${PIPESTATUS[0]}
134 # check st_atime, st_mtime
135 do_check_timestamps () {
136 local atime=$(date --date="$NEW_ATIME" +%s)
137 local mtime=$(date --date="$NEW_MTIME" +%s)
139 local times="$atime $mtime"
141 echo "Checking atime, mtime ... "
143 do_nodesv $NODES_TO_USE "set $TRACE;
144 for HOST in ${NODES_TO_USE//,/ } ; do
145 TESTFILE=$TESTDIR/\\\$HOST/$FILE;
146 tmp=\\\$(stat -c \\\"%X %Y\\\" \\\$TESTFILE);
147 if [ x\\\"\\\$tmp\\\" != x\\\"$times\\\" ] ; then
148 echo \\\"\\\$TESTFILE [ atime mtime ] expected : $times ; got : \\\$tmp \\\";
152 exit \\\$RC" || return ${PIPESTATUS[0]}
157 echo "Filling up directories ... files : f1 ... f$NUM_FILES) ... "
159 do_nodes $NODES_TO_USE "set $TRACE;
160 TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
162 DIR=$TESTDIR/\\\$(hostname);
163 for i in \\\$(seq $NUM_FILES) ; do
164 touch \\\$DIR/f\\\$i;
165 done " || return ${PIPESTATUS[0]}
169 check_dir_contents () {
170 local num_files=${1:-1}
172 echo "Checking dir contents ... (should exist files : f$num_files ... f$NUM_FILES) ... "
173 do_nodes $NODES_TO_USE "set $TRACE;
174 for HOST in ${NODES_TO_USE//,/ } ; do
175 DIR=$TESTDIR/\\\$HOST;
176 for i in \\\$(seq $NUM_FILES -1 $num_files) ; do
177 if ! [ -f \\\$DIR/f\\\$i ] ; then
178 echo \\\"ERROR: file \\\$DIR/f\\\$i should exist\\\";
182 for i in \\\$(seq $(($num_files - 1 ))) ; do
183 if [ -f \\\$DIR/f\\\$i ] ; then
184 echo \\\"ERROR: deleted file \\\$DIR/f\\\$i exists\\\";
189 exit \\\$RC " || return ${PIPESTATUS[0]}
193 do_partial_delete () {
196 echo "Deleting files ... f1 ... f$num_files ... "
197 do_nodes $NODES_TO_USE "set $TRACE;
198 DIR=$TESTDIR/\\\$(hostname);
199 for i in \\\$(seq $num_files) ; do
200 if ! rm -f \\\$DIR/f\\\$i ; then
203 done " || return ${PIPESTATUS[0]}
209 chmod 0777 $MOUNT || exit 1
210 mkdir -p $TESTDIR || exit 1
211 chmod 0777 $TESTDIR || exit 1
213 cleanup_prepare || error_exit "cleanup failed"
215 # create file(s) (mknod (2)), write data, check data, check file attributes
216 echo "Part 1. create file(s) (mknod (2)), write data, check data, check file attributes."
217 do_mknod || error_exit "mknod failed"
218 echo "Writing data to file(s) ... store md5sum ... "
219 do_write || error_exit "write data failed"
220 do_check_data || error_exit "md5sum verification failed"
221 get_stat || { error_noexit "attributes check failed" ; STATUS=1; }
223 # file(s) attributes modification
224 echo "Part 2. file(s) attributes modification."
225 do_chmod || error_exit "chmod failed"
226 get_stat || { error_noexit "wrong attributes after chmod"; STATUS=1; }
228 do_change_timestamps || error_exit "timestamps change failed"
229 do_check_timestamps || { error_noexit "wrong timestamps"; STATUS=1; }
231 # truncate file(s) to 0 size, check new file size
232 echo "Part 3. truncate file(s) to 0 size, check new file size."
233 do_truncate || error_exit"truncate failed"
234 get_stat || { error_noexit "wrong attributes after truncate"; STATUS=1; }
236 # directory content solidity
237 echo "Part 4. directory content solidity: fill up directory, check dir content, remove some files, check dir content."
238 do_fill_dir || error_exit "dir creation failed"
239 check_dir_contents || { error_noexit "dir contents check failed"; STATUS=1; }
241 do_partial_delete $(($NUM_FILES / 2)) || error_exit "delete failed"
242 check_dir_contents $(($NUM_FILES / 2 + 1)) ||
243 { error_noexit "dir contents check after delete failed"; STATUS=1; }
245 # "write_disjoint" test
246 echo "Part 5. write_disjoint test: see lustre/tests/mpi/write_disjoint.c for details"
247 if [ -f "$WRITE_DISJOINT" ]; then
249 MACHINEFILE=${MACHINEFILE:-$TMP/$(basename $0 .sh).machines}
250 generate_machine_file $NODES_TO_USE $MACHINEFILE
251 mpi_run -np $(get_node_count ${NODES_TO_USE//,/ }) -machinefile $MACHINEFILE \
252 $WRITE_DISJOINT -f $WRITE_DISJOINT_FILE -n $NUMLOOPS || STATUS=1
254 skip_env "$0 : write_disjoint not found "
257 equals_msg `basename $0`: test complete, cleaning up
260 check_and_cleanup_lustre