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 LUSTRE=${LUSTRE:-$(dirname $0)/..}
12 . $LUSTRE/tests/test-framework.sh
16 #Bug number for skipped test:
17 ALWAYS_EXCEPT="$METADATA_UPDATES_EXCEPT "
18 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT LIST
23 TESTDIR=${TESTDIR:-$DIR/d0.$(basename $0 .sh)}
25 NODES_TO_USE=${NODES_TO_USE:-$CLIENTS}
27 [ -z $CLIENTS ] && NODES_TO_USE=$(hostname)
29 # hostname could differ from a network interface
30 # configured for NODES_TO_USE, bug 23961
31 # the test dir on each host is created based on `hostname` of this host
32 HOSTS=$(comma_list $(do_nodes $NODES_TO_USE "echo \\\$(hostname)"))
38 NEW_ATIME="2001-01-01 GMT"
39 NEW_MTIME="2005-05-05 GMT"
42 test_GROUP=$(id -g -n)
44 SUMFILE=$TESTDIR/mdsum
48 log "===== $0 ====== "
50 check_and_setup_lustre
54 do_nodes $NODES_TO_USE "set $TRACE;
55 DIR=$TESTDIR/\\\$(hostname);
56 TESTFILE=\\\$DIR/$FILE;
59 rmdir \\\$DIR 2>/dev/null;
60 mkdir -p \\\$DIR" || return ${PIPESTATUS[0]}
65 log "Creating file(s) by mknod (2) ... "
67 do_nodes $NODES_TO_USE "set $TRACE;
68 TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
69 mcreate \\\$TESTFILE; " || return ${PIPESTATUS[0]}
74 do_nodes $NODES_TO_USE "set $TRACE;
75 TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
76 dd if=/dev/zero of=\\\$TESTFILE bs=$FILE_SIZE count=1 2>/dev/null ||
78 echo \\\$(hostname) | dd of=\\\$TESTFILE conv=notrunc 2>/dev/null ||
80 md5sum \\\$TESTFILE >> $SUMFILE; " || return ${PIPESTATUS[0]}
85 log "Checking file(s) data ... md5sum : "
88 do_nodesv $NODES_TO_USE "md5sum --check $SUMFILE" ||
89 return ${PIPESTATUS[0]}
94 log "Truncating file(s) ... "
96 do_nodes $NODES_TO_USE "set $TRACE;
97 TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
98 $TRUNCATE \\\$TESTFILE 0" || return ${PIPESTATUS[0]}
104 # check st_uid, st_gid, st_size, st_mode
106 local attr="$test_USER $test_GROUP $FILE_SIZE $CURRENT_MODE"
108 log "Checking file(s) attributes ... "
110 do_nodesv $NODES_TO_USE "set $TRACE;
111 for HOST in ${HOSTS//,/ } ; do
112 TESTFILE=$TESTDIR/\\\$HOST/$FILE;
113 tmp=\\\$(stat -c \\\"%U %G %s 0%a\\\" \\\$TESTFILE);
114 echo \\\"\\\$TESTFILE [ uid gid size mode ] expected : $attr ; got : \\\$tmp \\\";
115 if [ x\\\"\\\$tmp\\\" != x\\\"$attr\\\" ] ; then
116 echo \\\"Wrong file attributes\\\";
119 done " || return ${PIPESTATUS[0]}
124 log "Performing chmod 0$NEW_MODE ..."
126 do_nodes $NODES_TO_USE "set $TRACE;
127 TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
128 chmod $NEW_MODE \\\$TESTFILE" || return ${PIPESTATUS[0]}
130 CURRENT_MODE=$NEW_MODE
134 do_change_timestamps () {
135 log "Changing atime, mtime ..."
137 do_nodes $NODES_TO_USE " set $TRACE;
138 TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
139 touch -c --date=\\\"$NEW_ATIME\\\" -a \\\$TESTFILE;
140 touch -c --date=\\\"$NEW_MTIME\\\" -m \\\$TESTFILE " ||
141 return ${PIPESTATUS[0]}
145 # check st_atime, st_mtime
146 do_check_timestamps () {
147 local atime=$(date --date="$NEW_ATIME" +%s)
148 local mtime=$(date --date="$NEW_MTIME" +%s)
150 local times="$atime $mtime"
152 log "Checking atime, mtime ... "
154 do_nodesv $NODES_TO_USE "set $TRACE;
155 for HOST in ${HOSTS//,/ } ; do
156 TESTFILE=$TESTDIR/\\\$HOST/$FILE;
157 tmp=\\\$(stat -c \\\"%X %Y\\\" \\\$TESTFILE);
158 if [ x\\\"\\\$tmp\\\" != x\\\"$times\\\" ] ; then
159 echo \\\"\\\$TESTFILE [ atime mtime ] expected : $times ; got : \\\$tmp \\\";
163 exit \\\$RC" || return ${PIPESTATUS[0]}
168 log "Filling up directories ... files : f1 ... f$NUM_FILES) ... "
170 do_nodes $NODES_TO_USE "set $TRACE;
171 TESTFILE=$TESTDIR/\\\$(hostname)/$FILE;
173 DIR=$TESTDIR/\\\$(hostname);
174 for i in \\\$(seq $NUM_FILES) ; do
175 touch \\\$DIR/f\\\$i;
176 done " || return ${PIPESTATUS[0]}
180 check_dir_contents () {
181 local num_files=${1:-1}
183 log "Directory contents should exist: f$num_files ... f$NUM_FILES)"
184 do_nodes $NODES_TO_USE "set $TRACE;
185 for HOST in ${HOSTS//,/ } ; do
186 DIR=$TESTDIR/\\\$HOST;
187 for i in \\\$(seq $NUM_FILES -1 $num_files) ; do
188 if ! [ -f \\\$DIR/f\\\$i ] ; then
189 echo \\\"ERROR: file \\\$DIR/f\\\$i should exist\\\";
193 for i in \\\$(seq $(($num_files - 1 ))) ; do
194 if [ -f \\\$DIR/f\\\$i ] ; then
195 echo \\\"ERROR: deleted file \\\$DIR/f\\\$i exists\\\";
200 exit \\\$RC " || return ${PIPESTATUS[0]}
204 do_partial_delete () {
207 log "Deleting files ... f1 ... f$num_files ... "
208 do_nodes $NODES_TO_USE "set $TRACE;
209 DIR=$TESTDIR/\\\$(hostname);
210 for i in \\\$(seq $num_files) ; do
211 if ! rm -f \\\$DIR/f\\\$i ; then
214 done " || return ${PIPESTATUS[0]}
218 chmod 0777 $MOUNT || exit 1
219 mkdir -p $TESTDIR || exit 1
220 chmod 0777 $TESTDIR || exit 1
222 cleanup_prepare || error_exit "cleanup failed"
225 log "Create files (mknod (2)) and write data"
226 do_mknod || error "mknod failed"
227 do_write || error "write data failed"
228 log "Check data and file attributes."
229 do_check_data || error "md5sum verification failed"
230 get_stat || error "attributes check failed"
232 # file attributes modification
233 log "File attributes modification."
234 do_chmod || error "chmod failed"
235 get_stat || error "wrong attributes after chmod"
237 do_change_timestamps || error "timestamps change failed"
238 do_check_timestamps || error "wrong timestamps"
240 # truncate file(s) to 0 size, check new file size
241 log "Truncate file(s) to 0 size, check new file size."
242 do_truncate || error "truncate failed"
243 get_stat || error "wrong attributes after truncate"
245 run_test 1 "create files (mknod), write and check data, truncate files"
248 do_fill_dir || error "dir creation failed"
249 check_dir_contents || error "dir contents check failed"
251 do_partial_delete $(($NUM_FILES / 2)) || error "delete failed"
252 check_dir_contents $(($NUM_FILES / 2 + 1)) ||
253 error "dir contents check after delete failed"
255 run_test 2 "directory content create, check, delete files , check"
258 WRITE_DISJOINT=${WRITE_DISJOINT:-$(which write_disjoint 2> /dev/null)} || true
259 disjoint_file=$TESTDIR/$tfile
262 [ ! -f "$WRITE_DISJOINT" ] && skip_env "write_disjoint not found"
265 generate_machine_file $NODES_TO_USE $MACHINEFILE
266 mpi_run ${MACHINEFILE_OPTION} ${MACHINEFILE} \
267 -np $(get_node_count ${NODES_TO_USE//,/ }) \
268 $WRITE_DISJOINT -f $disjoint_file -n $numloops ||
269 error "mpi_run failed"
273 run_test 3 "write_disjoint test"
277 check_and_cleanup_lustre