--- /dev/null
+*~
+*.log
+*.o
+*.trs
+
+.deps
+Makefile
+Makefile.in
+
+/aclocal.m4
+/autom4te.cache
+/compile
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/depcomp
+/init
+/initrd
+/install-sh
+/missing
+/qemu-sanity-check
+/qemu-sanity-check.1
+/qemu-sanity-check.pod
+/stamp-h1
+/test-driver
CLEANFILES = qemu-sanity-check
bin_SCRIPTS = qemu-sanity-check
+initrddir = $(libdir)/qemu-sanity-check
+initrd_DATA = initrd
+
+# Build the initramfs.
+initrd: init
+ echo $< | cpio --quiet -o -H newc > $@-t
+ mv $@-t $@
+
+noinst_PROGRAMS = init
+init_SOURCES = init.c
+init_CFLAGS = -static
+init_LDFLAGS = -static
+
+# Build the man pages.
+qemu-sanity-check.pod: qemu-sanity-check.pod.in Makefile
+ rm -f $@ $@-t
+ $(SED) -e 's,@libdir\@,$(libdir),g' < $< > $@-t
+ mv $@-t $@
+ chmod 0555 $@
if HAVE_POD2MAN
endif
-TESTS = qemu-sanity-check
+# Tests.
+TESTS = run-qemu-sanity-check
bash - to run the script
+ gcc - to compile the helper program
+
+ static libc - to link the helper program statically
+
+ cpio - to build the initramfs
+
qemu and/or Linux kernel - something to test
pod2man (from Perl) - if you want to build the manual page
AC_INIT([qemu-sanity-check],[1.1.1])
AM_INIT_AUTOMAKE([foreign])
+dnl Check for basic C environment.
+AC_PROG_CC_STDC
+AC_PROG_INSTALL
+AC_PROG_CPP
+
+AC_C_PROTOTYPES
+test "x$U" != "x" && AC_MSG_ERROR([Compiler not ANSI compliant])
+
+AM_PROG_CC_C_O
+
+AC_PROG_SED
+
+AC_MSG_CHECKING([that a static binary can be built])
+old_CFLAGS="$CFLAGS"
+old_LDFLAGS="$LDFLAGS"
+CFLAGS="$CFLAGS -static"
+LDFLAGS="$LDFLAGS -static"
+AC_LINK_IFELSE([
+ #include <stdio.h>
+ #include <stdlib.h>
+ int main () { exit (0); }
+],[
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+ AC_MSG_ERROR([Building a static binary failed. Make sure you have static libc installed.])
+])
+
AC_CHECK_PROG([POD2MAN], [pod2man], [pod2man], [no])
if test "x$POD2MAN" = "xno"; then
AC_MSG_WARN([pod2man was not found. This is needed to build man pages.])
dnl Produce output files.
AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_FILES([qemu-sanity-check],[chmod +x qemu-sanity-check])
+AC_CONFIG_FILES([qemu-sanity-check],[chmod 0555 qemu-sanity-check])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
--- /dev/null
+/* init
+ * Copyright (C) 2013 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int
+main (int argc, char *argv[])
+{
+ fprintf (stderr, "\n");
+ fprintf (stderr, "***** initrd started up OK *****\n");
+ fprintf (stderr, "\n");
+ fprintf (stderr, "\n");
+ fprintf (stderr, "expect to see a kernel panic below, that is normal\n");
+ fprintf (stderr, "\n");
+ fprintf (stderr, "\n");
+
+ /* This process is init, PID 1, so when it exits the kernel will
+ * panic and reboot, but because we use qemu -no-reboot that will
+ * cause qemu to exit.
+ */
+ exit (0);
+}
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+initrd="@libdir@/initrd"
+
+arch="$(uname -m)"
+canonical_arch="$(uname -m | sed 's/i[456]86/i386/')"
+
+#timeout=10m
+
# Handle command line parsing.
function usage {
echo "qemu-sanity-check [options]"
echo "Options:"
- echo " --help Display this help"
- echo " --version Display version and exit"
+ echo " --help Display this help"
+ echo " -i|--initrd=initrd Set location of initramfs"
+ echo " -k|--kernel=vmlinuz Set location of kernel"
+ echo " -q|--qemu=qemu Set location of qemu/KVM binary"
+# echo " -t|--timeout=timeout Set the timeout"
+ echo " -V|--version Display version and exit"
exit 0
}
TEMP=$(getopt \
- -o v \
+ -o i:k:q:V \
--long help \
+ --long initrd: \
+ --long kernel: \
+ --long qemu: \
--long version \
-n 'qemu-sanity-check' -- "$@")
-if [ $? != 0 ]; then exit 1; fi
+if [ $? != 0 ]; then exit 2; fi
eval set -- "$TEMP"
while true; do
case "$1" in
- --help) usage ;;
- -v|--version) echo "@PACKAGE_NAME@ @PACKAGE_VERSION@"; exit 0 ;;
- --) shift; break ;;
- *) fail "internal error ($1)" ;;
+ --help)
+ usage
+ ;;
+ -i|--initrd)
+ initrd="$2"
+ shift 2
+ ;;
+ -k|--kernel)
+ kernel="$2"
+ shift 2
+ ;;
+ -q|--qemu)
+ qemu="$2"
+ shift 2
+ ;;
+# -t|--timeout)
+# timeout="$2"
+# shift 2
+# ;;
+ -V|--version)
+ echo "@PACKAGE_NAME@ @PACKAGE_VERSION@"
+ exit 0
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ echo "$0: internal error parsing options: $1"
+ exit 2
+ ;;
esac
done
+
+# Locate initrd.
+if [ ! -f "$initrd" ]; then
+ echo "$0: cannot find 'initrd', try using --initrd=/path/to/initrd"
+ echo "If you are running qemu-sanity-check without installing, then do:"
+ echo " $0 --initrd=./initrd $@"
+ echo "The default path is '@libdir@/initrd'."
+ exit 2
+fi
+
+# Locate kernel if not specified.
+if [ -z "$kernel" ]; then
+ kernel="$(ls -vr /boot/vmlinuz-*.$arch | head -1)"
+ if [ -z "$kernel" ]; then
+ echo "$0: cannot find a Linux kernel in /boot"
+ echo "Choose a kernel to test using --kernel=/path/to/vmlinuz"
+ exit 2
+ fi
+fi
+
+# Locate qemu if not specified.
+if [ -z "$qemu" ]; then
+ for q in qemu-kvm qemu-system-$canonical_arch qemu kvm; do
+ if "$q" --help >/dev/null 2>&1; then
+ qemu="$q"
+ break
+ fi
+ done
+ if [ -z "$qemu" ]; then
+ echo "$0: cannot find a qemu binary on the \$PATH"
+ echo "Choose a qemu binary to test using --qemu=/path/to/qemu"
+ exit 2
+ fi
+fi
+
+# Choose a temporary file for the output.
+test_output="$(mktemp --suff=.out)"
+
+# Run the command
+set -x
+#timeout "$timeout"
+"$qemu" \
+ -nographic -nodefconfig -nodefaults \
+ -no-reboot \
+ -serial stdio \
+ -kernel "$kernel" \
+ -initrd "$initrd" \
+ -append "console=ttyS0 panic=1" 2>&1 | tee "$test_output"
+r="${PIPESTATUS[0]}"
+set +x
+#if [ $r -eq 124 ]; then
+# cat "$test_output"
+# echo "$0: error: test $kernel on $qemu: timed out"
+# rm "$test_output"
+# exit 1
+if [ $r -ne 0 ]; then
+ cat "$test_output"
+ echo "$0: error: test $kernel on $qemu: failed"
+ rm "$test_output"
+ exit 1
+fi
+
+# Verify that userspace was reached.
+if ! grep -sq "initrd started up OK" "$test_output"; then
+ cat "$test_output"
+ echo "$0: error: test $kernel on $qemu: init process did not start up"
+ rm "$test_output"
+ exit 1
+fi
+
+# Successful.
+rm "$test_output"
+exit 0
--- /dev/null
+=encoding utf8
+
+=head1 NAME
+
+qemu-sanity-check - run a simple sanity check on qemu and the Linux kernel
+
+=head1 SUMMARY
+
+qemu-sanity-check [options]
+
+=head1 DESCRIPTION
+
+B<qemu-sanity-check> is a short shell script that test-boots a Linux
+kernel under qemu, making sure it boots up to userspace. The idea is
+to test the Linux kernel and/or qemu to make sure they are working.
+
+You can use the command on its own:
+
+ qemu-sanity-check
+
+In this case, the script will look for a suitable qemu binary on the
+C<$PATH> and the latest Linux kernel in C</boot> and try to boot that
+kernel on that qemu.
+
+You can also specify a qemu binary or a Linux kernel (either or both
+options can be omitted):
+
+ qemu-sanity-check --qemu=/path/to/qemu --kernel=/path/to/vmlinuz
+
+=head2 KVM
+
+KVM (C<kvm> or C<qemu-kvm>) can be used in place of qemu.
+
+=head2 KERNEL DRIVERS
+
+No kernel modules or special drivers are required except as noted
+below. The test uses an initramfs containing a static binary, so the
+kernel is B<not> required to locate block devices, use virtio, mount
+filesystems, etc.
+
+The kernel B<must> support only the following, compiled in (not as
+modules):
+
+=over 4
+
+=item *
+
+A serial port (usually: C<CONFIG_SERIAL_8250=y>)
+
+=item *
+
+Initrd/initramfs (C<CONFIG_BLK_DEV_INITRD=y>)
+
+=back
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<--help>
+
+Display short help message and exit.
+
+=item B<-i> INITRD
+
+=item B<--initrd>=INITRD
+
+Use the initramfs image named C<INITRD> instead of the default.
+
+=item B<-k> VMLINUZ
+
+=item B<--kernel>=VMLINUZ
+
+Use the kernel image C<VMLINUZ> instead of searching for the latest
+kernel installed in C</boot>.
+
+=item B<-q> QEMU
+
+=item B<--qemu>=QEMU
+
+Use the qemu (or KVM) binary C<QEMU> instead of searching C<$PATH> for
+a suitable binary.
+
+=item B<-V>
+
+=item B<--version>
+
+Display version and exit.
+
+=back
+
+=head1 EXIT STATUS
+
+The exit status is 0 if the Linux kernel booted as far as userspace
+under qemu; or if the I<--help> or I<--version> options were used.
+
+The exit status is 1 if the kernel boot failed under qemu.
+
+The exit status is 2 if the script itself failed (eg. incorrect
+command line options were used, a suitable kernel could not be found).
+
+=head1 FILES
+
+=over 4
+
+=item B<@libdir@/qemu-sanity-check/initrd>
+
+The default location for the small initramfs image that is used to
+test that userspace has been reached.
+
+=back
+
+=head1 SEE ALSO
+
+L<http://qemu.org>,
+L<http://kernel.org>
+
+=head1 AUTHORS
+
+Richard W.M. Jones <rjones@redhat.com>
+
+=head1 COPYRIGHT
+
+(C) Copyright 2013 Red Hat Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
--- /dev/null
+#!/bin/bash
+# -*- shell-script -*-
+# run-qemu-sanity-check
+# Copyright (C) 2013 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+./qemu-sanity-check --initrd=./initrd