TMP=${TMP:-/tmp}
+CC=${CC:-cc}
CHECKSTAT=${CHECKSTAT:-"checkstat -v"}
CREATETEST=${CREATETEST:-createtest}
LFS=${LFS:-lfs}
SETUP=${SETUP:-:}
TRACE=${TRACE:-""}
LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
+LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
. $LUSTRE/tests/test-framework.sh
init_test_env $@
. ${CONFIG:=$LUSTRE/tests/cfg/${NAME}.sh}
local MDTIDX=1
local remote_dir=remote_dir
- [ $MDSCOUNT -ge 2 ] && skip "skip now for LU-4690" && return #LU-4690
test_mkdir $DIR/$remote_dir ||
error "Create remote directory failed"
error "Expect error removing in-use dir $DIR/$remote_dir"
test -d $DIR/$remote_dir || error "Remote directory disappeared"
+
+ rm -rf $DIR/$remote_dir || error "remove remote dir error"
}
run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
test_17i() { #bug 20018
remote_mds_nodsh && skip "remote MDS with nodsh" && return
[ $PARALLEL == "yes" ] && skip "skip parallel run" && return
- test_mkdir -p $DIR/$tdir
+ test_mkdir -c1 $DIR/$tdir
local foo=$DIR/$tdir/$tfile
local mdt_idx
if [[ $MDSCOUNT -gt 1 ]]; then
[ $PARALLEL == "yes" ] && skip "skip parallel run" && return
- mkdir -p $DIR/$tdir
+ mkdir $DIR/$tdir
for ((i=0; i<10; i++)); do
- $LFS mkdir -i 1 $DIR/$tdir/remote_dir_${i} ||
+ $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
error "create remote dir error $i"
createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
error "create files under remote dir failed $i"
rm -rf $DIR/$tdir
mkdir -p $DIR/$tdir
createmany -m $DIR/$tdir/$tfile $NFILES
- local t=`ls $DIR/$tdir | wc -l`
- local u=`ls $DIR/$tdir | sort -u | wc -l`
- if [ $t -ne $NFILES -o $u -ne $NFILES ] ; then
- error "Expected $NFILES files, got $t ($u unique)"
+ local t=$(ls $DIR/$tdir | wc -l)
+ local u=$(ls $DIR/$tdir | sort -u | wc -l)
+ local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
+ if [ $t -ne $NFILES -o $u -ne $NFILES -o $v -ne $((NFILES + 2)) ] ; then
+ error "Expected $NFILES files, got $t ($u unique $v .&..)"
fi
rm -rf $DIR/$tdir || error "Can not delete directories"
}
run_test 24A "readdir() returns correct number of entries."
+test_24B() { # LU-4805
+ [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
+ local count
+
+ mkdir $DIR/$tdir
+ $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
+ error "create striped dir failed"
+
+ count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
+ [ $count -eq 2 ] || error "Expected 2, got $count"
+
+ touch $DIR/$tdir/striped_dir/a
+
+ count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
+ [ $count -eq 3 ] || error "Expected 3, got $count"
+
+ touch $DIR/$tdir/striped_dir/.f
+
+ count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
+ [ $count -eq 4 ] || error "Expected 4, got $count"
+
+ rm -rf $DIR/$tdir || error "Can not delete directories"
+}
+run_test 24B "readdir for striped dir return correct number of entries"
+
+test_24C() {
+ [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
+
+ mkdir $DIR/$tdir
+ mkdir $DIR/$tdir/d0
+ mkdir $DIR/$tdir/d1
+
+ $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
+ error "create striped dir failed"
+
+ cd $DIR/$tdir/d0/striped_dir
+
+ local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
+ local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
+ local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
+
+ [ "$d0_ino" = "$parent_ino" ] ||
+ error ".. wrong, expect $d0_ino, get $parent_ino"
+
+ mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
+ error "mv striped dir failed"
+
+ parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
+
+ [ "$d1_ino" = "$parent_ino" ] ||
+ error ".. wrong after mv, expect $d1_ino, get $parent_ino"
+}
+run_test 24C "check .. in striped dir"
+
test_25a() {
echo '== symlink sanity ============================================='
}
run_test 31o "duplicate hard links with same filename"
+test_31p() {
+ [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
+
+ mkdir $DIR/$tdir
+ $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
+ $LFS setdirstripe -D -c2 -t all_char $DIR/$tdir/striped_dir
+
+ opendirunlink $DIR/$tdir/striped_dir/test1 ||
+ error "open unlink test1 failed"
+ opendirunlink $DIR/$tdir/striped_dir/test2 ||
+ error "open unlink test2 failed"
+
+ $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
+ error "test1 still exists"
+ $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
+ error "test2 still exists"
+}
+run_test 31p "remove of open striped directory"
+
cleanup_test32_mount() {
trap 0
$UMOUNT -d $DIR/$tdir/ext2-mountpoint
}
run_test 36h "utime on file racing with OST BRW write =========="
+test_36i() {
+ [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
+
+ mkdir $DIR/$tdir
+ $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
+
+ local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
+ local new_mtime=$((mtime + 200))
+
+ #change Modify time of striped dir
+ touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
+ error "change mtime failed"
+
+ local got=$(stat -c%Y $DIR/$tdir/striped_dir)
+
+ [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
+}
+run_test 36i "change mtime on striped directory"
+
# test_37 - duplicate with tests 32q 32r
test_38() {
test_51a() { # was test_51
# bug 1516 - create an empty entry right after ".." then split dir
- test_mkdir -p $DIR/$tdir
+ test_mkdir -c1 $DIR/$tdir
touch $DIR/$tdir/foo
$MCREATE $DIR/$tdir/bar
rm $DIR/$tdir/foo
# cleanup the directory
rm -fr $BASE
- test_mkdir -p $BASE
+ test_mkdir -p -c1 $BASE
local mdtidx=$(printf "%04x" $($LFS getstripe -M $BASE))
local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
EXPECTED=$(((NUMDIRS + 1) * NUMFILES))
CMD="$LFIND -stripe-count $OSTCOUNT -type f $TDIR"
NUMS=$($CMD | wc -l)
- [ $NUMS -eq $EXPECTED ] ||
+ [ $NUMS -eq $EXPECTED ] || {
+ $GETSTRIPE -R $TDIR
error "\"$CMD\" wrong: found $NUMS, expected $EXPECTED"
+ }
EXPECTED=$(((NUMDIRS + 1) * NUMFILES + EXTRA))
CMD="$LFIND -stripe-count +0 -type f $TDIR"
NUMS=$($CMD | wc -l)
- [ $NUMS -eq $EXPECTED ] ||
+ [ $NUMS -eq $EXPECTED ] || {
+ $GETSTRIPE -R $TDIR
error "\"$CMD\" wrong: found $NUMS, expected $EXPECTED"
+ }
EXPECTED=$ONESTRIPE
CMD="$LFIND -stripe-count 1 -type f $TDIR"
NUMS=$($CMD | wc -l)
- [ $NUMS -eq $EXPECTED ] ||
+ [ $NUMS -eq $EXPECTED ] || {
+ $GETSTRIPE -R $TDIR
error "\"$CMD\" wrong: found $NUMS, expected $EXPECTED"
+ }
CMD="$LFIND -stripe-count -2 -type f $TDIR"
NUMS=$($CMD | wc -l)
- [ $NUMS -eq $EXPECTED ] ||
+ [ $NUMS -eq $EXPECTED ] || {
+ $GETSTRIPE -R $TDIR
error "\"$CMD\" wrong: found $NUMS, expected $EXPECTED"
+ }
EXPECTED=0
CMD="$LFIND -stripe-count $((OSTCOUNT + 1)) -type f $TDIR"
NUMS=$($CMD | wc -l)
- [ $NUMS -eq $EXPECTED ] ||
+ [ $NUMS -eq $EXPECTED ] || {
+ $GETSTRIPE -R $TDIR
error "\"$CMD\" wrong: found $NUMS, expected $EXPECTED"
+ }
}
run_test 56s "check lfs find -stripe-count works"
run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
fi
+ run_acl_subtest 4924 || error "LU-4924 test failed"
+
cd $SAVE_PWD
umask $SAVE_UMASK
test_105a() {
# doesn't work on 2.4 kernels
touch $DIR/$tfile
- if [ -n "$(mount | grep "$MOUNT.*flock" | grep -v noflock)" ]; then
+ if $(flock_is_enabled); then
flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
else
flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
test_105b() {
touch $DIR/$tfile
- if [ -n "$(mount | grep "$MOUNT.*flock" | grep -v noflock)" ]; then
+ if $(flock_is_enabled); then
flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
else
flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
test_105c() {
touch $DIR/$tfile
- if [ -n "$(mount | grep "$MOUNT.*flock" | grep -v noflock)" ]; then
+ if $(flock_is_enabled); then
flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
else
flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
test_105d() { # bug 15924
[ $PARALLEL == "yes" ] && skip "skip parallel run" && return
test_mkdir -p $DIR/$tdir
- [ -z "$(mount | grep "$MOUNT.*flock" | grep -v noflock)" ] &&
- skip "mount w/o flock enabled" && return
+ flock_is_enabled || { skip "mount w/o flock enabled" && return; }
#define OBD_FAIL_LDLM_CP_CB_WAIT 0x315
$LCTL set_param fail_loc=0x80000315
flocks_test 2 $DIR/$tdir
run_test 105d "flock race (should not freeze) ========"
test_105e() { # bug 22660 && 22040
- [ -z "$(mount | grep "$MOUNT.*flock" | grep -v noflock)" ] &&
- skip "mount w/o flock enabled" && return
+ flock_is_enabled || { skip "mount w/o flock enabled" && return; }
touch $DIR/$tfile
flocks_test 3 $DIR/$tfile
}
cancel_lru_locks osc
dd if=$DIR/$tdir/f1 of=/dev/null
stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
+ # XXX client can not do early lock cancel of OST lock
+ # during unlink (LU-4206), so cancel osc lock now.
+ cancel_lru_locks osc
can1=$(do_facet $SINGLEMDS \
"$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
awk '/ldlm_cancel/ {print $2}')
blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
awk '/ldlm_bl_callback/ {print $2}')
unlink $DIR/$tdir/f1
+ sleep 5
can2=$(do_facet $SINGLEMDS \
"$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
awk '/ldlm_cancel/ {print $2}')
lru_resize_disable osc
test_mkdir -p -c1 $DIR/$tdir/d1
test_mkdir -p -c1 $DIR/$tdir/d2
- dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
- dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
- cancel_lru_locks mdc
- cancel_lru_locks osc
- dd if=$DIR/$tdir/d1/f1 of=/dev/null
- dd if=$DIR/$tdir/d2/f2 of=/dev/null
- stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
+ dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
+ dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
+ cancel_lru_locks mdc
+ cancel_lru_locks osc
+ dd if=$DIR/$tdir/d1/f1 of=/dev/null
+ dd if=$DIR/$tdir/d2/f2 of=/dev/null
+ stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
+ # XXX client can not do early lock cancel of OST lock
+ # during rename (LU-4206), so cancel osc lock now.
+ cancel_lru_locks osc
can1=$(do_facet $SINGLEMDS \
"$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
awk '/ldlm_cancel/ {print $2}')
blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
awk '/ldlm_bl_callback/ {print $2}')
- mv $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
+ mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
+ sleep 5
can2=$(do_facet $SINGLEMDS \
"$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
awk '/ldlm_cancel/ {print $2}')
-type f \
-not -name force_lbug \
-not -name changelog_mask \
- -exec badarea_io '{}' \; > /dev/null
+ -exec badarea_io '{}' \; &> /dev/null ||
+ error "find $proc_dirs failed"
[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.5.54) ] &&
skip "Too old lustre on MDS"
-type f \
-not -name force_lbug \
-not -name changelog_mask \
- -exec badarea_io '{}' \\\; &> /dev/null
+ -exec badarea_io '{}' \\\; &> /dev/null ||
+ error "$facet find $proc_dirs failed"
done
+ # remount the FS in case writes/reads /proc break the FS
+ cleanup || error "failed to unmount"
+ setup || error "failed to setup"
true
}
run_test 133g "Check for Oopses on bad io area writes/reads in /proc"
}
run_test 162 "path lookup sanity"
+test_162b() {
+ [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
+ [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
+
+ mkdir $DIR/$tdir
+ $LFS setdirstripe -i0 -c$MDSCOUNT -t all_char $DIR/$tdir/striped_dir ||
+ error "create striped dir failed"
+
+ local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
+ tail -n 1 | awk '{print $2}')
+ stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
+
+ touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
+ mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
+
+ # regular file
+ for ((i=0;i<5;i++)); do
+ FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
+ error "get fid for f$i failed"
+ check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
+
+ FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
+ error "get fid for d$i failed"
+ check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
+ done
+
+ return 0
+}
+run_test 162b "striped directory path lookup sanity"
+
test_169() {
# do directio so as not to populate the page cache
log "creating a 10 Mb file"
cp /etc/passwd $migrate_dir/$tfile
cp /etc/passwd $other_dir/$tfile
+ chattr +SAD $migrate_dir
+ chattr +SAD $migrate_dir/$tfile
+
+ local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
+ local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
+ local old_dir_mode=$(stat -c%f $migrate_dir)
+ local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
+
mkdir -p $migrate_dir/dir_default_stripe2
$SETSTRIPE -c 2 $migrate_dir/dir_default_stripe2
$SETSTRIPE -c 2 $migrate_dir/${tfile}_stripe2
[ $mdt_index == 0 ] ||
error "$file is not on MDT${MDTIDX}"
+ local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
+ [ "$old_dir_flag" = "$new_dir_flag" ] ||
+ error " expect $old_dir_flag get $new_dir_flag"
+
+ local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
+ [ "$old_file_flag" = "$new_file_flag" ] ||
+ error " expect $old_file_flag get $new_file_flag"
+
+ local new_dir_mode=$(stat -c%f $migrate_dir)
+ [ "$old_dir_mode" = "$new_dir_mode" ] ||
+ error "expect mode $old_dir_mode get $new_dir_mode"
+
+ local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
+ [ "$old_file_mode" = "$new_file_mode" ] ||
+ error "expect mode $old_file_mode get $new_file_mode"
+
diff /etc/passwd $migrate_dir/$tfile ||
error "$tfile different after migration"
error "$file is not on MDT${MDTIDX}"
done
+ local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
+ [ "$old_dir_flag" = "$new_dir_flag" ] ||
+ error " expect $old_dir_flag get $new_dir_flag"
+
+ local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
+ [ "$old_file_flag" = "$new_file_flag" ] ||
+ error " expect $old_file_flag get $new_file_flag"
+
+ local new_dir_mode=$(stat -c%f $migrate_dir)
+ [ "$old_dir_mode" = "$new_dir_mode" ] ||
+ error "expect mode $old_dir_mode get $new_dir_mode"
+
+ local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
+ [ "$old_file_mode" = "$new_file_mode" ] ||
+ error "expect mode $old_file_mode get $new_file_mode"
+
diff /etc/passwd ${migrate_dir}/$tfile ||
error "$tfile different after migration"
}
run_test 300f "check rename cross striped directory"
+test_300g() {
+ [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
+ local stripe_count
+ local dir
+
+ mkdir $DIR/$tdir
+ $LFS setdirstripe -i 0 -c $MDSCOUNT -t all_char \
+ $DIR/$tdir/striped_dir ||
+ error "set striped dir error"
+
+ $LFS setdirstripe -D -c $MDSCOUNT -t all_char $DIR/$tdir/striped_dir ||
+ error "set default stripe on striped dir error"
+
+ stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/striped_dir)
+ [ $stripe_count -eq $MDSCOUNT ] ||
+ error "default stripe wrong expect $MDSCOUNT get $stripe_count"
+
+ mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
+
+ for dir in $(find $DIR/$tdir/striped_dir/*); do
+ stripe_count=$($LFS getdirstripe -c $dir)
+ [ $stripe_count -eq $MDSCOUNT ] ||
+ error "expect $MDSCOUNT get $stripe_count for $dir"
+ done
+
+ rmdir $DIR/$tdir/striped_dir/* || error "rmdir1 failed"
+ #change default stripe count to 2
+ $LFS setdirstripe -D -c 2 -t all_char $DIR/$tdir/striped_dir ||
+ error "set default stripe on striped dir error"
+
+ mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
+
+ rmdir $DIR/$tdir/striped_dir/* || error "rmdir2 failed"
+
+ #change default stripe count to 1
+ $LFS setdirstripe -D -c 1 -t all_char $DIR/$tdir/striped_dir ||
+ error "set default stripe on striped dir error"
+
+ mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
+ for dir in $(find $DIR/$tdir/striped_dir/*); do
+ stripe_count=$($LFS getdirstripe -c $dir)
+ [ $stripe_count -eq 1 ] ||
+ error "expect 1 get $stripe_count for $dir"
+ done
+ rmdir $DIR/$tdir/striped_dir/* || error "rmdir3 failed"
+}
+run_test 300g "check default striped directory for striped directory"
+
+test_400a() { # LU-1606, was conf-sanity test_74
+ local extra_flags=''
+ local out=$TMP/$tfile
+ local prefix=/usr/include/lustre
+ local prog
+
+ if ! which $CC > /dev/null 2>&1; then
+ skip_env "$CC is not installed"
+ return 0
+ fi
+
+ if ! [[ -d $prefix ]]; then
+ # Assume we're running in tree and fixup the include path.
+ extra_flags+=" -I$LUSTRE/../libcfs/include"
+ extra_flags+=" -I$LUSTRE/include"
+ extra_flags+=" -L$LUSTRE/utils"
+ fi
+
+ for prog in $LUSTRE_TESTS_API_DIR/*.c; do
+ $CC -Wall -Werror $extra_flags -llustreapi -o $out $prog ||
+ error "client api broken"
+ done
+}
+run_test 400a "Lustre client api program can compile and link"
+
+test_400b() { # LU-1606, LU-5011
+ local header
+ local out=$TMP/$tfile
+ local prefix=/usr/include/lustre
+
+ # We use a hard coded prefix so that this test will not fail
+ # when run in tree. There are headers in lustre/include/lustre/
+ # that are not packaged (like lustre_idl.h) and have more
+ # complicated include dependencies (like config.h and lnet/types.h).
+ # Since this test about correct packaging we just skip them when
+ # they don't exist (see below) rather than try to fixup cppflags.
+
+ if ! which $CC > /dev/null 2>&1; then
+ skip_env "$CC is not installed"
+ return 0
+ fi
+
+ for header in $prefix/*.h; do
+ if ! [[ -f "$header" ]]; then
+ continue
+ fi
+
+ if [[ "$(basename $header)" == liblustreapi.h ]]; then
+ continue # liblustreapi.h is deprecated.
+ fi
+
+ $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
+ error "cannot compile '$header'"
+ done
+}
+run_test 400b "packaged headers can be compiled"
+
#
# tests that do cleanup/setup should be run at the end
#