@@ -50,27 +50,56 @@ die()
ask_yesno()
{
local response
- echo -n -e "$@ (y/n) "
+ echo -n -e "$@ (y/N) "
read response
if [ "$response" != y ]; then
exit 1
fi
}
+adb_ready()
+{
+ adb devices | grep -q 'device$'
+}
+
+fastboot_ready()
+{
+ fastboot devices | grep -q 'fastboot$'
+}
+
wait_for_device()
{
+ local want_adb=false
+ local want_fastboot=false
+ local waiting_for=""
local unauthorized=false
local waiting=false
+
+ if [[ ,$1, == *,adb,* ]]; then
+ want_adb=true
+ waiting_for="adb to be ready"
+ fi
+ if [[ ,$1, == *,fastboot,* ]]; then
+ want_fastboot=true
+ waiting_for+="${waiting_for:+ or for }device to enter fastboot mode"
+ fi
+ : "${waiting_for:=device}"
+
while true; do
- if adb devices | grep -q 'device$'; then
- break
+ if $want_adb; then
+ if adb_ready; then
+ break
+ fi
+ if ! $unauthorized && adb devices | grep -q 'unauthorized$'; then
+ echo "adb is not authorized. Authorize it using the dialog on the device to continue."
+ unauthorized=true
+ fi
fi
- if adb devices | grep -q 'unauthorized$' && ! $unauthorized; then
- echo "adb is not authorized. Authorize it using the dialog on the device to continue."
- unauthorized=true
+ if $want_fastboot && fastboot_ready; then
+ return
fi
if ! $waiting && ! $unauthorized; then
- echo "Waiting for device..."
+ echo "Waiting for $waiting_for..."
waiting=true
fi
sleep 0.5
@@ -83,6 +112,115 @@ wait_for_device()
adb shell "setenforce 0"
}
+wait_for_adb()
+{
+ wait_for_device adb
+}
+
+wait_for_fastboot()
+{
+ wait_for_device fastboot
+}
+
+wait_for_adb_or_fastboot()
+{
+ wait_for_device adb,fastboot
+}
+
+reboot_into_fastboot_mode()
+{
+ adb reboot bootloader
+ wait_for_fastboot
+}
+
+# Query the version of the kernel running on the device
+query_kernel_version()
+{
+ adb shell "uname -r -v"
+}
+
+# Try to extract the version information from the $KERNEL image by grepping for
+# the linux_banner[] string. It's a hack, but there doesn't seem to be a better
+# way, and scripts elsewhere supposedly have been doing this for a long time...
+extract_kernel_version()
+{
+ local decompress
+
+ # Note: we use the filename extension rather than the 'file' program to get
+ # the compression format because old versions of 'file' don't recognize
+ # LZ4-compressed files.
+ case "$(basename "$KERNEL")" in
+ Image.gz*)
+ decompress="gzip -d -c"
+ ;;
+ Image.bz2*)
+ decompress="bzip2 -d -c"
+ ;;
+ Image.xz*)
+ decompress="xz -d -c"
+ ;;
+ Image.lz4*)
+ decompress="lz4 -d" # no -c option; stdout is assumed when not a tty
+ ;;
+ *)
+ decompress="cat"
+ ;;
+ esac
+ local banner="$($decompress "$KERNEL" \
+ | grep -a -m1 'Linux version [0-9]\+\.[0-9]\+.*#.*$')"
+
+ if [ -n "$banner" ]; then
+ local krelease="$(echo "$banner" | awk '{print $3}')"
+ local kver="#${banner##*#}"
+ echo "$krelease $kver"
+ fi
+}
+
+# If the specified $KERNEL isn't already running on the device, try to boot it
+# using 'fastboot boot'.
+boot_kernel()
+{
+ local version actual_version
+ local have_version=true
+
+ if [ ! -f "$KERNEL" ]; then
+ die "The specified kernel image does not exist: $KERNEL"
+ fi
+
+ version="$(extract_kernel_version "$KERNEL")"
+ if [ -z "$version" ]; then
+ cat 1>&2 <<EOF
+Warning: unable to extract version information from $KERNEL.
+We won't be able to verify that the device has successfully booted the kernel!
+EOF
+ version="(unknown version)"
+ have_version=false
+ fi
+
+ wait_for_adb_or_fastboot
+ if adb_ready; then
+ actual_version="$(query_kernel_version)"
+ if $have_version && [ "$version" = "$actual_version" ]; then
+ # Kernel is already running.
+ return
+ fi
+ echo "Rebooting to start new kernel: $version"
+ stop_existing_tests
+ reboot_into_fastboot_mode
+ else
+ echo "Starting kernel: $version"
+ fi
+ fastboot boot "$KERNEL"
+ wait_for_adb
+
+ actual_version="$(query_kernel_version)"
+ if $have_version && [ "$version" != "$actual_version" ]; then
+ die "Kernel did not successfully boot!\n" \
+ "Expected: $version\n" \
+ "Actual: $actual_version\n"
+ fi
+}
+
chroot_prepare()
{
cat <<EOF | adb shell
@@ -203,10 +341,9 @@ a smaller size? WARNING: THIS WILL DELETE ALL USER DATA!
EOF
ask_yesno " Erase and reformat userdata with smaller size?"
- adb reboot bootloader
+ echo
+ reboot_into_fastboot_mode
fastboot format::0x100000000 userdata # 4 GiB
- fastboot continue
- wait_for_device
}
setup_partitions()
@@ -222,12 +359,7 @@ setup_partitions()
ready)
;;
shrink_userdata)
- if [ "$1" = second_try ]; then
- die "An unexpected problem occurred when shrinking userdata."
- fi
- try_shrink_userdata
- setup_chroot
- setup_partitions second_try
+ return 1
;;
insufficient_space)
die "This device doesn't have enough space on its internal storage to run android-xfstests."
@@ -236,6 +368,7 @@ setup_partitions()
die "An unexpected problem occurred while setting up the xfstests partitions."
;;
esac
+ return 0
}
xfstests_running()
@@ -273,20 +406,60 @@ if ! type -P fastboot > /dev/null ; then
die "fastboot is not installed"
fi
-wait_for_device
-setup_chroot
-if ! xfstests_running; then
- setup_partitions first_try
-fi
-
case "$ARG" in
cmd=shell*|cmd=maint*)
- chroot_interactive_shell
- exit 0
+ want_shell=true
+ ;;
+ *)
+ want_shell=false
+ if adb_ready; then
+ stop_existing_tests
+ fi
;;
esac
-stop_existing_tests
+# Set up the kernel, the chroot, and the xfstests partitions.
+
+tried_to_shrink_userdata=false
+while true; do
+
+ # Start by booting into the correct kernel.
+ if [ -n "$KERNEL" ]; then
+ boot_kernel
+ elif fastboot_ready; then
+ fastboot continue
+ fi
+
+ wait_for_adb
+
+ # Set up the chroot and xfstests partitions. Note: if an interactive shell
+ # is requested and tests are currently running, we won't mess around with
+ # the partitions. However, we'll still try to set up the chroot just in
+ # case a different ROOT_FS was specified (in which case the existing tests
+ # will need to be stopped).
+ setup_chroot
+ if $want_shell && xfstests_running; then
+ break
+ fi
+ if setup_partitions; then
+ break
+ fi
+
+ # Need to shrink userdata to make space for the xfstests partitions!
+ if $tried_to_shrink_userdata; then
+ die "An unexpected problem occurred when shrinking userdata."
+ fi
+ try_shrink_userdata
+ tried_to_shrink_userdata=true
+
+ # 'userdata' has just been formatted and the device is now in fastboot mode.
+ # Start the configuration over again.
+done
+
+if $want_shell; then
+ chroot_interactive_shell
+ exit 0
+fi
cat > "$tmpfile" <<EOF
#!/bin/bash
@@ -10,3 +10,8 @@ ROOT_FS="$DIR/test-appliance/armhf_root_fs.tar.gz"
# Where to download the tarball from (at user's request) if we don't have it.
# If you want to disable this functionality, set this to an empty string.
ROOT_FS_URL="https://www.kernel.org/pub/linux/kernel/people/tytso/kvm-xfstests/armhf_root_fs.tar.gz"
+
+# Path to the kernel which android-xfstests will boot on the device using
+# 'fastboot boot', if it's not already running. This can also be set by the
+# --kernel option. If unset or empty, the existing kernel will be used.
+#KERNEL=$HOME/linux/arch/arm64/boot/Image.lz4-dtb
@@ -51,9 +51,7 @@ print_help ()
fi
echo " -x group - Exclude group of tests from running"
echo " -X test - Exclude test from running"
- if flavor_in kvm gce ; then
- echo " --kernel file - Boot the specified kernel"
- fi
+ echo " --kernel file - Boot the specified kernel"
if flavor_in kvm ; then
echo " --initrd initrd - Boot with the specified initrd"
elif flavor_in gce ; then
@@ -282,7 +280,6 @@ while [ "$1" != "" ]; do
SKIP_LOG=no
;;
--kernel) shift
- supported_flavors kvm gce
KERNEL="$1"
if test -d "$KERNEL" ; then
KERNEL="$KERNEL/arch/x86/boot/bzImage"