From: grev Date: Fri, 31 Jul 2009 16:16:46 +0000 (+0000) Subject: b=19418 X-Git-Tag: v1_9_230~3 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=044a13ae4b617344a266c5f25f494994465363da;ds=sidebyside b=19418 i=Brian cmd3-38 port to acc-sm: new metadata updates test --- diff --git a/lustre/tests/acceptance-small.sh b/lustre/tests/acceptance-small.sh index 320eeeb..6401abc 100755 --- a/lustre/tests/acceptance-small.sh +++ b/lustre/tests/acceptance-small.sh @@ -23,7 +23,7 @@ fi [ "$DEBUG_OFF" ] || DEBUG_OFF="eval lctl set_param debug=\"$DEBUG_LVL\"" [ "$DEBUG_ON" ] || DEBUG_ON="eval lctl set_param debug=0x33f0484" -export TESTSUITE_LIST="RUNTESTS SANITY DBENCH BONNIE IOZONE FSX SANITYN LFSCK LIBLUSTRE RACER REPLAY_SINGLE CONF_SANITY RECOVERY_SMALL REPLAY_OST_SINGLE REPLAY_DUAL REPLAY_VBR INSANITY SANITY_QUOTA SANITY_SEC SANITY_GSS PERFORMANCE_SANITY LARGE_SCALE RECOVERY_MDS_SCALE RECOVERY_DOUBLE_SCALE RECOVERY_RANDOM_SCALE PARALLEL_SCALE LREPLICATE_TEST" +export TESTSUITE_LIST="RUNTESTS SANITY DBENCH BONNIE IOZONE FSX SANITYN LFSCK LIBLUSTRE RACER REPLAY_SINGLE CONF_SANITY RECOVERY_SMALL REPLAY_OST_SINGLE REPLAY_DUAL REPLAY_VBR INSANITY SANITY_QUOTA SANITY_SEC SANITY_GSS PERFORMANCE_SANITY LARGE_SCALE RECOVERY_MDS_SCALE RECOVERY_DOUBLE_SCALE RECOVERY_RANDOM_SCALE PARALLEL_SCALE LREPLICATE_TEST METADATA_UPDATES" if [ "$ACC_SM_ONLY" ]; then for O in $TESTSUITE_LIST; do @@ -493,6 +493,12 @@ if [ "$PARALLEL_SCALE" != "no" ]; then PARALLEL_SCALE="done" fi +if [ "$METADATA_UPDATES" != "no" ]; then + title metadata-updates + bash metadata-updates.sh + METADATA_UPDATES="done" +fi + RC=$? title FINISHED echo "Finished at `date` in $((`date +%s` - $STARTTIME))s" diff --git a/lustre/tests/metadata-updates.sh b/lustre/tests/metadata-updates.sh new file mode 100755 index 0000000..68f8077 --- /dev/null +++ b/lustre/tests/metadata-updates.sh @@ -0,0 +1,294 @@ +#!/bin/bash + +# A Metadata Update Test tests that +# metadata updates are properly completed when +# multiple clients create/delete files and modify the attributes of files. + +set -e + +LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)} +. $LUSTRE/tests/test-framework.sh +init_test_env $@ +. ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh} + +TRACE="+x" + +TESTDIR=${TESTDIR:-$DIR/d0.$(basename $0 .sh)} + +NODES_TO_USE=${NODES_TO_USE:-$CLIENTS} + +[ -z $CLIENTS ] && NODES_TO_USE=$(hostname) + +FILE=testfile +FILE_SIZE=1024 +CURRENT_MODE=0644 +NEW_MODE=0222 +NEW_ATIME="2001-01-01 GMT" +NEW_MTIME="2005-05-05 GMT" + +test_UID=$(id -u) +test_GID=$(id -g) + +NUM_FILES=1000 + +WRITE_DISJOINT=${WRITE_DISJOINT:-$(which write_disjoint 2> /dev/null)} || true +WRITE_DISJOINT_FILE=$TESTDIR/f0.write_disjoint_file +NUMLOOPS=1000 + +SUM=$(pwd)/sum + +log "===== $0 ====== " + +check_and_setup_lustre + +cleanup_prepare () { + + do_nodes $NODES_TO_USE "set $TRACE; +DIR=$TESTDIR/\\\$(hostname); +TESTFILE=\\\$DIR/$FILE; +rm -f \\\$TESTFILE; +rmdir \\\$DIR 2>/dev/null; +mkdir -p \\\$DIR" || return ${PIPESTATUS[0]} + + return 0 +} + +do_mknod () { + echo "Creating file(s) by mknod (2) ... " + + do_nodes $NODES_TO_USE "set $TRACE +TESTFILE=$TESTDIR/\\\$(hostname)/$FILE +mcreate \\\$TESTFILE" || return ${PIPESTATUS[0]} + + return 0 +} + +do_write () { + echo "Writing data to file(s) ... store md5sum ... " + + do_nodes $NODES_TO_USE "set $TRACE; +TESTFILE=$TESTDIR/\\\$(hostname)/$FILE; +sum=${SUM}_\\\$(hostname); +dd if=/dev/zero of=\\\$TESTFILE bs=$FILE_SIZE count=1 2>/dev/null; +md5sum \\\$TESTFILE > \\\$sum " + if [ ${PIPESTATUS[0]} -ne 0 ] ; then + echo "ERROR: on file creation" + return 1 + fi + + return 0 +} + +do_check_data () { + local HOST + echo "Checking file(s) data ... " + + for HOST in ${NODES_TO_USE//,/ } ; do + local sum=${SUM}_$HOST + do_nodes $NODES_TO_USE "md5sum --check $sum" + if [ ${PIPESTATUS[0]} -ne 0 ] ; then + echo "ERROR: wrong data." + [ -f $sum ] && { cat $sum ; rm -f $sum; } + return 1 + fi + [ -f $sum ] && { cat $sum; rm -f $sum; } + done + + return 0 +} + +do_truncate () { + echo "Truncating file(s) ... " + + do_nodes $NODES_TO_USE "set $TRACE; +TESTFILE=$TESTDIR/\\\$(hostname)/$FILE; +truncate \\\$TESTFILE 0" || return ${PIPESTATUS[0]} + + FILE_SIZE=0 + + return 0 +} + +# check st_uid, st_gid, st_size, st_mode +get_stat () { + local attr="$test_UID $test_GID $FILE_SIZE $CURRENT_MODE" + + echo "Checking file(s) attributes ... " + + do_nodes $NODES_TO_USE "set $TRACE; +for HOST in ${NODES_TO_USE//,/ } ; do + TESTFILE=$TESTDIR/\\\$HOST/$FILE; + tmp=\\\$(stat -c \\\"%u %g %s 0%a\\\" \\\$TESTFILE); + echo \\\"\\\$TESTFILE [ uid gid size mode ] expected : $attr ; got : \\\$tmp \\\"; + if [ x\\\"\\\$tmp\\\" != x\\\"$attr\\\" ] ; then + echo \\\"Wrong file attributes\\\"; + exit 56; + fi; +done " + if [ ${PIPESTATUS[0]} -ne 0 ] ; then + return 1 + fi + + return 0 +} + +do_chmod () { + echo "Performing chmod 0$NEW_MODE ..." + + do_nodes $NODES_TO_USE "set $TRACE; +TESTFILE=$TESTDIR/\\\$(hostname)/$FILE; +chmod $NEW_MODE \\\$TESTFILE" || return ${PIPESTATUS[0]} + + CURRENT_MODE=$NEW_MODE + + return 0 +} + +do_change_timestamps () { + echo "Changing atime, mtime ..." + + do_nodes $NODES_TO_USE " set $TRACE; +TESTFILE=$TESTDIR/\\\$(hostname)/$FILE; +touch -c --date=\\\"$NEW_ATIME\\\" -a \\\$TESTFILE; +touch -c --date=\\\"$NEW_MTIME\\\" -m \\\$TESTFILE " || return ${PIPESTATUS[0]} + + return 0 +} + +# check st_atime, st_mtime +do_check_timestamps () { + local atime=$(date --date="$NEW_ATIME" +%s) + local mtime=$(date --date="$NEW_MTIME" +%s) + + local times="$atime $mtime" + + echo "Checking atime, mtime ... " + + do_nodes $NODES_TO_USE "set $TRACE; +for HOST in ${NODES_TO_USE//,/ } ; do + TESTFILE=$TESTDIR/\\\$HOST/$FILE; + tmp=\\\$(stat -c \\\"%X %Y\\\" \\\$TESTFILE); + if [ x\\\"\\\$tmp\\\" != x\\\"$times\\\" ] ; then + echo \\\"\\\$TESTFILE [ atime mtime ] expected : $times ; got : \\\$tmp \\\"; + RC=57; + fi; +done; +exit \\\$RC" + if [ ${PIPESTATUS[0]} -ne 0 ] ; then + echo "WARNING : Wrong atime and(or) mtime values. Hope this is expected." + return 0 + fi + + return 0 +} + +do_fill_dir () { + echo "Filling up directories ... files : f1 ... f$NUM_FILES) ... " + + do_nodes $NODES_TO_USE "set $TRACE; +TESTFILE=$TESTDIR/\\\$(hostname)/$FILE; +rm -f \\\$TESTFILE; +DIR=$TESTDIR/\\\$(hostname); +for i in \\\$(seq $NUM_FILES) ; do + touch \\\$DIR/f\\\$i; +done " || return ${PIPESTATUS[0]} + + return 0 +} + +check_dir_contents () { + local num_files=${1:-1} + + echo "Checking dir contents ... (should exist files : f$num_files ... f$NUM_FILES) ... " + do_nodes $NODES_TO_USE "set $TRACE; +for HOST in ${NODES_TO_USE//,/ } ; do + DIR=$TESTDIR/\\\$HOST; + for i in \\\$(seq $NUM_FILES -1 $num_files) ; do + if ! [ -f \\\$DIR/f\\\$i ] ; then + echo \\\"ERROR: file \\\$DIR/f\\\$i should exist\\\"; + RC=1; + fi; + done; + for i in \\\$(seq $(($num_files - 1 ))) ; do + if [ -f \\\$DIR/f\\\$i ] ; then + echo \\\"ERROR: deleted file \\\$DIR/f\\\$i exists\\\"; + RC=1; + fi; + done; +done; +exit \\\$RC " + if [ ${PIPESTATUS[0]} -ne 0 ] ; then + return 1 + fi + + return 0 +} + +do_partial_delete () { + local num_files=$1 + + echo "Deleting files ... f1 ... f$num_files ... " + do_nodes $NODES_TO_USE "set $TRACE; +DIR=$TESTDIR/\\\$(hostname); +for i in \\\$(seq $num_files) ; do + if ! rm -f \\\$DIR/f\\\$i ; then + exit 1; + fi; +done " || return ${PIPESTATUS[0]} + + return 0 +} + +STATUS=0 + +chmod 0777 $MOUNT || exit 1 +mkdir -p $TESTDIR || exit 1 +chmod 0777 $TESTDIR || exit 1 + +cleanup_prepare || exit 1 + +# create file(s) (mknod (2)), write data, check data, check file attributes +echo "Part 1. create file(s) (mknod (2)), write data, check data, check file attributes." +do_mknod || exit ${PIPESTATUS[0]} +do_write || exit ${PIPESTATUS[0]} +do_check_data || exit ${PIPESTATUS[0]} +get_stat || STATUS=1 + +# file(s) attributes modification +echo "Part 2. file(s) attributes modification." +do_chmod || exit ${PIPESTATUS[0]} +get_stat || STATUS=1 + +do_change_timestamps || exit ${PIPESTATUS[0]} +do_check_timestamps || STATUS=1 + +# truncate file(s) to 0 size, check new file size +echo "Part 3. truncate file(s) to 0 size, check new file size." +do_truncate || exit ${PIPESTATUS[0]} +get_stat || STATUS=1 + +# directory content solidity +echo "Part 4. directory content solidity: fill up directory, check dir content, remove some files, check dir content." +do_fill_dir || exit ${PIPESTATUS[0]} +check_dir_contents || STATUS=1 + +do_partial_delete $(($NUM_FILES / 2)) || exit ${PIPESTATUS[0]} +check_dir_contents $(($NUM_FILES / 2 + 1)) || STATUS=1 + +# "write_disjoint" test +echo "Part 5. write_disjoint test: see lustre/tests/write_disjoint.c for details" +if [ -f "$WRITE_DISJOINT" ]; then + set $TRACE + MACHINEFILE=${MACHINEFILE:-$TMP/$(basename $0 .sh).machines} + generate_machine_file $NODES_TO_USE $MACHINEFILE + mpi_run -np $(get_node_count ${NODES_TO_USE//,/ }) $MACHINEFILE \ + $WRITE_DISJOINT -f $WRITE_DISJOINT_FILE -n $NUMLOOPS || STATUS=1 +else + skip "$0 : write_disjoint not found " +fi + +equals_msg `basename $0`: test complete, cleaning up +rm -rf $TESTDIR +rm -f $MACHINEFILE +check_and_cleanup_lustre +exit $STATUS