#! /bin/bash
|
#
|
# Divided into four section:
|
#
|
## USAGE
|
## Helper Variables
|
## Helper Functions
|
## MAINLINE
|
|
##
|
## USAGE
|
##
|
|
USAGE="USAGE: `basename ${0}` [--help] [--serial <SerialNumber>] [options]
|
|
adb remount tests
|
|
--help This help
|
--serial Specify device (must if multiple are present)
|
--color Dress output with highlighting colors
|
--print-time Report the test duration
|
|
Conditions:
|
- Must be a userdebug build.
|
- Must be in adb mode.
|
- Also tests overlayfs
|
- Kernel must have overlayfs enabled and patched to support override_creds.
|
- Must have either erofs, squashfs, ext4-dedupe or full partitions.
|
- Minimum expectation system and vender are overlayfs covered partitions.
|
"
|
|
##
|
## Helper Variables
|
##
|
|
SPACE=" "
|
# A _real_ embedded tab character
|
TAB="`echo | tr '\n' '\t'`"
|
# A _real_ embedded escape character
|
ESCAPE="`echo | tr '\n' '\033'`"
|
# A _real_ embedded carriage return character
|
CR="`echo | tr '\n' '\r'`"
|
GREEN="${ESCAPE}[38;5;40m"
|
RED="${ESCAPE}[38;5;196m"
|
ORANGE="${ESCAPE}[38;5;255:165:0m"
|
BLUE="${ESCAPE}[35m"
|
NORMAL="${ESCAPE}[0m"
|
TMPDIR=${TMPDIR:-/tmp}
|
print_time=false
|
start_time=`date +%s`
|
ACTIVE_SLOT=
|
|
##
|
## Helper Functions
|
##
|
|
[ "USAGE: inFastboot
|
|
Returns: true if device is in fastboot mode" ]
|
inFastboot() {
|
fastboot devices |
|
if [ -n "${ANDROID_SERIAL}" ]; then
|
grep "^${ANDROID_SERIAL}[${SPACE}${TAB}]" > /dev/null
|
else
|
wc -l | grep '^1$' >/dev/null
|
fi
|
}
|
|
[ "USAGE: inAdb
|
|
Returns: true if device is in adb mode" ]
|
inAdb() {
|
adb devices |
|
grep -v -e 'List of devices attached' -e '^$' -e "[${SPACE}${TAB}]recovery\$" |
|
if [ -n "${ANDROID_SERIAL}" ]; then
|
grep "^${ANDROID_SERIAL}[${SPACE}${TAB}]" > /dev/null
|
else
|
wc -l | grep '^1$' >/dev/null
|
fi
|
}
|
|
[ "USAGE: inRecovery
|
|
Returns: true if device is in recovery mode" ]
|
inRecovery() {
|
local list="`adb devices |
|
grep -v -e 'List of devices attached' -e '^$'`"
|
if [ -n "${ANDROID_SERIAL}" ]; then
|
echo "${list}" |
|
grep "^${ANDROID_SERIAL}[${SPACE}${TAB}][${SPACE}${TAB}]*recovery\$" >/dev/null
|
return ${?}
|
fi
|
if echo "${list}" | wc -l | grep '^1$' >/dev/null; then
|
echo "${list}" |
|
grep "[${SPACE}${TAB}]recovery\$" >/dev/null
|
return ${?}
|
fi
|
false
|
}
|
|
[ "USAGE: adb_sh <commands> </dev/stdin >/dev/stdout 2>/dev/stderr
|
|
Returns: true if the command succeeded" ]
|
adb_sh() {
|
local args=
|
for i in "${@}"; do
|
[ -z "${args}" ] || args="${args} "
|
if [ X"${i}" != X"${i#\'}" ]; then
|
args="${args}${i}"
|
elif [ X"${i}" != X"${i#* }" ]; then
|
args="${args}'${i}'"
|
elif [ X"${i}" != X"${i#*${TAB}}" ]; then
|
args="${args}'${i}'"
|
else
|
args="${args}${i}"
|
fi
|
done
|
adb shell "${args}"
|
}
|
|
[ "USAGE: adb_date >/dev/stdout
|
|
Returns: report device epoch time (suitable for logcat -t)" ]
|
adb_date() {
|
adb_sh date +%s.%N </dev/null
|
}
|
|
[ "USAGE: adb_logcat [arguments] >/dev/stdout
|
|
Returns: the logcat output" ]
|
adb_logcat() {
|
echo "${RED}[ INFO ]${NORMAL} logcat ${@}" >&2 &&
|
adb logcat "${@}" </dev/null |
|
grep -v 'logd : logdr: UID=' |
|
sed -e '${/------- beginning of kernel/d}' -e 's/^[0-1][0-9]-[0-3][0-9] //'
|
}
|
|
[ "USAGE: get_property <prop>
|
|
Returns the property value" ]
|
get_property() {
|
adb_sh getprop ${1} </dev/null
|
}
|
|
[ "USAGE: isDebuggable
|
|
Returns: true if device is (likely) a debug build" ]
|
isDebuggable() {
|
if inAdb && [ 1 != "`get_property ro.debuggable`" ]; then
|
false
|
fi
|
}
|
|
[ "USAGE: adb_su <commands> </dev/stdin >/dev/stdout 2>/dev/stderr
|
|
Returns: true if the command running as root succeeded" ]
|
adb_su() {
|
adb_sh su root "${@}"
|
}
|
|
[ "USAGE: adb_cat <file> >stdout
|
|
Returns: content of file to stdout with carriage returns skipped,
|
true of the file exists" ]
|
adb_cat() {
|
local OUTPUT="`adb_sh cat ${1} </dev/null 2>&1`"
|
local ret=${?}
|
echo "${OUTPUT}" | tr -d '\r'
|
return ${ret}
|
}
|
|
[ "USAGE: adb_reboot
|
|
Returns: true if the reboot command succeeded" ]
|
adb_reboot() {
|
adb reboot remount-test || true
|
sleep 2
|
}
|
|
[ "USAGE: format_duration [<seconds>|<seconds>s|<minutes>m|<hours>h|<days>d]
|
|
human readable output whole seconds, whole minutes or mm:ss" ]
|
format_duration() {
|
if [ -z "${1}" ]; then
|
echo unknown
|
return
|
fi
|
local duration="${1}"
|
if [ X"${duration}" != X"${duration%s}" ]; then
|
duration=${duration%s}
|
elif [ X"${duration}" != X"${duration%m}" ]; then
|
duration=`expr ${duration%m} \* 60`
|
elif [ X"${duration}" != X"${duration%h}" ]; then
|
duration=`expr ${duration%h} \* 3600`
|
elif [ X"${duration}" != X"${duration%d}" ]; then
|
duration=`expr ${duration%d} \* 86400`
|
fi
|
local seconds=`expr ${duration} % 60`
|
local minutes=`expr \( ${duration} / 60 \) % 60`
|
local hours=`expr ${duration} / 3600`
|
if [ 0 -eq ${minutes} -a 0 -eq ${hours} ]; then
|
if [ 1 -eq ${duration} ]; then
|
echo 1 second
|
return
|
fi
|
echo ${duration} seconds
|
return
|
elif [ 60 -eq ${duration} ]; then
|
echo 1 minute
|
return
|
elif [ 0 -eq ${seconds} -a 0 -eq ${hours} ]; then
|
echo ${minutes} minutes
|
return
|
fi
|
if [ 0 -eq ${hours} ]; then
|
echo ${minutes}:`expr ${seconds} / 10``expr ${seconds} % 10`
|
return
|
fi
|
echo ${hours}:`expr ${minutes} / 10``expr ${minutes} % 10`:`expr ${seconds} / 10``expr ${seconds} % 10`
|
}
|
|
[ "USAGE: adb_wait [timeout]
|
|
Returns: waits until the device has returned for adb or optional timeout" ]
|
adb_wait() {
|
local ret
|
if [ -n "${1}" ]; then
|
echo -n ". . . waiting `format_duration ${1}`" ${ANDROID_SERIAL} ${USB_ADDRESS} "${CR}"
|
timeout --preserve-status --signal=KILL ${1} adb wait-for-device 2>/dev/null
|
ret=${?}
|
echo -n " ${CR}"
|
else
|
adb wait-for-device
|
ret=${?}
|
fi
|
if [ 0 = ${ret} -a -n "${ACTIVE_SLOT}" ]; then
|
local active_slot=`get_active_slot`
|
if [ X"${ACTIVE_SLOT}" != X"${active_slot}" ]; then
|
echo "${ORANGE}[ WARNING ]${NORMAL} Active slot changed from ${ACTIVE_SLOT} to ${active_slot}" >&2
|
fi
|
fi
|
return ${ret}
|
}
|
|
[ "USAGE: usb_status > stdout
|
|
If adb_wait failed, check if device is in adb, recovery or fastboot mode
|
and report status string.
|
|
Returns: \"(USB stack borken?)\", \"(In fastboot mode)\" or \"(in adb mode)\"" ]
|
usb_status() {
|
if inFastboot; then
|
echo "(In fastboot mode)"
|
elif inRecovery; then
|
echo "(In recovery mode)"
|
elif inAdb; then
|
echo "(In adb mode)"
|
else
|
echo "(USB stack borken?)"
|
fi
|
}
|
|
[ "USAGE: fastboot_wait [timeout]
|
|
Returns: waits until the device has returned for fastboot or optional timeout" ]
|
fastboot_wait() {
|
local ret
|
# fastboot has no wait-for-device, but it does an automatic
|
# wait and requires (even a nonsensical) command to do so.
|
if [ -n "${1}" ]; then
|
echo -n ". . . waiting `format_duration ${1}`" ${ANDROID_SERIAL} ${USB_ADDRESS} "${CR}"
|
timeout --preserve-status --signal=KILL ${1} fastboot wait-for-device >/dev/null 2>/dev/null
|
ret=${?}
|
echo -n " ${CR}"
|
( exit ${ret} )
|
else
|
fastboot wait-for-device >/dev/null 2>/dev/null
|
fi ||
|
inFastboot
|
ret=${?}
|
if [ 0 = ${ret} -a -n "${ACTIVE_SLOT}" ]; then
|
local active_slot=`get_active_slot`
|
if [ X"${ACTIVE_SLOT}" != X"${active_slot}" ]; then
|
echo "${ORANGE}[ WARNING ]${NORMAL} Active slot changed from ${ACTIVE_SLOT} to ${active_slot}" >&2
|
fi
|
fi
|
return ${ret}
|
}
|
|
[ "USAGE: recovery_wait [timeout]
|
|
Returns: waits until the device has returned for recovery or optional timeout" ]
|
recovery_wait() {
|
local ret
|
if [ -n "${1}" ]; then
|
echo -n ". . . waiting `format_duration ${1}`" ${ANDROID_SERIAL} ${USB_ADDRESS} "${CR}"
|
timeout --preserve-status --signal=KILL ${1} adb wait-for-recovery 2>/dev/null
|
ret=${?}
|
echo -n " ${CR}"
|
else
|
adb wait-for-recovery
|
ret=${?}
|
fi
|
if [ 0 = ${ret} -a -n "${ACTIVE_SLOT}" ]; then
|
local active_slot=`get_active_slot`
|
if [ X"${ACTIVE_SLOT}" != X"${active_slot}" ]; then
|
echo "${ORANGE}[ WARNING ]${NORMAL} Active slot changed from ${ACTIVE_SLOT} to ${active_slot}" >&2
|
fi
|
fi
|
return ${ret}
|
}
|
|
[ "any_wait [timeout]
|
|
Returns: waits until a device has returned or optional timeout" ]
|
any_wait() {
|
(
|
adb_wait ${1} &
|
adb_pid=${!}
|
fastboot_wait ${1} &
|
fastboot_pid=${!}
|
recovery_wait ${1} &
|
recovery_pid=${!}
|
wait -n
|
kill "${adb_pid}" "${fastboot_pid}" "${recovery_pid}"
|
) >/dev/null 2>/dev/null
|
inFastboot || inAdb || inRecovery
|
}
|
|
[ "USAGE: adb_root
|
|
NB: This can be flakey on devices due to USB state
|
|
Returns: true if device in root state" ]
|
adb_root() {
|
[ root != "`adb_sh echo '${USER}' </dev/null`" ] || return 0
|
adb root >/dev/null </dev/null 2>/dev/null
|
sleep 2
|
adb_wait 2m &&
|
[ root = "`adb_sh echo '${USER}' </dev/null`" ]
|
}
|
|
[ "USAGE: adb_unroot
|
|
NB: This can be flakey on devices due to USB state
|
|
Returns: true if device in un root state" ]
|
adb_unroot() {
|
[ root = "`adb_sh echo '${USER}' </dev/null`" ] || return 0
|
adb unroot >/dev/null </dev/null 2>/dev/null
|
sleep 2
|
adb_wait 2m &&
|
[ root != "`adb_sh echo '${USER}' </dev/null`" ]
|
}
|
|
[ "USAGE: fastboot_getvar var expected >/dev/stderr
|
|
Returns: true if var output matches expected" ]
|
fastboot_getvar() {
|
local O=`fastboot getvar ${1} 2>&1`
|
local ret=${?}
|
O="${O#< waiting for * >?}"
|
O="${O%%?Finished. Total time: *}"
|
if [ 0 -ne ${ret} ]; then
|
echo ${O} >&2
|
false
|
return
|
fi
|
if [ "${O}" != "${O#*FAILED}" ]; then
|
O="${1}: <empty>"
|
fi
|
if [ -n "${2}" -a "${1}: ${2}" != "${O}" ]; then
|
echo "${2} != ${O}" >&2
|
false
|
return
|
fi
|
echo ${O} >&2
|
}
|
|
[ "USAGE: get_active_slot >/dev/stdout
|
|
Returns: with a or b string reporting active slot" ]
|
get_active_slot() {
|
if inAdb || inRecovery; then
|
get_property ro.boot.slot_suffix | tr -d _
|
elif inFastboot; then
|
fastboot_getvar current-slot 2>&1 | sed -n 's/current-slot: //p'
|
else
|
false
|
fi
|
}
|
|
[ "USAGE: restore
|
|
Do nothing: should be redefined when necessary. Called after cleanup.
|
|
Returns: reverses configurations" ]
|
restore() {
|
true
|
}
|
|
[ "USAGE: cleanup
|
|
Do nothing: should be redefined when necessary
|
|
Returns: cleans up any latent resources" ]
|
cleanup() {
|
true
|
}
|
|
[ "USAGE: test_duration >/dev/stderr
|
|
Prints the duration of the test
|
|
Returns: reports duration" ]
|
test_duration() {
|
if ${print_time}; then
|
echo "${BLUE}[ INFO ]${NORMAL} end `date`"
|
[ -n "${start_time}" ] || return
|
end_time=`date +%s`
|
local diff_time=`expr ${end_time} - ${start_time}`
|
echo "${BLUE}[ INFO ]${NORMAL} duration `format_duration ${diff_time}`"
|
fi >&2
|
}
|
|
[ "USAGE: die [-d|-t <epoch>] [message] >/dev/stderr
|
|
If -d, or -t <epoch> argument is supplied, dump logcat.
|
|
Returns: exit failure, report status" ]
|
die() {
|
if [ X"-d" = X"${1}" ]; then
|
adb_logcat -b all -v nsec -d >&2
|
shift
|
elif [ X"-t" = X"${1}" ]; then
|
if [ -n "${2}" ]; then
|
adb_logcat -b all -v nsec -t ${2} >&2
|
else
|
adb_logcat -b all -v nsec -d >&2
|
fi
|
shift 2
|
fi
|
echo "${RED}[ FAILED ]${NORMAL} ${@}" >&2
|
cleanup
|
restore
|
test_duration
|
exit 1
|
}
|
|
[ "USAGE: EXPECT_EQ <lval> <rval> [--warning [message]]
|
|
Returns true if (regex) lval matches rval" ]
|
EXPECT_EQ() {
|
local lval="${1}"
|
local rval="${2}"
|
shift 2
|
local error=1
|
local prefix="${RED}[ ERROR ]${NORMAL}"
|
if [ X"${1}" = X"--warning" ]; then
|
prefix="${RED}[ WARNING ]${NORMAL}"
|
error=0
|
shift 1
|
fi
|
if ! ( echo X"${rval}" | grep '^X'"${lval}"'$' >/dev/null 2>/dev/null ); then
|
if [ `echo ${lval}${rval}${*} | wc -c` -gt 50 -o "${rval}" != "${rval%
|
*}" ]; then
|
echo "${prefix} expected \"${lval}\"" >&2
|
echo "${prefix} got \"${rval}\"" |
|
sed ': again
|
N
|
s/\(\n\)\([^ ]\)/\1 \2/
|
t again' >&2
|
if [ -n "${*}" ] ; then
|
echo "${prefix} ${*}" >&2
|
fi
|
else
|
echo "${prefix} expected \"${lval}\" got \"${rval}\" ${*}" >&2
|
fi
|
return ${error}
|
fi
|
if [ -n "${*}" ] ; then
|
prefix="${GREEN}[ INFO ]${NORMAL}"
|
if [ X"${lval}" != X"${rval}" ]; then # we were supplied a regex?
|
if [ `echo ${lval}${rval}${*} | wc -c` -gt 60 -o "${rval}" != "${rval% *}" ]; then
|
echo "${prefix} ok \"${lval}\"" >&2
|
echo " = \"${rval}\"" |
|
sed ': again
|
N
|
s/\(\n\)\([^ ]\)/\1 \2/
|
t again' >&2
|
if [ -n "${*}" ] ; then
|
echo "${prefix} ${*}" >&2
|
fi
|
else
|
echo "${prefix} ok \"${lval}\" = \"${rval}\" ${*}" >&2
|
fi
|
else
|
echo "${prefix} ok \"${lval}\" ${*}" >&2
|
fi
|
fi
|
return 0
|
}
|
|
[ "USAGE: check_eq <lval> <rval> [--warning [message]]
|
|
Exits if (regex) lval mismatches rval" ]
|
check_eq() {
|
local lval="${1}"
|
local rval="${2}"
|
shift 2
|
if [ X"${1}" = X"--warning" ]; then
|
EXPECT_EQ "${lval}" "${rval}" ${*}
|
return
|
fi
|
EXPECT_EQ "${lval}" "${rval}" ||
|
die "${@}"
|
}
|
|
[ "USAGE: skip_administrative_mounts [data] < /proc/mounts
|
|
Filters out all administrative (eg: sysfs) mounts uninteresting to the test" ]
|
skip_administrative_mounts() {
|
if [ "data" = "${1}" ]; then
|
grep -v " /data "
|
else
|
cat -
|
fi |
|
grep -v \
|
-e "^\(overlay\|tmpfs\|none\|sysfs\|proc\|selinuxfs\|debugfs\|bpf\) " \
|
-e "^\(binfmt_misc\|cg2_bpf\|pstore\|tracefs\|adb\|mtp\|ptp\|devpts\) " \
|
-e "^\(/data/media\|/dev/block/loop[0-9]*\) " \
|
-e "^rootfs / rootfs rw," \
|
-e " /\(cache\|mnt/scratch\|mnt/vendor/persist\|persist\|metadata\) "
|
}
|
|
[ "USAGE: skip_unrelated_mounts < /proc/mounts
|
|
or output from df
|
|
Filters out all apex and vendor override administrative overlay mounts
|
uninteresting to the test" ]
|
skip_unrelated_mounts() {
|
grep -v "^overlay.* /\(apex\|bionic\|system\|vendor\)/[^ ]" |
|
grep -v "[%] /\(apex\|bionic\|system\|vendor\)/[^ ][^ ]*$"
|
}
|
|
##
|
## MAINLINE
|
##
|
|
OPTIONS=`getopt --alternative --unquoted \
|
--longoptions help,serial:,colour,color,no-colour,no-color \
|
--longoptions gtest_print_time,print-time \
|
-- "?hs:" ${*}` ||
|
( echo "${USAGE}" >&2 ; false ) ||
|
die "getopt failure"
|
set -- ${OPTIONS}
|
|
color=false
|
while [ ${#} -gt 0 ]; do
|
case ${1} in
|
-h | --help | -\?)
|
echo "${USAGE}" >&2
|
exit 0
|
;;
|
-s | --serial)
|
export ANDROID_SERIAL=${2}
|
shift
|
;;
|
--color | --colour)
|
color=true
|
;;
|
--no-color | --no-colour)
|
color=false
|
;;
|
--print-time | --gtest_print_time)
|
print_time=true
|
;;
|
--)
|
shift
|
break
|
;;
|
-*)
|
echo "${USAGE}" >&2
|
die "${0}: error unknown option ${1}"
|
;;
|
*)
|
break
|
;;
|
esac
|
shift
|
done
|
if ! ${color}; then
|
GREEN=""
|
RED=""
|
ORANGE=""
|
BLUE=""
|
NORMAL=""
|
fi
|
|
if ${print_time}; then
|
echo "${BLUE}[ INFO ]${NORMAL}" start `date` >&2
|
fi
|
|
inFastboot && die "device in fastboot mode"
|
inRecovery && die "device in recovery mode"
|
if ! inAdb; then
|
echo "${ORANGE}[ WARNING ]${NORMAL} device not in adb mode" >&2
|
adb_wait 2m
|
fi
|
inAdb || die "specified device not in adb mode"
|
isDebuggable || die "device not a debug build"
|
enforcing=true
|
if ! adb_su getenforce </dev/null | grep 'Enforcing' >/dev/null; then
|
echo "${ORANGE}[ WARNING ]${NORMAL} device does not have sepolicy in enforcing mode" >&2
|
enforcing=false
|
fi
|
|
# Do something.
|
|
D=`get_property ro.serialno`
|
[ -n "${D}" ] || D=`get_property ro.boot.serialno`
|
[ -z "${D}" -o -n "${ANDROID_SERIAL}" ] || ANDROID_SERIAL=${D}
|
USB_SERIAL=
|
[ -z "${ANDROID_SERIAL}" ] || USB_SERIAL=`find /sys/devices -name serial |
|
grep usb |
|
xargs grep -l ${ANDROID_SERIAL}`
|
USB_ADDRESS=
|
if [ -n "${USB_SERIAL}" ]; then
|
USB_ADDRESS=${USB_SERIAL%/serial}
|
USB_ADDRESS=usb${USB_ADDRESS##*/}
|
fi
|
[ -z "${ANDROID_SERIAL}${USB_ADDRESS}" ] ||
|
echo "${BLUE}[ INFO ]${NORMAL}" ${ANDROID_SERIAL} ${USB_ADDRESS} >&2
|
BUILD_DESCRIPTION=`get_property ro.build.description`
|
[ -z "${BUILD_DESCRIPTION}" ] ||
|
echo "${BLUE}[ INFO ]${NORMAL} ${BUILD_DESCRIPTION}" >&2
|
ACTIVE_SLOT=`get_active_slot`
|
[ -z "${ACTIVE_SLOT}" ] ||
|
echo "${BLUE}[ INFO ]${NORMAL} active slot is ${ACTIVE_SLOT}" >&2
|
|
# Report existing partition sizes
|
adb_sh ls -l /dev/block/by-name/ </dev/null 2>/dev/null |
|
sed -n 's@.* \([^ ]*\) -> /dev/block/\([^ ]*\)$@\1 \2@p' |
|
while read name device; do
|
case ${name} in
|
system_[ab] | system | vendor_[ab] | vendor | super | cache)
|
case ${device} in
|
sd*)
|
device=${device%%[0-9]*}/${device}
|
;;
|
esac
|
size=`adb_su cat /sys/block/${device}/size 2>/dev/null </dev/null` &&
|
size=`expr ${size} / 2` &&
|
echo "${BLUE}[ INFO ]${NORMAL} partition ${name} device ${device} size ${size}K" >&2
|
;;
|
esac
|
done
|
|
# Can we test remount -R command?
|
overlayfs_supported=true
|
if [ "orange" = "`get_property ro.boot.verifiedbootstate`" -a \
|
"2" = "`get_property partition.system.verified`" ]; then
|
restore() {
|
${overlayfs_supported} || return 0
|
inFastboot &&
|
fastboot reboot &&
|
adb_wait 2m
|
inAdb &&
|
adb_root &&
|
adb enable-verity >/dev/null 2>/dev/null &&
|
adb_reboot &&
|
adb_wait 2m
|
}
|
|
echo "${GREEN}[ RUN ]${NORMAL} Testing adb shell su root remount -R command" >&2
|
|
adb_su remount -R system </dev/null || true
|
sleep 2
|
adb_wait 2m ||
|
die "waiting for device after remount -R `usb_status`"
|
if [ "orange" != "`get_property ro.boot.verifiedbootstate`" -o \
|
"2" = "`get_property partition.system.verified`" ]; then
|
die "remount -R command failed"
|
fi
|
|
echo "${GREEN}[ OK ]${NORMAL} adb shell su root remount -R command" >&2
|
fi
|
|
echo "${GREEN}[ RUN ]${NORMAL} Testing kernel support for overlayfs" >&2
|
|
adb_wait || die "wait for device failed"
|
adb_sh ls -d /sys/module/overlay </dev/null >/dev/null 2>/dev/null ||
|
adb_sh grep "nodev${TAB}overlay" /proc/filesystems </dev/null >/dev/null 2>/dev/null &&
|
echo "${GREEN}[ OK ]${NORMAL} overlay module present" >&2 ||
|
(
|
echo "${ORANGE}[ WARNING ]${NORMAL} overlay module not present" >&2 &&
|
false
|
) ||
|
overlayfs_supported=false
|
if ${overlayfs_supported}; then
|
adb_su ls /sys/module/overlay/parameters/override_creds </dev/null >/dev/null 2>/dev/null &&
|
echo "${GREEN}[ OK ]${NORMAL} overlay module supports override_creds" >&2 ||
|
case `adb_sh uname -r </dev/null` in
|
4.[456789].* | 4.[1-9][0-9]* | [56789].*)
|
echo "${ORANGE}[ WARNING ]${NORMAL} overlay module does not support override_creds" >&2 &&
|
overlayfs_supported=false
|
;;
|
*)
|
echo "${GREEN}[ OK ]${NORMAL} overlay module uses caller's creds" >&2
|
;;
|
esac
|
fi
|
|
adb_root ||
|
die "initial setup"
|
|
echo "${GREEN}[ RUN ]${NORMAL} Checking current overlayfs status" >&2
|
|
# We can not universally use adb enable-verity to ensure device is
|
# in a overlayfs disabled state since it can prevent reboot on
|
# devices that remount the physical content rather than overlayfs.
|
# So lets do our best to surgically wipe the overlayfs state without
|
# having to go through enable-verity transition.
|
reboot=false
|
OVERLAYFS_BACKING="cache mnt/scratch"
|
for d in ${OVERLAYFS_BACKING}; do
|
if adb_sh ls -d /${d}/overlay </dev/null >/dev/null 2>/dev/null; then
|
echo "${ORANGE}[ WARNING ]${NORMAL} /${d}/overlay is setup, surgically wiping" >&2
|
adb_sh rm -rf /${d}/overlay </dev/null ||
|
die "/${d}/overlay wipe"
|
reboot=true
|
fi
|
done
|
if ${reboot}; then
|
echo "${ORANGE}[ WARNING ]${NORMAL} rebooting before test" >&2
|
adb_reboot &&
|
adb_wait 2m ||
|
die "lost device after reboot after wipe `usb_status`"
|
adb_root ||
|
die "lost device after elevation to root after wipe `usb_status`"
|
fi
|
D=`adb_sh df -k </dev/null` &&
|
H=`echo "${D}" | head -1` &&
|
D=`echo "${D}" | grep -v " /vendor/..*$" | grep "^overlay "` &&
|
echo "${H}" &&
|
echo "${D}" &&
|
echo "${ORANGE}[ WARNING ]${NORMAL} overlays present before setup" >&2 ||
|
echo "${GREEN}[ OK ]${NORMAL} no overlay present before setup" >&2
|
overlayfs_needed=true
|
D=`adb_sh cat /proc/mounts </dev/null |
|
skip_administrative_mounts data`
|
if echo "${D}" | grep /dev/root >/dev/null; then
|
D=`echo / /
|
echo "${D}" | grep -v /dev/root`
|
fi
|
D=`echo "${D}" | cut -s -d' ' -f1 | sort -u`
|
no_dedupe=true
|
for d in ${D}; do
|
adb_sh tune2fs -l $d </dev/null 2>&1 |
|
grep "Filesystem features:.*shared_blocks" >/dev/null &&
|
no_dedupe=false
|
done
|
D=`adb_sh df -k ${D} </dev/null |
|
sed 's@\([%] /\)\(apex\|bionic\|system\|vendor\)/[^ ][^ ]*$@\1@'`
|
echo "${D}"
|
if [ X"${D}" = X"${D##* 100[%] }" ] && ${no_dedupe} ; then
|
overlayfs_needed=false
|
elif ! ${overlayfs_supported}; then
|
die "need overlayfs, but do not have it"
|
fi
|
|
echo "${GREEN}[ RUN ]${NORMAL} disable verity" >&2
|
|
T=`adb_date`
|
H=`adb disable-verity 2>&1`
|
err=${?}
|
L=
|
D="${H%?Now reboot your device for settings to take effect*}"
|
if [ X"${D}" != X"${D##*[Uu]sing overlayfs}" ]; then
|
echo "${GREEN}[ OK ]${NORMAL} using overlayfs" >&2
|
fi
|
if [ ${err} != 0 ]; then
|
echo "${H}"
|
( [ -n "${L}" ] && echo "${L}" && false ) ||
|
die -t "${T}" "disable-verity"
|
fi
|
rebooted=false
|
if [ X"${D}" != X"${H}" ]; then
|
echo "${H}"
|
if [ X"${D}" != X"${D##*setup failed}" ]; then
|
echo "${ORANGE}[ WARNING ]${NORMAL} overlayfs setup whined" >&2
|
fi
|
D=`adb_sh df -k </dev/null` &&
|
H=`echo "${D}" | head -1` &&
|
D=`echo "${D}" | grep -v " /vendor/..*$" | grep "^overlay " || true` &&
|
[ -z "${D}" ] ||
|
( echo "${H}" && echo "${D}" && false ) ||
|
die -t ${T} "overlay takeover unexpected at this phase"
|
echo "${GREEN}[ INFO ]${NORMAL} rebooting as requested" >&2
|
L=`adb_logcat -b all -v nsec -t ${T} 2>&1`
|
adb_reboot &&
|
adb_wait 2m ||
|
die "lost device after reboot requested `usb_status`"
|
adb_root ||
|
die "lost device after elevation to root `usb_status`"
|
rebooted=true
|
# re-disable verity to see the setup remarks expected
|
T=`adb_date`
|
H=`adb disable-verity 2>&1`
|
err=${?}
|
D="${H%?Now reboot your device for settings to take effect*}"
|
if [ X"${D}" != X"${D##*[Uu]sing overlayfs}" ]; then
|
echo "${GREEN}[ OK ]${NORMAL} using overlayfs" >&2
|
fi
|
if [ ${err} != 0 ]; then
|
T=
|
fi
|
fi
|
if ${overlayfs_supported} && ${overlayfs_needed} && [ X"${D}" != X"${D##*setup failed}" ]; then
|
echo "${D}"
|
( [ -n "${L}" ] && echo "${L}" && false ) ||
|
die -t "${T}" "setup for overlay"
|
fi
|
if [ X"${D}" != X"${D##*Successfully disabled verity}" ]; then
|
echo "${H}"
|
D=`adb_sh df -k </dev/null` &&
|
H=`echo "${D}" | head -1` &&
|
D=`echo "${D}" | grep -v " /vendor/..*$" | grep "^overlay " || true` &&
|
[ -z "${D}" ] ||
|
( echo "${H}" && echo "${D}" && false ) ||
|
( [ -n "${L}" ] && echo "${L}" && false ) ||
|
die -t "${T}" "overlay takeover unexpected"
|
[ -n "${L}" ] && echo "${L}"
|
die -t "${T}" "unexpected report of verity being disabled a second time"
|
elif ${rebooted}; then
|
echo "${GREEN}[ OK ]${NORMAL} verity already disabled" >&2
|
else
|
echo "${ORANGE}[ WARNING ]${NORMAL} verity already disabled" >&2
|
fi
|
|
echo "${GREEN}[ RUN ]${NORMAL} remount" >&2
|
|
D=`adb remount 2>&1`
|
ret=${?}
|
echo "${D}"
|
[ ${ret} != 0 ] ||
|
[ X"${D}" = X"${D##*remount failed}" ] ||
|
( [ -n "${L}" ] && echo "${L}" && false ) ||
|
die -t "${T}" "adb remount failed"
|
D=`adb_sh df -k </dev/null` &&
|
H=`echo "${D}" | head -1` &&
|
D=`echo "${D}" | skip_unrelated_mounts | grep "^overlay "` ||
|
( [ -n "${L}" ] && echo "${L}" && false )
|
ret=${?}
|
uses_dynamic_scratch=false
|
scratch_partition=
|
if ${overlayfs_needed}; then
|
if [ ${ret} != 0 ]; then
|
die -t ${T} "overlay takeover failed"
|
fi
|
echo "${D}" | grep "^overlay .* /system\$" >/dev/null ||
|
echo "${ORANGE}[ WARNING ]${NORMAL} overlay takeover not complete" >&2
|
scratch_partition=scratch
|
if echo "${D}" | grep " /mnt/scratch" >/dev/null; then
|
echo "${BLUE}[ INFO ]${NORMAL} using ${scratch_partition} dynamic partition for overrides" >&2
|
fi
|
M=`adb_sh cat /proc/mounts </dev/null |
|
sed -n 's@\([^ ]*\) /mnt/scratch \([^ ]*\) .*@\2 on \1@p'`
|
[ -n "${M}" ] &&
|
echo "${BLUE}[ INFO ]${NORMAL} scratch filesystem ${M}"
|
uses_dynamic_scratch=true
|
if [ "${M}" != "${M##*/dev/block/by-name/}" ]; then
|
uses_dynamic_scratch=false
|
scratch_partition="${M##*/dev/block/by-name/}"
|
fi
|
scratch_size=`adb_sh df -k /mnt/scratch </dev/null 2>/dev/null |
|
while read device kblocks used available use mounted on; do
|
if [ "/mnt/scratch" = "\${mounted}" ]; then
|
echo \${kblocks}
|
fi
|
done` &&
|
[ -n "${scratch_size}" ] ||
|
die "scratch size"
|
echo "${BLUE}[ INFO ]${NORMAL} scratch size ${scratch_size}KB" >&2
|
for d in ${OVERLAYFS_BACKING}; do
|
if adb_sh ls -d /${d}/overlay/system/upper </dev/null >/dev/null 2>/dev/null; then
|
echo "${BLUE}[ INFO ]${NORMAL} /${d}/overlay is setup" >&2
|
fi
|
done
|
|
echo "${H}" &&
|
echo "${D}" &&
|
echo "${D}" | grep "^overlay .* /system\$" >/dev/null ||
|
die "overlay takeover after remount"
|
!(adb_sh grep "^overlay " /proc/mounts </dev/null |
|
skip_unrelated_mounts |
|
grep " overlay ro,") ||
|
die "remount overlayfs missed a spot (ro)"
|
D=`adb_sh grep " rw," /proc/mounts </dev/null |
|
skip_administrative_mounts data`
|
if echo "${D}" | grep /dev/root >/dev/null; then
|
D=`echo / /
|
echo "${D}" | grep -v /dev/root`
|
fi
|
D=`echo "${D}" | cut -s -d' ' -f1 | sort -u`
|
bad_rw=false
|
for d in ${D}; do
|
if adb_sh tune2fs -l $d </dev/null 2>&1 |
|
grep "Filesystem features:.*shared_blocks" >/dev/null; then
|
bad_rw=true
|
else
|
d=`adb_sh df -k ${D} </dev/null |
|
sed 's@\([%] /\)\(apex\|bionic\|system\|vendor\)/[^ ][^ ]*$@\1@'`
|
[ X"${d}" = X"${d##* 100[%] }" ] ||
|
bad_rw=true
|
fi
|
done
|
[ -z "${D}" ] ||
|
D=`adb_sh df -k ${D} </dev/null |
|
sed -e 's@\([%] /\)\(apex\|bionic\|system\|vendor\)/[^ ][^ ]*$@\1@' \
|
-e 's/^Filesystem /Filesystem (rw) /'`
|
[ -z "${D}" ] || echo "${D}"
|
${bad_rw} && die "remount overlayfs missed a spot (rw)"
|
else
|
if [ ${ret} = 0 ]; then
|
die -t ${T} "unexpected overlay takeover"
|
fi
|
fi
|
|
# Check something.
|
|
echo "${GREEN}[ RUN ]${NORMAL} push content to /system and /vendor" >&2
|
|
A="Hello World! $(date)"
|
echo "${A}" | adb_sh cat - ">/system/hello"
|
echo "${A}" | adb_sh cat - ">/vendor/hello"
|
B="`adb_cat /system/hello`" ||
|
die "sytem hello"
|
check_eq "${A}" "${B}" /system before reboot
|
B="`adb_cat /vendor/hello`" ||
|
die "vendor hello"
|
check_eq "${A}" "${B}" /vendor before reboot
|
|
# Download libc.so, append some gargage, push back, and check if the file
|
# is updated.
|
tempdir="`mktemp -d`"
|
cleanup() {
|
rm -rf ${tempdir}
|
}
|
adb pull /system/lib/bootstrap/libc.so ${tempdir} >/dev/null ||
|
die "pull libc.so from device"
|
garbage="`hexdump -n 16 -e '4/4 "%08X" 1 "\n"' /dev/random`"
|
echo ${garbage} >> ${tempdir}/libc.so
|
adb push ${tempdir}/libc.so /system/lib/bootstrap/libc.so >/dev/null ||
|
die "push libc.so to device"
|
adb pull /system/lib/bootstrap/libc.so ${tempdir}/libc.so.fromdevice >/dev/null ||
|
die "pull libc.so from device"
|
diff ${tempdir}/libc.so ${tempdir}/libc.so.fromdevice > /dev/null ||
|
die "libc.so differ"
|
|
echo "${GREEN}[ RUN ]${NORMAL} reboot to confirm content persistent" >&2
|
|
adb_reboot &&
|
adb_wait 2m ||
|
die "reboot after override content added failed `usb_status`"
|
|
if ${overlayfs_needed}; then
|
D=`adb_su df -k </dev/null` &&
|
H=`echo "${D}" | head -1` &&
|
D=`echo "${D}" | grep -v " /vendor/..*$" | grep "^overlay "` ||
|
( echo "${L}" && false ) ||
|
die -d "overlay takeover failed after reboot"
|
|
adb_su sed -n '1,/overlay \/system/p' /proc/mounts </dev/null |
|
skip_administrative_mounts |
|
grep -v ' \(erofs\|squashfs\|ext4\|f2fs\|vfat\) ' &&
|
echo "${ORANGE}[ WARNING ]${NORMAL} overlay takeover after first stage init" >&2 ||
|
echo "${GREEN}[ OK ]${NORMAL} overlay takeover in first stage init" >&2
|
fi
|
|
if ${enforcing}; then
|
adb_unroot ||
|
die "device not in unroot'd state"
|
B="`adb_cat /vendor/hello 2>&1`"
|
check_eq "cat: /vendor/hello: Permission denied" "${B}" vendor after reboot w/o root
|
echo "${GREEN}[ OK ]${NORMAL} /vendor content correct MAC after reboot" >&2
|
fi
|
B="`adb_cat /system/hello`"
|
check_eq "${A}" "${B}" /system after reboot
|
echo "${GREEN}[ OK ]${NORMAL} /system content remains after reboot" >&2
|
# Only root can read vendor if sepolicy permissions are as expected.
|
adb_root ||
|
die "adb root"
|
B="`adb_cat /vendor/hello`"
|
check_eq "${A}" "${B}" vendor after reboot
|
echo "${GREEN}[ OK ]${NORMAL} /vendor content remains after reboot" >&2
|
|
# Check if the updated libc.so is persistent after reboot.
|
adb_root &&
|
adb pull /system/lib/bootstrap/libc.so ${tempdir}/libc.so.fromdevice >/dev/null ||
|
die "pull libc.so from device"
|
diff ${tempdir}/libc.so ${tempdir}/libc.so.fromdevice > /dev/null || die "libc.so differ"
|
rm -rf ${tempdir}
|
cleanup() {
|
true
|
}
|
echo "${GREEN}[ OK ]${NORMAL} /system/lib/bootstrap/libc.so content remains after reboot" >&2
|
|
echo "${GREEN}[ RUN ]${NORMAL} flash vendor, confirm its content disappears" >&2
|
|
H=`adb_sh echo '${HOSTNAME}' </dev/null 2>/dev/null`
|
is_bootloader_fastboot=false
|
# cuttlefish?
|
[ X"${H}" != X"${H#vsoc}" ] || is_bootloader_fastboot=true
|
is_userspace_fastboot=false
|
|
if ! ${is_bootloader_fastboot}; then
|
echo "${ORANGE}[ WARNING ]${NORMAL} does not support fastboot, skipping"
|
elif [ -z "${ANDROID_PRODUCT_OUT}" ]; then
|
echo "${ORANGE}[ WARNING ]${NORMAL} build tree not setup, skipping"
|
elif [ ! -s "${ANDROID_PRODUCT_OUT}/vendor.img" ]; then
|
echo "${ORANGE}[ WARNING ]${NORMAL} vendor image missing, skipping"
|
elif [ "${ANDROID_PRODUCT_OUT}" = "${ANDROID_PRODUCT_OUT%*/${H}}" ]; then
|
echo "${ORANGE}[ WARNING ]${NORMAL} wrong vendor image, skipping"
|
elif [ -z "${ANDROID_HOST_OUT}" ]; then
|
echo "${ORANGE}[ WARNING ]${NORMAL} please run lunch, skipping"
|
else
|
adb reboot fastboot ||
|
die "fastbootd not supported (wrong adb in path?)"
|
any_wait 2m &&
|
inFastboot ||
|
die "reboot into fastboot to flash vendor `usb_status` (bad bootloader?)"
|
fastboot flash vendor ||
|
( fastboot reboot && false) ||
|
die "fastboot flash vendor"
|
fastboot_getvar is-userspace yes &&
|
is_userspace_fastboot=true
|
if [ -n "${scratch_paritition}" ]; then
|
fastboot_getvar partition-type:${scratch_partition} raw ||
|
( fastboot reboot && false) ||
|
die "fastboot can not see ${scratch_partition} parameters"
|
if ${uses_dynamic_scratch}; then
|
# check ${scratch_partition} via fastboot
|
fastboot_getvar has-slot:${scratch_partition} no &&
|
fastboot_getvar is-logical:${scratch_partition} yes ||
|
( fastboot reboot && false) ||
|
die "fastboot can not see ${scratch_partition} parameters"
|
else
|
fastboot_getvar is-logical:${scratch_partition} no ||
|
( fastboot reboot && false) ||
|
die "fastboot can not see ${scratch_partition} parameters"
|
fi
|
if ! ${uses_dynamic_scratch}; then
|
fastboot reboot-bootloader ||
|
die "Reboot into fastboot"
|
fi
|
if ${uses_dynamic_scratch}; then
|
echo "${BLUE}[ INFO ]${NORMAL} expect fastboot erase ${scratch_partition} to fail" >&2
|
fastboot erase ${scratch_partition} &&
|
( fastboot reboot || true) &&
|
die "fastboot can erase ${scratch_partition}"
|
fi
|
echo "${BLUE}[ INFO ]${NORMAL} expect fastboot format ${scratch_partition} to fail" >&2
|
fastboot format ${scratch_partition} &&
|
( fastboot reboot || true) &&
|
die "fastboot can format ${scratch_partition}"
|
fi
|
fastboot reboot ||
|
die "can not reboot out of fastboot"
|
echo "${ORANGE}[ WARNING ]${NORMAL} adb after fastboot"
|
adb_wait 2m ||
|
die "did not reboot after flash `usb_status`"
|
if ${overlayfs_needed}; then
|
adb_root &&
|
D=`adb_sh df -k </dev/null` &&
|
H=`echo "${D}" | head -1` &&
|
D=`echo "${D}" | skip_unrelated_mounts | grep "^overlay "` &&
|
echo "${H}" &&
|
echo "${D}" &&
|
echo "${D}" | grep "^overlay .* /system\$" >/dev/null ||
|
die "overlay /system takeover after flash vendor"
|
echo "${D}" | grep "^overlay .* /vendor\$" >/dev/null &&
|
if ${is_userspace_fastboot}; then
|
die "overlay supposed to be minus /vendor takeover after flash vendor"
|
else
|
echo "${ORANGE}[ WARNING ]${NORMAL} user fastboot missing required to invalidate, ignoring a failure" >&2
|
echo "${ORANGE}[ WARNING ]${NORMAL} overlay supposed to be minus /vendor takeover after flash vendor" >&2
|
fi
|
fi
|
B="`adb_cat /system/hello`"
|
check_eq "${A}" "${B}" system after flash vendor
|
adb_root ||
|
die "adb root"
|
B="`adb_cat /vendor/hello`"
|
if ${is_userspace_fastboot} || ! ${overlayfs_needed}; then
|
check_eq "cat: /vendor/hello: No such file or directory" "${B}" \
|
vendor content after flash vendor
|
else
|
echo "${ORANGE}[ WARNING ]${NORMAL} user fastboot missing required to invalidate, ignoring a failure" >&2
|
check_eq "cat: /vendor/hello: No such file or directory" "${B}" \
|
--warning vendor content after flash vendor
|
fi
|
fi
|
|
echo "${GREEN}[ RUN ]${NORMAL} remove test content (cleanup)" >&2
|
|
T=`adb_date`
|
H=`adb remount 2>&1`
|
err=${?}
|
L=
|
D="${H%?Now reboot your device for settings to take effect*}"
|
if [ X"${H}" != X"${D}" ]; then
|
echo "${ORANGE}[ WARNING ]${NORMAL} adb remount requires a reboot after partial flash (legacy avb)"
|
L=`adb_logcat -b all -v nsec -t ${T} 2>&1`
|
adb_reboot &&
|
adb_wait 2m &&
|
adb_root ||
|
die "failed to reboot"
|
T=`adb_date`
|
H=`adb remount 2>&1`
|
err=${?}
|
fi
|
echo "${H}"
|
[ ${err} = 0 ] &&
|
( adb_sh rm /vendor/hello </dev/null 2>/dev/null || true ) &&
|
adb_sh rm /system/hello </dev/null ||
|
( [ -n "${L}" ] && echo "${L}" && false ) ||
|
die -t ${T} "cleanup hello"
|
B="`adb_cat /system/hello`"
|
check_eq "cat: /system/hello: No such file or directory" "${B}" after rm
|
B="`adb_cat /vendor/hello`"
|
check_eq "cat: /vendor/hello: No such file or directory" "${B}" after rm
|
|
if [ -n "${scratch_partition}" ]; then
|
|
echo "${GREEN}[ RUN ]${NORMAL} test fastboot flash to ${scratch_partition} recovery" >&2
|
|
adb reboot fastboot ||
|
die "Reboot into fastbootd"
|
img=${TMPDIR}/adb-remount-test-${$}.img
|
cleanup() {
|
rm ${img}
|
}
|
dd if=/dev/zero of=${img} bs=4096 count=16 2>/dev/null &&
|
fastboot_wait 2m ||
|
die "reboot into fastboot `usb_status`"
|
fastboot flash --force ${scratch_partition} ${img}
|
err=${?}
|
cleanup
|
cleanup() {
|
true
|
}
|
fastboot reboot ||
|
die "can not reboot out of fastboot"
|
[ 0 -eq ${err} ] ||
|
die "fastboot flash ${scratch_partition}"
|
adb_wait 2m &&
|
adb_root ||
|
die "did not reboot after flash"
|
T=`adb_date`
|
D=`adb disable-verity 2>&1`
|
err=${?}
|
if [ X"${D}" != "${D%?Now reboot your device for settings to take effect*}" ]
|
then
|
echo "${ORANGE}[ WARNING ]${NORMAL} adb disable-verity requires a reboot after partial flash"
|
adb_reboot &&
|
adb_wait 2m &&
|
adb_root ||
|
die "failed to reboot"
|
T=`adb_date`
|
D="${D}
|
`adb disable-verity 2>&1`"
|
err=${?}
|
fi
|
|
echo "${D}"
|
[ ${err} = 0 ] &&
|
[ X"${D}" = X"${D##*setup failed}" ] &&
|
[ X"${D}" != X"${D##*[Uu]sing overlayfs}" ] &&
|
echo "${GREEN}[ OK ]${NORMAL} ${scratch_partition} recreated" >&2 ||
|
die -t ${T} "setup for overlayfs"
|
D=`adb remount 2>&1`
|
err=${?}
|
echo "${D}"
|
[ ${err} != 0 ] ||
|
[ X"${D}" = X"${D##*remount failed}" ] ||
|
( echo "${D}" && false ) ||
|
die -t ${T} "remount failed"
|
fi
|
|
echo "${GREEN}[ RUN ]${NORMAL} test raw remount commands" >&2
|
|
# Prerequisite is a prepped device from above.
|
adb_reboot &&
|
adb_wait 2m ||
|
die "lost device after reboot to ro state `usb_status`"
|
adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null &&
|
die "/vendor is not read-only"
|
adb_su mount -o rw,remount /vendor </dev/null ||
|
die "remount command"
|
adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null ||
|
die "/vendor is not read-write"
|
echo "${GREEN}[ OK ]${NORMAL} mount -o rw,remount command works" >&2
|
|
# Prerequisite is a prepped device from above.
|
adb_reboot &&
|
adb_wait 2m ||
|
die "lost device after reboot to ro state (USB stack broken?)"
|
adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null &&
|
die "/vendor is not read-only"
|
adb_su remount vendor </dev/null ||
|
die "remount command"
|
adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null ||
|
die "/vendor is not read-write"
|
adb_sh grep " /system .* rw," /proc/mounts >/dev/null </dev/null &&
|
die "/vendor is not read-only"
|
echo "${GREEN}[ OK ]${NORMAL} remount command works from setup" >&2
|
|
# Prerequisite is an overlayfs deconstructed device but with verity disabled.
|
# This also saves a lot of 'noise' from the command doing a mkfs on backing
|
# storage and all the related tuning and adjustment.
|
for d in ${OVERLAYFS_BACKING}; do
|
adb_su rm -rf /${d}/overlay </dev/null ||
|
die "/${d}/overlay wipe"
|
done
|
adb_reboot &&
|
adb_wait 2m ||
|
die "lost device after reboot after wipe (USB stack broken?)"
|
adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null &&
|
die "/vendor is not read-only"
|
adb_su remount vendor </dev/null ||
|
die "remount command"
|
adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null ||
|
die "/vendor is not read-write"
|
adb_sh grep " /system .* rw," /proc/mounts >/dev/null </dev/null &&
|
die "/system is not read-only"
|
echo "${GREEN}[ OK ]${NORMAL} remount command works from scratch" >&2
|
|
restore
|
err=${?}
|
|
if [ ${err} = 0 ] && ${overlayfs_supported}; then
|
echo "${GREEN}[ RUN ]${NORMAL} test 'adb remount -R'" >&2
|
adb_root &&
|
adb remount -R &&
|
adb_wait 2m ||
|
die "adb remount -R"
|
if [ "orange" != "`get_property ro.boot.verifiedbootstate`" -o \
|
"2" = "`get_property partition.system.verified`" ]; then
|
die "remount -R command failed to disable verity"
|
fi
|
|
echo "${GREEN}[ OK ]${NORMAL} 'adb remount -R' command" >&2
|
|
restore
|
err=${?}
|
fi
|
|
restore() {
|
true
|
}
|
|
[ ${err} = 0 ] ||
|
die "failed to restore verity" >&2
|
|
echo "${GREEN}[ PASSED ]${NORMAL} adb remount" >&2
|
|
test_duration
|