Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4e3a5f61 authored by Mark Salyzyn's avatar Mark Salyzyn Committed by Gerrit Code Review
Browse files

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

parents 186661d1 6d109ecb
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -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;
+152 −29
Original line number Diff line number Diff line
#! /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