+test_50g() {
+ [ "$OSTCOUNT" -lt "2" ] && skip_env "$OSTCOUNT < 2, skipping" && return
+ setup
+ start_ost2 || error "Unable to start OST2"
+ wait_osc_import_state mds ost2 FULL
+ wait_osc_import_state client ost2 FULL
+
+ local PARAM="${FSNAME}-OST0001.osc.active"
+
+ $LFS setstripe -c -1 $DIR/$tfile || error "Unable to lfs setstripe"
+ do_facet mgs $LCTL conf_param $PARAM=0 || error "Unable to deactivate OST"
+
+ umount_client $MOUNT || error "Unable to unmount client"
+ mount_client $MOUNT || error "Unable to mount client"
+ # This df should not cause a panic
+ df -k $MOUNT
+
+ do_facet mgs $LCTL conf_param $PARAM=1 || error "Unable to activate OST"
+ rm -f $DIR/$tfile
+ umount_client $MOUNT || error "Unable to unmount client"
+ stop_ost2 || error "Unable to stop OST2"
+ stop_ost || error "Unable to stop OST1"
+ stop_mds || error "Unable to stop MDS"
+ #writeconf to remove all ost2 traces for subsequent tests
+ writeconf
+}
+run_test 50g "deactivated OST should not cause panic====================="
+
+test_51() {
+ local LOCAL_TIMEOUT=20
+
+ reformat
+ setup_noconfig
+ check_mount || return 1
+
+ mkdir $MOUNT/d1
+ $LFS setstripe -c -1 $MOUNT/d1
+ #define OBD_FAIL_MDS_REINT_DELAY 0x142
+ do_facet $SINGLEMDS "lctl set_param fail_loc=0x142"
+ touch $MOUNT/d1/f1 &
+ local pid=$!
+ sleep 2
+ start_ost2 || return 2
+ wait $pid
+ stop_ost2 || return 3
+ cleanup
+ #writeconf to remove all ost2 traces for subsequent tests
+ writeconf
+}
+run_test 51 "Verify that mdt_reint handles RMF_MDT_MD correctly when an OST is added"
+
+copy_files_xattrs()
+{
+ local node=$1
+ local dest=$2
+ local xattrs=$3
+ shift 3
+
+ do_node $node mkdir -p $dest
+ [ $? -eq 0 ] || { error "Unable to create directory"; return 1; }
+
+ do_node $node 'tar cf - '$@' | tar xf - -C '$dest';
+ [ \"\${PIPESTATUS[*]}\" = \"0 0\" ] || exit 1'
+ [ $? -eq 0 ] || { error "Unable to tar files"; return 2; }
+
+ do_node $node 'getfattr -d -m "[a-z]*\\." '$@' > '$xattrs
+ [ $? -eq 0 ] || { error "Unable to read xattrs"; return 3; }
+}
+
+diff_files_xattrs()
+{
+ local node=$1
+ local backup=$2
+ local xattrs=$3
+ shift 3
+
+ local backup2=${TMP}/backup2
+
+ do_node $node mkdir -p $backup2
+ [ $? -eq 0 ] || { error "Unable to create directory"; return 1; }
+
+ do_node $node 'tar cf - '$@' | tar xf - -C '$backup2';
+ [ \"\${PIPESTATUS[*]}\" = \"0 0\" ] || exit 1'
+ [ $? -eq 0 ] || { error "Unable to tar files to diff"; return 2; }
+
+ do_node $node "diff -rq $backup $backup2"
+ [ $? -eq 0 ] || { error "contents differ"; return 3; }
+
+ local xattrs2=${TMP}/xattrs2
+ do_node $node 'getfattr -d -m "[a-z]*\\." '$@' > '$xattrs2
+ [ $? -eq 0 ] || { error "Unable to read xattrs to diff"; return 4; }
+
+ do_node $node "diff $xattrs $xattrs2"
+ [ $? -eq 0 ] || { error "xattrs differ"; return 5; }
+
+ do_node $node "rm -rf $backup2 $xattrs2"
+ [ $? -eq 0 ] || { error "Unable to delete temporary files"; return 6; }
+}
+
+test_52() {
+ start_mds
+ [ $? -eq 0 ] || { error "Unable to start MDS"; return 1; }
+ start_ost
+ [ $? -eq 0 ] || { error "Unable to start OST1"; return 2; }
+ mount_client $MOUNT
+ [ $? -eq 0 ] || { error "Unable to mount client"; return 3; }
+
+ local nrfiles=8
+ local ost1mnt=$(facet_mntpt ost1)
+ local ost1node=$(facet_active_host ost1)
+ local ost1tmp=$TMP/conf52
+
+ mkdir -p $DIR/$tdir
+ [ $? -eq 0 ] || { error "Unable to create tdir"; return 4; }
+ touch $TMP/modified_first
+ [ $? -eq 0 ] || { error "Unable to create temporary file"; return 5; }
+ local mtime=$(stat -c %Y $TMP/modified_first)
+ do_node $ost1node "mkdir -p $ost1tmp && touch -m -d @$mtime $ost1tmp/modified_first"
+
+ [ $? -eq 0 ] || { error "Unable to create temporary file"; return 6; }
+ sleep 1
+
+ $LFS setstripe -c -1 -S 1M $DIR/$tdir
+ [ $? -eq 0 ] || { error "lfs setstripe failed"; return 7; }
+
+ for (( i=0; i < nrfiles; i++ )); do
+ multiop $DIR/$tdir/$tfile-$i Ow1048576w1048576w524288c
+ [ $? -eq 0 ] || { error "multiop failed"; return 8; }
+ echo -n .
+ done
+ echo
+
+ # backup files
+ echo backup files to $TMP/files
+ local files=$(find $DIR/$tdir -type f -newer $TMP/modified_first)
+ copy_files_xattrs `hostname` $TMP/files $TMP/file_xattrs $files
+ [ $? -eq 0 ] || { error "Unable to copy files"; return 9; }
+
+ umount_client $MOUNT
+ [ $? -eq 0 ] || { error "Unable to umount client"; return 10; }
+ stop_ost
+ [ $? -eq 0 ] || { error "Unable to stop ost1"; return 11; }
+
+ echo mount ost1 as ldiskfs
+ do_node $ost1node mkdir -p $ost1mnt
+ [ $? -eq 0 ] || { error "Unable to create $ost1mnt"; return 23; }
+ do_node $ost1node mount -t $FSTYPE $ost1_dev $ost1mnt $OST_MOUNT_OPTS
+ [ $? -eq 0 ] || { error "Unable to mount ost1 as ldiskfs"; return 12; }
+
+ # backup objects
+ echo backup objects to $ost1tmp/objects
+ local objects=$(do_node $ost1node 'find '$ost1mnt'/O/0 -type f -size +0'\
+ '-newer '$ost1tmp'/modified_first -regex ".*\/[0-9]+"')
+ copy_files_xattrs $ost1node $ost1tmp/objects $ost1tmp/object_xattrs $objects
+ [ $? -eq 0 ] || { error "Unable to copy objects"; return 13; }
+
+ # move objects to lost+found
+ do_node $ost1node 'mv '$objects' '${ost1mnt}'/lost+found'
+ [ $? -eq 0 ] || { error "Unable to move objects"; return 14; }
+
+ # recover objects
+ do_node $ost1node "ll_recover_lost_found_objs -d $ost1mnt/lost+found"
+ [ $? -eq 0 ] || { error "ll_recover_lost_found_objs failed"; return 15; }
+
+ # compare restored objects against saved ones
+ diff_files_xattrs $ost1node $ost1tmp/objects $ost1tmp/object_xattrs $objects
+ [ $? -eq 0 ] || { error "Unable to diff objects"; return 16; }
+
+ do_node $ost1node "umount $ost1mnt"
+ [ $? -eq 0 ] || { error "Unable to umount ost1 as ldiskfs"; return 17; }
+
+ start_ost
+ [ $? -eq 0 ] || { error "Unable to start ost1"; return 18; }
+ mount_client $MOUNT
+ [ $? -eq 0 ] || { error "Unable to mount client"; return 19; }
+
+ # compare files
+ diff_files_xattrs `hostname` $TMP/files $TMP/file_xattrs $files
+ [ $? -eq 0 ] || { error "Unable to diff files"; return 20; }
+
+ rm -rf $TMP/files $TMP/file_xattrs
+ [ $? -eq 0 ] || { error "Unable to delete temporary files"; return 21; }
+ do_node $ost1node "rm -rf $ost1tmp"
+ [ $? -eq 0 ] || { error "Unable to delete temporary files"; return 22; }
+ cleanup
+}
+run_test 52 "check recovering objects from lost+found"
+
+# Checks threads_min/max/started for some service
+#
+# Arguments: service name (OST or MDT), facet (e.g., ost1, $SINGLEMDS), and a
+# parameter pattern prefix like 'ost.*.ost'.
+thread_sanity() {
+ local modname=$1
+ local facet=$2
+ local parampat=$3
+ local opts=$4
+ local tmin
+ local tmin2
+ local tmax
+ local tmax2
+ local tstarted
+ local paramp
+ local msg="Insane $modname thread counts"
+ shift 4
+
+ setup
+ check_mount || return 41
+
+ # We need to expand $parampat, but it may match multiple parameters, so
+ # we'll pick the first one
+ if ! paramp=$(do_facet $facet "lctl get_param -N ${parampat}.threads_min"|head -1); then
+ error "Couldn't expand ${parampat}.threads_min parameter name"
+ return 22
+ fi
+
+ # Remove the .threads_min part
+ paramp=${paramp%.threads_min}
+
+ # Check for sanity in defaults
+ tmin=$(do_facet $facet "lctl get_param -n ${paramp}.threads_min" || echo 0)
+ tmax=$(do_facet $facet "lctl get_param -n ${paramp}.threads_max" || echo 0)
+ tstarted=$(do_facet $facet "lctl get_param -n ${paramp}.threads_started" || echo 0)
+ lassert 23 "$msg (PDSH problems?)" '(($tstarted && $tmin && $tmax))' || return $?
+ lassert 24 "$msg" '(($tstarted >= $tmin && $tstarted <= $tmax ))' || return $?
+
+ # Check that we can change min/max
+ do_facet $facet "lctl set_param ${paramp}.threads_min=$((tmin + 1))"
+ do_facet $facet "lctl set_param ${paramp}.threads_max=$((tmax - 1))"
+ tmin2=$(do_facet $facet "lctl get_param -n ${paramp}.threads_min" || echo 0)
+ tmax2=$(do_facet $facet "lctl get_param -n ${paramp}.threads_max" || echo 0)
+ lassert 25 "$msg" '(($tmin2 == ($tmin + 1) && $tmax2 == ($tmax -1)))' || return $?
+
+ # Check that we can set min/max to the same value
+ tmin=$(do_facet $facet "lctl get_param -n ${paramp}.threads_min" || echo 0)
+ do_facet $facet "lctl set_param ${paramp}.threads_max=$tmin"
+ tmin2=$(do_facet $facet "lctl get_param -n ${paramp}.threads_min" || echo 0)
+ tmax2=$(do_facet $facet "lctl get_param -n ${paramp}.threads_max" || echo 0)
+ lassert 26 "$msg" '(($tmin2 == $tmin && $tmax2 == $tmin))' || return $?
+
+ # Check that we can't set max < min
+ do_facet $facet "lctl set_param ${paramp}.threads_max=$((tmin - 1))"
+ tmin2=$(do_facet $facet "lctl get_param -n ${paramp}.threads_min" || echo 0)
+ tmax2=$(do_facet $facet "lctl get_param -n ${paramp}.threads_max" || echo 0)
+ lassert 27 "$msg" '(($tmin2 <= $tmax2))' || return $?
+
+ # We need to ensure that we get the module options desired; to do this
+ # we set LOAD_MODULES_REMOTE=true and we call setmodopts below.
+ LOAD_MODULES_REMOTE=true
+ cleanup
+ local oldvalue
+ setmodopts -a $modname "$opts" oldvalue
+
+ load_modules
+ setup
+ check_mount || return 41
+
+ # Restore previous setting of MODOPTS_*
+ setmodopts $modname "$oldvalue"
+
+ # Check that $opts took
+ tmin=$(do_facet $facet "lctl get_param -n ${paramp}.threads_min")
+ tmax=$(do_facet $facet "lctl get_param -n ${paramp}.threads_max")
+ tstarted=$(do_facet $facet "lctl get_param -n ${paramp}.threads_started")
+ lassert 28 "$msg" '(($tstarted == $tmin && $tstarted == $tmax ))' || return $?
+ cleanup
+
+ # Workaround a YALA bug where YALA expects that modules will remain
+ # loaded on the servers
+ LOAD_MODULES_REMOTE=false
+ load_modules
+ setup
+ cleanup
+}
+
+test_53a() {
+ thread_sanity OST ost1 'ost.*.ost' 'oss_num_threads=64'
+}
+run_test 53a "check OSS thread count params"
+
+test_53b() {
+ thread_sanity MDT $SINGLEMDS 'mdt.*.*.' 'mdt_num_threads=64'
+}
+run_test 53b "check MDT thread count params"
+
+test_54a() {
+ do_rpc_nodes $(facet_host ost1) run_llverdev $(ostdevname 1) -p
+ [ $? -eq 0 ] || error "llverdev failed!"
+ reformat_and_config
+}
+run_test 54a "test llverdev and partial verify of device"
+
+test_54b() {
+ setup
+ run_llverfs $MOUNT -p
+ [ $? -eq 0 ] || error "llverfs failed!"
+ cleanup
+}
+run_test 54b "test llverfs and partial verify of filesystem"
+
+lov_objid_size()
+{
+ local max_ost_index=$1
+ echo -n $(((max_ost_index + 1) * 8))
+}
+
+test_55() {
+ local mdsdev=$(mdsdevname 1)
+ local ostdev=$(ostdevname 1)
+ local saved_opts=$OST_MKFS_OPTS
+
+ for i in 1023 2048
+ do
+ OST_MKFS_OPTS="$saved_opts --index $i"
+ reformat
+
+ setup_noconfig
+ stopall
+
+ setup_noconfig
+ sync
+ echo checking size of lov_objid for ost index $i
+ LOV_OBJID_SIZE=$(do_facet mds1 "$DEBUGFS -R 'stat lov_objid' $mdsdev 2>/dev/null" | grep ^User | awk '{print $6}')
+ if [ "$LOV_OBJID_SIZE" != $(lov_objid_size $i) ]; then
+ error "lov_objid size has to be $(lov_objid_size $i), not $LOV_OBJID_SIZE"
+ else
+ echo ok, lov_objid size is correct: $LOV_OBJID_SIZE
+ fi
+ stopall
+ done
+
+ OST_MKFS_OPTS=$saved_opts
+ reformat
+}
+run_test 55 "check lov_objid size"
+
+test_56() {
+ add mds1 $MDS_MKFS_OPTS --mkfsoptions='\"-J size=16\"' --reformat $(mdsdevname 1)
+ add ost1 $OST_MKFS_OPTS --index=1000 --reformat $(ostdevname 1)
+ add ost2 $OST_MKFS_OPTS --index=10000 --reformat $(ostdevname 2)
+
+ start_mgsmds
+ start_ost
+ start_ost2 || error "Unable to start second ost"
+ mount_client $MOUNT || error "Unable to mount client"
+ echo ok
+ $LFS osts
+ [ -n "$ENABLE_QUOTA" ] && { $LFS quotacheck -ug $MOUNT || error "quotacheck has failed" ; }
+ stopall
+ reformat
+}
+run_test 56 "check big indexes"
+
+test_57a() { # bug 22656
+ local NID=$(do_facet ost1 "$LCTL get_param nis" | tail -1 | awk '{print $1}')
+ writeconf
+ do_facet ost1 "$TUNEFS --failnode=$NID `ostdevname 1`" || error "tunefs failed"
+ start_mgsmds
+ start_ost && error "OST registration from failnode should fail"
+ reformat
+}
+run_test 57a "initial registration from failnode should fail (should return errs)"
+
+test_57b() {
+ local NID=$(do_facet ost1 "$LCTL get_param nis" | tail -1 | awk '{print $1}')
+ writeconf
+ do_facet ost1 "$TUNEFS --servicenode=$NID `ostdevname 1`" || error "tunefs failed"
+ start_mgsmds
+ start_ost || error "OST registration from servicenode should not fail"
+ reformat
+}
+run_test 57b "initial registration from servicenode should not fail"
+
+count_osts() {
+ do_facet mgs $LCTL get_param mgs.MGS.live.$FSNAME | grep OST | wc -l
+}
+
+test_58() { # bug 22658
+ [ "$FSTYPE" != "ldiskfs" ] && skip "not supported for $FSTYPE" && return
+ setup_noconfig
+ mkdir -p $DIR/$tdir
+ createmany -o $DIR/$tdir/$tfile-%d 100
+ # make sure that OSTs do not cancel llog cookies before we unmount the MDS
+#define OBD_FAIL_OBD_LOG_CANCEL_NET 0x601
+ do_facet mds "lctl set_param fail_loc=0x601"
+ unlinkmany $DIR/$tdir/$tfile-%d 100
+ stop mds
+ local MNTDIR=$(facet_mntpt mds)
+ # remove all files from the OBJECTS dir
+ do_facet mds "mount -t ldiskfs $MDSDEV $MNTDIR"
+ do_facet mds "find $MNTDIR/OBJECTS -type f -delete"
+ do_facet mds "umount $MNTDIR"
+ # restart MDS with missing llog files
+ start_mds
+ do_facet mds "lctl set_param fail_loc=0"
+ reformat
+}
+run_test 58 "missing llog files must not prevent MDT from mounting"
+
+test_59() {
+ start_mgsmds >> /dev/null
+ local C1=$(count_osts)
+ if [ $C1 -eq 0 ]; then
+ start_ost >> /dev/null
+ C1=$(count_osts)
+ fi
+ stopall
+ echo "original ost count: $C1 (expect > 0)"
+ [ $C1 -gt 0 ] || error "No OSTs in $FSNAME log"
+ start_mgsmds -o writeconf >> /dev/null || error "MDT start failed"
+ local C2=$(count_osts)
+ echo "after mdt writeconf count: $C2 (expect 0)"
+ [ $C2 -gt 0 ] && error "MDT writeconf should erase OST logs"
+ echo "OST start without writeconf should fail:"
+ start_ost >> /dev/null && error "OST start without writeconf didn't fail"
+ echo "OST start with writeconf should succeed:"
+ start_ost -o writeconf >> /dev/null || error "OST1 start failed"
+ local C3=$(count_osts)
+ echo "after ost writeconf count: $C3 (expect 1)"
+ [ $C3 -eq 1 ] || error "new OST writeconf should add:"
+ start_ost2 -o writeconf >> /dev/null || error "OST2 start failed"
+ local C4=$(count_osts)
+ echo "after ost2 writeconf count: $C4 (expect 2)"
+ [ $C4 -eq 2 ] || error "OST2 writeconf should add log"
+ stop_ost2 >> /dev/null
+ cleanup_nocli >> /dev/null
+ #writeconf to remove all ost2 traces for subsequent tests
+ writeconf
+}
+run_test 59 "writeconf mount option"
+
+test_60() { # LU-471
+ add mds1 $MDS_MKFS_OPTS --mkfsoptions='\" -E stride=64 -O ^uninit_bg\"' --reformat $(mdsdevname 1)
+
+ dump=$(do_facet $SINGLEMDS dumpe2fs $(mdsdevname 1))
+ rc=${PIPESTATUS[0]}
+ [ $rc -eq 0 ] || error "dumpe2fs $(mdsdevname 1) failed"
+
+ # MDT default has dirdata feature
+ echo $dump | grep dirdata > /dev/null || error "dirdata is not set"
+ # we disable uninit_bg feature
+ echo $dump | grep uninit_bg > /dev/null && error "uninit_bg is set"
+ # we set stride extended options
+ echo $dump | grep stride > /dev/null || error "stride is not set"
+ reformat
+}
+run_test 60 "check mkfs.lustre --mkfsoptions -E -O options setting"
+
+test_61() { # LU-80
+ local reformat=false
+
+ [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.1.53) ] ||
+ { skip "Need MDS version at least 2.1.53"; return 0; }
+
+ if ! large_xattr_enabled; then
+ reformat=true
+ local mds_dev=$(mdsdevname ${SINGLEMDS//mds/})
+ add $SINGLEMDS $MDS_MKFS_OPTS --mkfsoptions='\"-O large_xattr\"' \
+ --reformat $mds_dev || error "reformatting $mds_dev failed"
+ fi
+
+ setup_noconfig || error "setting up the filesystem failed"
+ client_up || error "starting client failed"
+
+ local file=$DIR/$tfile
+ touch $file
+
+ local large_value="$(generate_string $(max_xattr_size))"
+ local small_value="bar"
+
+ local name="trusted.big"
+ log "save large xattr $name on $file"
+ setfattr -n $name -v $large_value $file ||
+ error "saving $name on $file failed"
+
+ local new_value=$(get_xattr_value $name $file)
+ [[ "$new_value" != "$large_value" ]] &&
+ error "$name different after saving"
+
+ log "shrink value of $name on $file"
+ setfattr -n $name -v $small_value $file ||
+ error "shrinking value of $name on $file failed"
+
+ new_value=$(get_xattr_value $name $file)
+ [[ "$new_value" != "$small_value" ]] &&
+ error "$name different after shrinking"
+
+ log "grow value of $name on $file"
+ setfattr -n $name -v $large_value $file ||
+ error "growing value of $name on $file failed"
+
+ new_value=$(get_xattr_value $name $file)
+ [[ "$new_value" != "$large_value" ]] &&
+ error "$name different after growing"
+
+ log "check value of $name on $file after remounting MDS"
+ fail $SINGLEMDS
+ new_value=$(get_xattr_value $name $file)
+ [[ "$new_value" != "$large_value" ]] &&
+ error "$name different after remounting MDS"
+
+ log "remove large xattr $name from $file"
+ setfattr -x $name $file || error "removing $name from $file failed"
+
+ rm -f $file
+ stopall
+ $reformat && reformat
+}
+run_test 61 "large xattr"
+
+test_62() {
+ # MRP-118
+ local mdsdev=$(mdsdevname 1)
+ local ostdev=$(ostdevname 1)
+
+ echo "disable journal for mds"
+ do_facet mds tune2fs -O ^has_journal $mdsdev || error "tune2fs failed"
+ start_mds && error "MDT start should fail"
+ echo "disable journal for ost"
+ do_facet ost1 tune2fs -O ^has_journal $ostdev || error "tune2fs failed"
+ start_ost && error "OST start should fail"
+ cleanup || return $?
+ reformat_and_config
+}
+run_test 62 "start with disabled journal"
+
+if ! combined_mgs_mds ; then
+ stop mgs
+fi