hwsim tests: Add scripts to run in a VM

Instead of running on the host, it can be useful to run in a
VM, particularly to test kernel rather than userspace changes,
so add a few scripts that allow doing so easily.

The basic idea is that the VM kernel is the same architecture
as the host kernel, so the host's root filesystem can be used
(in read-only mode) to run everything. Only a log filesystem
is mounted read-write and will get all the test output.

The kernel console output is collected to a special 'console'
file in the logs directory and kernel crashes are detected.

Signed-hostap: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2013-10-31 00:23:57 +01:00 committed by Jouni Malinen
parent e8e238c436
commit 970d3b096f
5 changed files with 1845 additions and 0 deletions

1
tests/hwsim/vm/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
vm-config

19
tests/hwsim/vm/README Normal file
View file

@ -0,0 +1,19 @@
These scripts allow you to run the hwsim tests inside a KVM virtual machine.
To set it up, first compile a kernel with the kernel-config file as the
.config. You can adjust it as needed, the configuration is for a 64-bit
x86 system and should be close to minimal. The architecture must be the
same as your host since the host's filesystem is used.
Install the required tools: at least 'kvm', if you want tracing trace-cmd,
valgrind if you want, etc.
Compile the hwsim tests as per the instructions given, you may have to
install some extra development packages (e.g. binutils-dev for libbfd).
Create a vm-config file and put the KERNELDIR option into it (see the
vm-run.sh script). If you want valgrind, also increase the memory size.
Now you can run the vm-run.sh script and it will execute the tests using
your system's root filesystem (read-only) inside the VM. The options you
give it are passed through to run-all.sh, see there.

73
tests/hwsim/vm/inside.sh Executable file
View file

@ -0,0 +1,73 @@
#!/bin/sh
# mount all kinds of things
mount tmpfs -t tmpfs /etc
# we need our own /dev/rfkill, and don't want device access
mount tmpfs -t tmpfs /dev
mount tmpfs -t tmpfs /tmp
# some sockets go into /var/run, and / is read-only
mount tmpfs -t tmpfs /var/run
mount proc -t proc /proc
mount sysfs -t sysfs /sys
# needed for tracing
mount debugfs -t debugfs /sys/kernel/debug
# reboot on any sort of crash
sysctl kernel.panic_on_oops=1
sysctl kernel.panic=1
# get extra command line variables from /proc/cmdline
TESTDIR=$(sed 's/.*testdir=\([^ ]*\) .*/\1/' /proc/cmdline)
EPATH=$(sed 's/.*EPATH=\([^ ]*\) .*/\1/' /proc/cmdline)
ARGS=$(sed 's/.*ARGS=//' /proc/cmdline)
# create /dev entries we need
mknod -m 660 /dev/ttyS0 c 4 64
mknod -m 660 /dev/random c 1 8
mknod -m 660 /dev/urandom c 1 9
mknod -m 666 /dev/null c 1 3
test -f /sys/class/misc/rfkill/dev && \
mknod -m 660 /dev/rfkill c $(cat /sys/class/misc/rfkill/dev | tr ':' ' ')
ln -s /proc/self/fd/0 /dev/stdin
ln -s /proc/self/fd/1 /dev/stdout
ln -s /proc/self/fd/2 /dev/stderr
# create dummy sudo - everything runs as uid 0
mkdir /tmp/bin
cat > /tmp/bin/sudo << EOF
#!/bin/bash
exec "\$@"
EOF
chmod +x /tmp/bin/sudo
# and put it into $PATH, as well as our extra-$PATH
export PATH=/tmp/bin:$EPATH:$PATH
# some tests assume adm/admin group(s) exist(s)
echo 'adm:x:0:' > /etc/group
echo 'admin:x:0:' >> /etc/group
# root should exist
echo 'root:x:0:0:root:/tmp:/bin/bash' > /etc/passwd
# local network is needed for some tests
ip link set lo up
# create logs mountpoint and mount the logshare
mkdir /tmp/logs
mount -t 9p -o trans=virtio,rw logshare /tmp/logs
# check if we're rebooting due to a kernel panic ...
if grep -q 'Kernel panic' /tmp/logs/console ; then
echo "KERNEL CRASHED!" >/dev/ttyS0
else
# finally run the tests
export USER=0
export LOGDIR=/tmp/logs
cd $TESTDIR
./run-all.sh $ARGS >/dev/ttyS0 2>&1
#bash </dev/ttyS0 >/dev/ttyS0 2>&1
fi
# and shut down the machine again
halt -f -p

1706
tests/hwsim/vm/kernel-config Normal file

File diff suppressed because it is too large Load diff

46
tests/hwsim/vm/vm-run.sh Executable file
View file

@ -0,0 +1,46 @@
#!/bin/bash
cd "$(dirname $0)"
if [ -z "$TESTDIR" ] ; then
TESTDIR=$(pwd)/../
fi
LOGS=/tmp/hwsim-test-logs/
# increase the memory size if you want to run with valgrind, 512 MB works
MEMORY=128
# Some ubuntu systems (notably 12.04) have issues with this - since the guest
# mounts as read-only it should be safe to not specify ,readonly. Override in
# vm-config if needed (see below)
ROTAG=,readonly
# set this to ttyS0 to see kvm messages (if something doesn't work)
KVMOUT=ttyS1
# you can set EPATH if you need anything extra in $PATH inside the VM
#EPATH=/some/dir
test -f vm-config && . vm-config
if [ -z "$KERNELDIR" ] ; then
echo "You need to set a KERNELDIR (in the environment or vm-config)"
exit 2
fi
KERNEL=$KERNELDIR/arch/x86_64/boot/bzImage
CMD=$TESTDIR/vm/inside.sh
LOGDIR=$LOGS/$(date +%s)
mkdir -p $LOGDIR
exec kvm \
-kernel $KERNEL -smp 4 \
-s -m $MEMORY -nographic \
-fsdev local,security_model=none,id=fsdev-root,path=/$ROTAG \
-device virtio-9p-pci,id=fs-root,fsdev=fsdev-root,mount_tag=/dev/root \
-fsdev local,security_model=none,id=fsdev-logs,path="$LOGDIR",writeout=immediate \
-device virtio-9p-pci,id=fs-logs,fsdev=fsdev-logs,mount_tag=logshare \
-monitor null -serial stdio -serial file:$LOGDIR/console \
-append "mac80211_hwsim.radios=5 init=$CMD testdir=$TESTDIR console=$KVMOUT root=/dev/root rootflags=trans=virtio,version=9p2000.u ro rootfstype=9p EPATH=$EPATH ARGS=$*"