| #!/bin/sh |
| # SPDX-License-Identifier: GPL-2.0 |
| # Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. |
| # |
| # automatic qa system. 31/08/00 dxm@sgi.com |
| # |
| # Usage: auto_qa start-state [stop-state] |
| # Do auto_qa from start-state up to stop-state inclusive |
| # or if no stop-state given then do it until reach "done" state. |
| # |
| |
| _log() |
| { |
| echo "$*" >&2 |
| echo "$*" >> $LOG |
| sync |
| } |
| |
| _fail() |
| { |
| if [ "$started" = "1" ] |
| then |
| echo "auto-qa stopped" | wall |
| started=0 |
| fi |
| |
| _log "$*" |
| |
| # send special email if a cron'd qa run fails |
| case $state |
| in |
| cron*) |
| mail -s "XFS QA status report" $EMAIL < $LOG 2>&1 |
| ;; |
| esac |
| |
| status=1 |
| exit 1 |
| } |
| |
| _get_kernel_version() |
| { |
| [ -x "$KWORKAREA" ] || return |
| [ -r "$KWORKAREA/Makefile" ] \ |
| || _fail "can't read kernel makefile $KWORKAREA/Makefile" |
| |
| eval `awk ' |
| BEGIN { FS = "[ \t=]+" } |
| /^VERSION =/ { a=$2 } |
| /^PATCHLEVEL =/ { b=$2 } |
| /^SUBLEVEL =/ { c=$2 } |
| /^EXTRAVERSION =/ { d=$2 } |
| END { |
| print "VERSION=" a "." b "." c d " ; SVERSION=" a "." b "." c |
| } |
| ' < $KWORKAREA/Makefile` |
| } |
| |
| # this should be constant |
| |
| ROOT="$HOME/qa" |
| HOST=`hostname -s` |
| if [ ! -z "$CVSROOT" ]; then |
| export WORKAREA="$ROOT/xfs-cmds" |
| else |
| [ -z "$WORKAREA" ] && export WORKAREA="$ROOT/xfs-cmds" |
| fi |
| |
| |
| export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin/ptools:/usr/local/bin" |
| STATE=$ROOT/qa.state |
| QADIR="$WORKAREA/xfstests" |
| SUDO="su -c" |
| CONFIG="$ROOT/$HOST.config" |
| COMMON_CONFIG="$QADIR/common/config" |
| SH="/bin/sh" |
| LOG="$ROOT/qa.log" |
| |
| # do some cleanup on exit |
| |
| _cleanup() |
| { |
| umount $SCRATCH_DEV &> /dev/null |
| umount $TEST_DEV &> /dev/null |
| if [ "$started" = 1 ] |
| then |
| echo "auto-qa stopped" | wall |
| started=0 |
| fi |
| } |
| status=1 |
| trap "_cleanup; exit \$status" 0 1 2 3 15 |
| |
| # clean exit |
| |
| _success() |
| { |
| status=0 |
| exit 0 |
| } |
| |
| _get_state() |
| { |
| state=`cat $STATE` |
| } |
| |
| _set_state() |
| { |
| echo $1 > $STATE |
| _get_state |
| } |
| |
| _change_state() |
| { |
| new=$1 |
| |
| # if have state XXXX-state then preserve XXXX-newstate |
| |
| case $state |
| in |
| *-*) |
| case $new |
| in |
| *-*) |
| _set_state $new |
| ;; |
| *) |
| _set_state `echo $state | sed "s/-.*$/-$new/"` |
| ;; |
| esac |
| ;; |
| *) |
| _set_state $new |
| ;; |
| esac |
| } |
| |
| _sudo() |
| { |
| $ROOT/su -c "$*" < /dev/null ;# HACK - we need a hacked su at the mo |
| } |
| |
| _restart() |
| { |
| exec $ROOT/su -c "(shutdown -r now \"auto-qa rebooting\" )&" < /dev/null |
| } |
| |
| _update_workarea() |
| { |
| if [ -z "$CVSROOT" ]; then |
| _log " *** p_tupdate" |
| cd "$1" |
| WORKAREA="$1" p_tupdate 2>&1 \ |
| || _fail " !!! p_tupdate failed" |
| |
| _log " *** non-trunk files" |
| cd "$1" |
| WORKAREA="$1" p_list -c 2>&1 \ |
| || _fail " !!! p_list failed" |
| else |
| _log " *** cvs update" |
| cd "$1" |
| cvs -z3 update -d |
| fi |
| } |
| |
| _test_mkfs_xfs() |
| { |
| TEST_OPTIONS="" |
| [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_RTDEV" ] && \ |
| TEST_OPTIONS="$TEST_OPTIONS -rrtdev=$TEST_RTDEV" |
| [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \ |
| TEST_OPTIONS="$TEST_OPTIONS -llogdev=$TEST_LOGDEV" |
| _sudo /sbin/mkfs.xfs -f $TEST_OPTIONS $MKFS_OPTIONS $* $TEST_DEV |
| mkfs_status=$? |
| if [ "$USE_BIG_LOOPFS" = yes ]; then |
| [ -z "$RETAIN_AG_BYTES" ] && RETAIN_AG_BYTES=0 |
| _sudo $QADIR/tools/ag-wipe -q -r $RETAIN_AG_BYTES $TEST_DEV |
| fi |
| return $mkfs_status |
| } |
| |
| _test_mount() |
| { |
| TEST_OPTIONS="" |
| [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_RTDEV" ] && \ |
| TEST_OPTIONS="$TEST_OPTIONS -ortdev=$TEST_RTDEV" |
| [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \ |
| TEST_OPTIONS="$TEST_OPTIONS -ologdev=$TEST_LOGDEV" |
| _sudo mount -t xfs $TEST_OPTIONS $MOUNT_OPTIONS $* $TEST_DEV $TEST_DIR |
| } |
| |
| _i386_install() |
| { |
| _sudo cp -f "$KWORKAREA/arch/i386/boot/bzImage" "$IMAGE" 2>&1 \ |
| || _fail " !!! install kernel failed" |
| _sudo cp -f "$KWORKAREA/System.map" "$SYSTEMMAP" 2>&1 \ |
| || _fail " !!! install kernel failed" |
| if [ -z "$KMODULES" -o "$KMODULES" = yes ]; then |
| _sudo make EXTRAVERSION=-$EXTRA modules_install 2>&1 \ |
| || _fail " !!! install modules failed" |
| fi |
| |
| |
| if [ -z "$KINSTALL" -o "$KINSTALL" = lilo ]; then |
| _log " *** reinit lilo" |
| _sudo /sbin/lilo 2>&1 \ |
| || _fail " !!! reinit lilo failed" |
| fi |
| } |
| |
| _i386_restart() |
| { |
| if [ -z "$KINSTALL" -o "$KINSTALL" = lilo ]; then |
| _sudo /sbin/lilo -R $EXTRA $KERNEL_OPTIONS 2>&1 \ |
| || _fail " !!! lilo failed" |
| fi |
| } |
| |
| _ia64_install() |
| { |
| echo not yet implemented |
| } |
| |
| _ia64_restart() |
| { |
| echo not yet implemented |
| } |
| |
| _check_kernel() |
| { |
| [ -d "$KWORKAREA" ] || _fail " !!! QA kernel workarea \"$KWORKAREA\" not found" |
| [ -r "$CONFIG" ] || _fail " !!! Can't read config file $CONFIG" |
| } |
| |
| |
| _log "*** XFS QA (`date`)" |
| |
| _get_state |
| |
| # check preconditions for starting state |
| case $1 |
| in |
| cron-init) |
| case $state |
| in |
| *done) |
| ;; |
| *) |
| _fail " !!! cron-init while not in \"*done\" state" |
| ;; |
| esac |
| ;; |
| cron-restarted) |
| # we don't auto restart after reboot, but cron the restart |
| # to happen a bit later - it's much easier and safer that way |
| if [ "$state" != "cron-restarted" ] |
| then |
| _fail " !!! cron-restarted while not in \"cron-restarted\" state" |
| fi |
| ;; |
| esac |
| |
| [ -n "$1" ] && _set_state $1 |
| [ -n "$2" ] && stop_state=$2 |
| |
| [ "$UID" -eq 0 ] && _fail " !!! QA most be run as a normal user" |
| [ -d "$ROOT" ] || _fail " !!! QA root \"$ROOT\" not found" |
| [ -d "$WORKAREA" ] || _fail " !!! QA workarea \"$WORKAREA\" not found" |
| cd $QADIR |
| . "$COMMON_CONFIG" || _fail " !!! Couldn't source $COMMON_CONFIG" |
| |
| _get_kernel_version |
| IMAGE="$BOOT/vmlinuz-$EXTRA" |
| SYSTEMMAP="$BOOT/System.map-$VERSION-$EXTRA" |
| MODULES="/lib/modules/$SVERSION" |
| |
| cd $ROOT |
| |
| started=1 |
| echo "auto-qa started" | wall |
| |
| while true |
| do |
| _get_state |
| |
| _log " *** state $state start (`date`)" |
| _log " (user=$USER, host=$HOST)" |
| new_state="" |
| |
| start_state=$state |
| |
| case $state |
| in |
| *init) |
| echo "" > $ROOT/qa.log |
| echo "" > $ROOT/qa.full |
| _log "******************************************************" |
| _log "QA init $VERSION (`date`)" |
| _log "******************************************************" |
| new_state="updatetools" |
| ;; |
| |
| *updatetools) |
| _update_workarea "$WORKAREA" |
| new_state="cleantools" |
| ;; |
| |
| *cleantools) |
| # we need to configure or else we might fail to clean |
| for pkg in attr acl xfsprogs xfsdump xfstests |
| do |
| [ -d $WORKAREA/$pkg ] || continue |
| cd $WORKAREA/$pkg |
| _log " *** clean $pkg tools" |
| make realclean 2>&1 \ |
| || _fail " !!! clean $pkg failed" |
| done |
| new_state="buildtools" |
| ;; |
| |
| *buildtools) |
| _log " *** build and install tools" |
| for pkg in attr acl xfsprogs xfsdump xfstests |
| do |
| [ -d $WORKAREA/$pkg ] || continue |
| cd $WORKAREA/$pkg |
| |
| make configure 2>&1 \ |
| || _fail " !!! configure $pkg failed" |
| make default 2>&1 \ |
| || _fail " !!! build $pkg failed" |
| |
| _sudo make install install-dev 2>&1 \ |
| || _fail " !!! install $pkg failed" |
| |
| # attr and acl now have install-lib targets as well |
| [ "$pkg" = "attr" -o "$pkg" = "acl" ] || continue |
| _sudo make install-lib 2>&1 \ |
| || _fail " !!! install $pkg failed" |
| done |
| |
| new_state="updatekernel" |
| ;; |
| |
| *updatekernel) |
| _check_kernel |
| _update_workarea "$KWORKAREA" |
| new_state="cleankernel" |
| ;; |
| |
| *cleankernel) |
| _check_kernel |
| _log " *** clean kernel" |
| cd "$KWORKAREA" |
| make mrproper 2>&1 \ |
| || _fail " !!! clean kernel failed" |
| |
| _log " *** install configuration file" |
| cp -f $CONFIG "$KWORKAREA/.config" 2>&1 \ |
| || _fail " !!! failed to install config" |
| |
| _log " *** remove version file" |
| rm -f include/linux/version.h 2>&1 \ |
| || _fail " !!! failed to clean version" |
| |
| new_state="reconfig" |
| ;; |
| |
| *reconfig) |
| _check_kernel |
| _log " *** reconfig kernel" |
| |
| # we better start from scratch if this fails |
| _change_state "cleankernel" |
| |
| cd "$KWORKAREA" |
| # we want to use default options for any new config options. |
| echo -e "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" | \ |
| make EXTRAVERSION=-$EXTRA oldconfig 2>&1 \ |
| || _fail " !!! reconfig oldconfig failed" |
| make EXTRAVERSION=-$EXTRA dep 2>&1 \ |
| || _fail " !!! reconfig dep failed" |
| |
| new_state="buildkernel" |
| ;; |
| |
| *buildkernel) |
| _check_kernel |
| _log " *** build kernel" |
| _log " --- kernel ($IMAGE)" |
| [ -z "$KMODULES" -o "$KMODULES" = yes ] && \ |
| _log " --- modules ($MODULES)" |
| |
| _change_state "cleankernel" ; # we better start from scratch if this fails |
| |
| cd "$KWORKAREA" |
| [ -z "$KTARGET" ] && KTARGET=bzImage |
| [ -z "$KMODULES" -o "$KMODULES" = yes ] && \ |
| KTARGET="$KTARGET modules" |
| make -j4 EXTRAVERSION=-$EXTRA $KTARGET 2>&1 \ |
| || _fail " !!! build $KTARGET failed" |
| new_state="install" |
| ;; |
| |
| *install) |
| _check_kernel |
| _log " *** blat old modules" |
| _sudo rm -rf $MODULES |
| |
| _log " *** install kernel" |
| cd "$KWORKAREA" |
| case `uname -m` |
| in |
| i386|i686) _i386_install ;; |
| ia64) _ia64_install ;; |
| esac |
| |
| new_state="restart" |
| ;; |
| |
| *restart) |
| _log " *** select qa kernel" |
| case `uname -m` |
| in |
| i386|i686) _i386_restart ;; |
| ia64) _ia64_restart ;; |
| esac |
| |
| _log " *** prepare to restart" |
| _change_state "restarted" |
| |
| _log " *** restarting" |
| |
| _restart # doesn't return |
| ;; |
| |
| *restarted) |
| _log " *** QA reentered after restart" |
| |
| new_state="check" |
| ;; |
| |
| *check) |
| uname=`uname -a` |
| _log " *** uname $uname" |
| |
| if [ "$MODULAR" -eq 0 ]; then |
| new_state="reset" |
| else |
| new_state="probe" |
| fi |
| ;; |
| |
| *probe) |
| _log " *** modules dependencies" |
| _sudo depmod -a 2>&1 \ |
| || _fail " !!! failed to depmod -a" |
| |
| _log " *** unmounting XFS mounts" |
| _sudo umount -a -t xfs 2>&1 |
| |
| _log " *** removing modules" |
| for m in xfsidbg xfs kdbm_pg kdbm_vm |
| do |
| _sudo rmmod $m 2> /dev/null |
| done |
| |
| _log " *** installing modules" |
| _sudo modprobe xfs 2>&1 \ |
| || _fail " !!! failed to modprobe xfs" |
| |
| new_state="reset" |
| ;; |
| |
| *reset) |
| |
| _log " *** unmounting TEST_DEV" |
| _sudo umount $TEST_DEV 2>&1 |
| |
| _log " *** unmounting SCRATCH_DEV" |
| _sudo umount $SCRATCH_DEV 2>&1 |
| |
| _log " *** clean TEST_DEV" |
| _test_mkfs_xfs 2>&1 \ |
| || _fail " !!! failed to mkfs TEST_DEV" |
| |
| _log " *** mounting TEST_DEV" |
| _test_mount 2>&1 \ |
| || _fail " !!! failed to mount" |
| |
| new_state="run" |
| ;; |
| |
| soak-run) |
| cd $QADIR |
| |
| _log " *** run soak test" |
| _sudo ./soak $SOAK_PASSES $SOAK_STRESS $SOAK_PROC \ |
| || _fail " !!! failed to run soak test" |
| |
| new_state="done" |
| ;; |
| |
| bench-run) |
| cd $QADIR |
| |
| # $BENCHMARK is typically unset, which equates to "all" |
| # |
| _log " *** run benchmarks" |
| _sudo ./bench $BENCH_PASSES `id -nu && id -ng` $BENCHMARK \ |
| || _fail " !!! failed to run benchmarks" |
| |
| _log "" |
| _log " *** send results mail" |
| mail -s "XFS QA benchmark results" $EMAIL < $QADIR/bench.out 2>&1 |
| |
| new_state="done" |
| ;; |
| |
| *run) |
| cd $QADIR |
| |
| _log " *** run tests ($CHECK_OPTIONS)" |
| _sudo ./check -l $CHECK_OPTIONS 2>&1 | tee $ROOT/qa.out |
| |
| _log "" |
| _log " *** send status mail" |
| mail -s "XFS QA status report" $EMAIL < $ROOT/qa.out 2>&1 |
| |
| new_state="done" |
| ;; |
| |
| *done) |
| _log "*** requested QA state transitions complete" |
| |
| _success |
| ;; |
| |
| *nothing) |
| new_state="done" |
| _log " *** do nothing" |
| ;; |
| |
| *) |
| _fail " !!! unknown state $state" |
| ;; |
| esac |
| |
| _log " *** state $state done (`date`)" |
| [ "$new_state" = "" ] && _fail " !!! no new state set" |
| |
| if [ -n "$stop_state" ] |
| then |
| # remove hyphen prefixes |
| s1=`echo $start_state | sed 's/.*-//'` |
| s2=`echo $stop_state | sed 's/.*-//'` |
| |
| if [ $s1 = $s2 ] |
| then |
| # we have been requested to stop here and not go on |
| new_state="done" |
| fi |
| fi |
| |
| _change_state $new_state |
| |
| done |