Merge "fs_mgr: overlayfs support legacy devices (marlin)"

This commit is contained in:
Mark Salyzyn 2019-02-07 18:03:55 +00:00 committed by Gerrit Code Review
commit 4e3a5f61a4
2 changed files with 167 additions and 33 deletions

View file

@ -67,6 +67,13 @@ bool fs_mgr_access(const std::string& path) {
return ret;
}
// determine if a filesystem is available
bool fs_mgr_overlayfs_filesystem_available(const std::string& filesystem) {
std::string filesystems;
if (!android::base::ReadFileToString("/proc/filesystems", &filesystems)) return false;
return filesystems.find("\t" + filesystem + "\n") != std::string::npos;
}
} // namespace
#if ALLOW_ADBD_DISABLE_VERITY == 0 // If we are a user build, provide stubs
@ -625,8 +632,12 @@ const std::string kMkExt4("/system/bin/mke2fs");
// Only a suggestion for _first_ try during mounting
std::string fs_mgr_overlayfs_scratch_mount_type() {
if (!access(kMkF2fs.c_str(), X_OK) && fs_mgr_access("/sys/fs/f2fs")) return "f2fs";
if (!access(kMkExt4.c_str(), X_OK) && fs_mgr_access("/sys/fs/ext4")) return "ext4";
if (!access(kMkF2fs.c_str(), X_OK) && fs_mgr_overlayfs_filesystem_available("f2fs")) {
return "f2fs";
}
if (!access(kMkExt4.c_str(), X_OK) && fs_mgr_overlayfs_filesystem_available("ext4")) {
return "ext4";
}
return "auto";
}
@ -657,7 +668,7 @@ bool fs_mgr_overlayfs_make_scratch(const std::string& scratch_device, const std:
if (mnt_type == "f2fs") {
command = kMkF2fs + " -w 4096 -f -d1 -l" + android::base::Basename(kScratchMountPoint);
} else if (mnt_type == "ext4") {
command = kMkExt4 + " -b 4096 -t ext4 -m 0 -O has_journal -M " + kScratchMountPoint;
command = kMkExt4 + " -F -b 4096 -t ext4 -m 0 -O has_journal -M " + kScratchMountPoint;
} else {
errno = ESRCH;
LERROR << mnt_type << " has no mkfs cookbook";
@ -1002,7 +1013,7 @@ OverlayfsValidResult fs_mgr_overlayfs_valid() {
if (fs_mgr_access("/sys/module/overlay/parameters/override_creds")) {
return OverlayfsValidResult::kOverrideCredsRequired;
}
if (!fs_mgr_access("/sys/module/overlay")) {
if (!fs_mgr_overlayfs_filesystem_available("overlay")) {
return OverlayfsValidResult::kNotSupported;
}
struct utsname uts;

View file

@ -1,4 +1,15 @@
#! /bin/bash
#
# Divided into four section:
#
## USAGE
## Helper Variables
## Helper Functions
## MAINLINE
##
## USAGE
##
USAGE="USAGE: `basename ${0}` [-s <SerialNumber>]
@ -17,20 +28,26 @@ if [ X"${1}" = X"--help" -o X"${1}" = X"-h" -o X"${1}" = X"-?" ]; then
exit 0
fi
# Helper Variables
##
## 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"
# Helper functions
##
## Helper Functions
##
[ "USAGE: inFastboot
@ -68,6 +85,8 @@ adb_sh() {
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
@ -130,16 +149,62 @@ adb_cat() {
Returns: true if the reboot command succeeded" ]
adb_reboot() {
adb reboot remount-test &&
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
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
seconds=`expr ${duration} % 60`
minutes=`expr \( ${duration} / 60 \) % 60`
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() {
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
retval=${?}
echo -n " ${CR}"
return ${retval}
else
adb wait-for-device
fi
@ -152,10 +217,14 @@ fastboot_wait() {
# 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
timeout --preserve-status --signal=KILL ${1} fastboot wait-for-device
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
retval=${?}
echo -n " ${CR}"
( exit ${retval} )
else
fastboot wait-for-device >/dev/null
fi >/dev/null 2>/dev/null ||
fastboot wait-for-device >/dev/null 2>/dev/null
fi ||
inFastboot
}
@ -310,9 +379,14 @@ skip_administrative_mounts() {
-e "^\(overlay\|tmpfs\|none\|sysfs\|proc\|selinuxfs\|debugfs\) " \
-e "^\(bpf\|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\) "
}
##
## MAINLINE
##
if [ X"-s" = X"${1}" -a -n "${2}" ]; then
export ANDROID_SERIAL="${2}"
shift 2
@ -320,7 +394,7 @@ fi
inFastboot && die "device in fastboot mode"
if ! inAdb; then
echo "${ORANGE}[ WARNING ]${NORMAL} device not in adb mode ... waiting 2 minutes"
echo "${ORANGE}[ WARNING ]${NORMAL} device not in adb mode"
adb_wait 2m
fi
inAdb || die "specified device not in adb mode"
@ -331,19 +405,38 @@ if ! adb_su getenforce </dev/null | grep 'Enforcing' >/dev/null; then
enforcing=false
fi
# Do something
# Do something.
D=`get_property ro.serialno`
[ -n "${D}" ] || D=`get_property ro.boot.serialno`
[ -z "${D}" ] || 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`
echo "${BLUE}[ INFO ]${NORMAL} ${ANDROID_SERIAL} ${BUILD_DESCRIPTION}" >&2
[ -z "${BUILD_DESCRIPTION}" ] ||
echo "${BLUE}[ INFO ]${NORMAL} ${BUILD_DESCRIPTION}" >&2
VERITY_WAS_ENABLED=false
if [ "orange" = "`get_property ro.boot.verifiedbootstate`" -a \
"2" = "`get_property partition.system.verified`" ]; then
VERITY_WAS_ENABLED=true
fi
echo "${GREEN}[ RUN ]${NORMAL} Testing kernel support for overlayfs" >&2
overlayfs_supported=true;
adb_wait || die "wait for device failed"
adb_sh ls -d /sys/module/overlay </dev/null >/dev/null &&
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 &&
@ -391,9 +484,9 @@ if ${reboot}; then
echo "${ORANGE}[ WARNING ]${NORMAL} rebooting before test" >&2
adb_reboot &&
adb_wait 2m ||
die "lost device after reboot after wipe"
die "lost device after reboot after wipe (USB stack broken?)"
adb_root ||
die "lost device after elevation to root after wipe"
die "lost device after elevation to root after wipe (USB stack broken?)"
fi
D=`adb_sh df -k </dev/null` &&
H=`echo "${D}" | head -1` &&
@ -455,9 +548,9 @@ if [ X"${D}" != X"${H}" ]; then
L=`adb_logcat -b all -v nsec -t ${T} 2>&1`
adb_reboot &&
adb_wait 2m ||
die "lost device after reboot requested"
die "lost device after reboot requested (USB stack broken?)"
adb_root ||
die "lost device after elevation to root"
die "lost device after elevation to root (USB stack broken?)"
rebooted=true
# re-disable verity to see the setup remarks expected
T=`adb_date`
@ -544,7 +637,7 @@ if ${overlayfs_needed}; then
echo "${D}" | grep "^overlay .* /system\$" >/dev/null ||
die "overlay takeover after remount"
!(adb_sh grep "^overlay " /proc/mounts </dev/null |
grep -v "^overlay /\(vendor\|system\)/..* overlay ro," |
grep -v "^overlay /\(vendor\|system\|bionic\)/..* overlay ro," |
grep " overlay ro,") &&
!(adb_sh grep " rw," /proc/mounts </dev/null |
skip_administrative_mounts data) ||
@ -555,7 +648,7 @@ else
fi
fi
# Check something
# Check something.
echo "${GREEN}[ RUN ]${NORMAL} push content to /system and /vendor" >&2
@ -569,17 +662,22 @@ 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.
# 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} || die "pull libc.so from device"
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 || die "push libc.so to device"
adb pull /system/lib/bootstrap/libc.so ${tempdir}/libc.so.fromdevice || die "pull libc.so from device"
diff ${tempdir}/libc.so ${tempdir}/libc.so.fromdevice > /dev/null || die "libc.so differ"
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
@ -605,7 +703,7 @@ B="`adb_cat /system/hello`" ||
die "re-read /system/hello after reboot"
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
# Only root can read vendor if sepolicy permissions are as expected.
if ${enforcing}; then
adb_unroot
B="`adb_cat /vendor/hello`" &&
@ -619,9 +717,9 @@ adb_root &&
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
# Check if the updated libc.so is persistent after reboot.
adb_root &&
adb pull /system/lib/bootstrap/libc.so ${tempdir}/libc.so.fromdevice ||
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 -r ${tempdir}
@ -677,7 +775,7 @@ else
fi
fastboot reboot ||
die "can not reboot out of fastboot"
echo "${ORANGE}[ WARNING ]${NORMAL} adb after fastboot ... waiting 2 minutes"
echo "${ORANGE}[ WARNING ]${NORMAL} adb after fastboot"
adb_wait 2m ||
die "did not reboot after flash"
if ${overlayfs_needed}; then
@ -719,9 +817,26 @@ fi
echo "${GREEN}[ RUN ]${NORMAL} remove test content (cleanup)" >&2
T=`adb_date`
adb remount &&
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`" &&
die "re-read /system/hello after rm"
@ -768,12 +883,12 @@ if [ -n "${scratch_partition}" ]; then
die -t ${T} "setup for overlayfs"
fi
echo "${GREEN}[ RUN ]${NORMAL} test raw remount command" >&2
echo "${GREEN}[ RUN ]${NORMAL} test raw remount commands" >&2
# prerequisite is a prepped device from above
# Prerequisite is a prepped device from above.
adb_reboot &&
adb_wait 2m ||
die "lost device after reboot to ro state"
die "lost device after reboot to ro state (USB stack broken?)"
adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null &&
die "/vendor is not read-only"
adb_su mount -o rw,remount /vendor ||
@ -782,4 +897,12 @@ adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null ||
die "/vendor is not read-write"
echo "${GREEN}[ OK ]${NORMAL} mount -o rw,remount command works" >&2
if $VERITY_WAS_ENABLED && $overlayfs_supported; then
adb_root &&
adb enable-verity &&
adb_reboot &&
adb_wait 2m ||
die "failed to restore verity" >&2
fi
echo "${GREEN}[ PASSED ]${NORMAL} adb remount" >&2