Merge "fs_mgr: overlayfs support legacy devices (marlin)"
This commit is contained in:
commit
4e3a5f61a4
2 changed files with 167 additions and 33 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue