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

Commit bbe33f78 authored by Mark Salyzyn's avatar Mark Salyzyn
Browse files

fs_mgr: harden adb-remount-test.sh

Harden adb-remount-test.sh script.  Add --no-color and --color
options.  Allows --serial to be passed in.  Add a recovery handler
that restores the device to verity enabled if possible.  List the
partitions sizes as they may be relevant to triaging errors.  Allow
for devices that have a mixed set of remounts, some direct, some
with overlayfs.  Allow two scripts to run at the same time on a host
machine targetting different devices.  Detect if wrong adb is used
for adb reboot-fastboot.

Add a build target for adb-remount-test.sh so that the script
is landed into the host tools bin for easy pickup.

Test: adb-remount-test.sh
Bug: 123079041
Change-Id: I6369a245a656419067ec4350a4dbdf78c9b0533e
parent cd67fa9c
Loading
Loading
Loading
Loading
+17 −0
Original line number Original line Diff line number Diff line
@@ -36,3 +36,20 @@ cc_test {
        "-Werror",
        "-Werror",
    ],
    ],
}
}

cc_prebuilt_binary {
    name: "adb-remount-test.sh",
    srcs: ["adb-remount-test.sh"],
    target: {
        darwin: {
            enabled: false,
        },
        windows: {
            enabled: false,
        },
        android: {
            enabled: false,
        },
    },
    host_supported: true,
}
+181 −50
Original line number Original line Diff line number Diff line
@@ -11,23 +11,23 @@
##  USAGE
##  USAGE
##
##


USAGE="USAGE: `basename ${0}` [-s <SerialNumber>]
USAGE="USAGE: `basename ${0}` [--help] [--serial <SerialNumber>] [--color]


adb remount tests (overlayfs focus)
adb remount tests

--help      This help
--serial    Specify device (must if multiple are present)
--color     Dress output with highlighting colors


Conditions:
Conditions:
 - Must be a userdebug build.
 - Must be a userdebug build.
 - Must be in adb mode.
 - Must be in adb mode.
 - Also tests overlayfs
  - Kernel must have overlayfs enabled and patched to support override_creds.
  - Kernel must have overlayfs enabled and patched to support override_creds.
 - Must have either squashfs, ext4-dedupe or right-sized partitions.
  - Must have either erofs, squashfs, ext4-dedupe or full partitions.
  - Minimum expectation system and vender are overlayfs covered partitions.
  - Minimum expectation system and vender are overlayfs covered partitions.
"
"


if [ X"${1}" = X"--help" -o X"${1}" = X"-h" -o X"${1}" = X"-?" ]; then
  echo "${USAGE}" >&2
  exit 0
fi

##
##
##  Helper Variables
##  Helper Variables
##
##
@@ -44,6 +44,7 @@ RED="${ESCAPE}[38;5;196m"
ORANGE="${ESCAPE}[38;5;255:165:0m"
ORANGE="${ESCAPE}[38;5;255:165:0m"
BLUE="${ESCAPE}[35m"
BLUE="${ESCAPE}[35m"
NORMAL="${ESCAPE}[0m"
NORMAL="${ESCAPE}[0m"
TMPDIR=${TMPDIR:-/tmp}


##
##
##  Helper Functions
##  Helper Functions
@@ -293,13 +294,22 @@ fastboot_getvar() {
  echo ${O} >&2
  echo ${O} >&2
}
}


[ "USAGE: restore

Do nothing: should be redefined when necessary.  Called after cleanup.

Returns: reverses configurations" ]
restore() {
  true
}

[ "USAGE: cleanup
[ "USAGE: cleanup


Do nothing: should be redefined when necessary
Do nothing: should be redefined when necessary


Returns: cleans up any latent resources, reverses configurations" ]
Returns: cleans up any latent resources" ]
cleanup() {
cleanup() {
  :
  true
}
}


[ "USAGE: die [-d|-t <epoch>] [message] >/dev/stderr
[ "USAGE: die [-d|-t <epoch>] [message] >/dev/stderr
@@ -321,6 +331,7 @@ die() {
  fi
  fi
  echo "${RED}[  FAILED  ]${NORMAL} ${@}" >&2
  echo "${RED}[  FAILED  ]${NORMAL} ${@}" >&2
  cleanup
  cleanup
  restore
  exit 1
  exit 1
}
}


@@ -413,9 +424,48 @@ skip_unrelated_mounts() {
##  MAINLINE
##  MAINLINE
##
##


if [ X"-s" = X"${1}" -a -n "${2}" ]; then
OPTIONS=`getopt --alternative --unquoted --longoptions help,serial:,colour,color,no-colour,no-color -- "?hs:" ${*}` ||
  export ANDROID_SERIAL="${2}"
  ( echo "${USAGE}" >&2 ; false ) ||
  shift 2
  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
      ;;
    --)
      shift
      break
      ;;
    -*)
      echo "${USAGE}" >&2
      die "${0}: error unknown option ${1}"
      ;;
    *)
      break
      ;;
  esac
  shift
done
if ! ${color}; then
  GREEN=""
  RED=""
  ORANGE=""
  BLUE=""
  NORMAL=""
fi
fi


inFastboot && die "device in fastboot mode"
inFastboot && die "device in fastboot mode"
@@ -451,15 +501,43 @@ BUILD_DESCRIPTION=`get_property ro.build.description`
[ -z "${BUILD_DESCRIPTION}" ] ||
[ -z "${BUILD_DESCRIPTION}" ] ||
  echo "${BLUE}[     INFO ]${NORMAL} ${BUILD_DESCRIPTION}" >&2
  echo "${BLUE}[     INFO ]${NORMAL} ${BUILD_DESCRIPTION}" >&2


VERITY_WAS_ENABLED=false
# 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 \
if [ "orange" = "`get_property ro.boot.verifiedbootstate`" -a \
     "2" = "`get_property partition.system.verified`" ]; then
     "2" = "`get_property partition.system.verified`" ]; then
  VERITY_WAS_ENABLED=true
  restore() {
    ${overlayfs_supported} || return 0
    echo "${GREEN}[     INFO ]${NORMAL} restoring verity" >&2
    inFastboot &&
      fastboot reboot &&
      adb_wait 2m
    adb_root &&
      adb enable-verity &&
      adb_reboot &&
      adb_wait 2m
  }
fi
fi


echo "${GREEN}[ RUN      ]${NORMAL} Testing kernel support for overlayfs" >&2
echo "${GREEN}[ RUN      ]${NORMAL} Testing kernel support for overlayfs" >&2


overlayfs_supported=true;
adb_wait || die "wait for device failed"
adb_wait || die "wait for device failed"
adb_sh ls -d /sys/module/overlay </dev/null >/dev/null 2>/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 &&
  adb_sh grep "nodev${TAB}overlay" /proc/filesystems </dev/null >/dev/null 2>/dev/null &&
@@ -478,7 +556,7 @@ if ${overlayfs_supported}; then
          echo "${ORANGE}[  WARNING ]${NORMAL} overlay module does not support override_creds" >&2 &&
          echo "${ORANGE}[  WARNING ]${NORMAL} overlay module does not support override_creds" >&2 &&
          false
          false
        ) ||
        ) ||
        overlayfs_supported=false;
        overlayfs_supported=false
      ;;
      ;;
    *)
    *)
      echo "${GREEN}[       OK ]${NORMAL} overlay module uses callers creds" >&2
      echo "${GREEN}[       OK ]${NORMAL} overlay module uses callers creds" >&2
@@ -550,8 +628,8 @@ T=`adb_date`
H=`adb disable-verity 2>&1`
H=`adb disable-verity 2>&1`
err=${?}
err=${?}
L=
L=
D="${H%?Now reboot your device for settings to take effect}"
D="${H%?Now reboot your device for settings to take effect*}"
if [ X"${D}" != X"${D##*using overlayfs}" ]; then
if [ X"${D}" != X"${D##*[Uu]sing overlayfs}" ]; then
  echo "${GREEN}[       OK ]${NORMAL} using overlayfs" >&2
  echo "${GREEN}[       OK ]${NORMAL} using overlayfs" >&2
fi
fi
if [ ${err} != 0 ]; then
if [ ${err} != 0 ]; then
@@ -583,8 +661,8 @@ if [ X"${D}" != X"${H}" ]; then
  T=`adb_date`
  T=`adb_date`
  H=`adb disable-verity 2>&1`
  H=`adb disable-verity 2>&1`
  err=${?}
  err=${?}
  D="${H%?Now reboot your device for settings to take effect}"
  D="${H%?Now reboot your device for settings to take effect*}"
  if [ X"${D}" != X"${D##*using overlayfs}" ]; then
  if [ X"${D}" != X"${D##*[Uu]sing overlayfs}" ]; then
    echo "${GREEN}[       OK ]${NORMAL} using overlayfs" >&2
    echo "${GREEN}[       OK ]${NORMAL} using overlayfs" >&2
  fi
  fi
  if [ ${err} != 0 ]; then
  if [ ${err} != 0 ]; then
@@ -615,7 +693,11 @@ fi


echo "${GREEN}[ RUN      ]${NORMAL} remount" >&2
echo "${GREEN}[ RUN      ]${NORMAL} remount" >&2


adb remount ||
D=`adb remount 2>&1`
ret=${?}
echo "${D}"
[ ${ret} != 0 ] ||
  [ X"${D}" = X"${D##*remount failed}" ] ||
  ( [ -n "${L}" ] && echo "${L}" && false ) ||
  ( [ -n "${L}" ] && echo "${L}" && false ) ||
  die -t "${T}" "adb remount failed"
  die -t "${T}" "adb remount failed"
D=`adb_sh df -k </dev/null` &&
D=`adb_sh df -k </dev/null` &&
@@ -665,10 +747,33 @@ if ${overlayfs_needed}; then
    die  "overlay takeover after remount"
    die  "overlay takeover after remount"
  !(adb_sh grep "^overlay " /proc/mounts </dev/null |
  !(adb_sh grep "^overlay " /proc/mounts </dev/null |
    skip_unrelated_mounts |
    skip_unrelated_mounts |
    grep " overlay ro,") &&
    grep " overlay ro,") ||
    !(adb_sh grep " rw," /proc/mounts </dev/null |
      skip_administrative_mounts data) ||
    die "remount overlayfs missed a spot (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 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
else
  if [ ${ret} = 0 ]; then
  if [ ${ret} = 0 ]; then
    die -t ${T} "unexpected overlay takeover"
    die -t ${T} "unexpected overlay takeover"
@@ -721,7 +826,7 @@ if ${overlayfs_needed}; then


  adb_su sed -n '1,/overlay \/system/p' /proc/mounts </dev/null |
  adb_su sed -n '1,/overlay \/system/p' /proc/mounts </dev/null |
    skip_administrative_mounts |
    skip_administrative_mounts |
    grep -v ' \(squashfs\|ext4\|f2fs\|vfat\) ' &&
    grep -v ' \(erofs\|squashfs\|ext4\|f2fs\|vfat\) ' &&
    echo "${ORANGE}[  WARNING ]${NORMAL} overlay takeover after first stage init" >&2 ||
    echo "${ORANGE}[  WARNING ]${NORMAL} overlay takeover after first stage init" >&2 ||
    echo "${GREEN}[       OK ]${NORMAL} overlay takeover in first stage init" >&2
    echo "${GREEN}[       OK ]${NORMAL} overlay takeover in first stage init" >&2
fi
fi
@@ -749,7 +854,10 @@ adb_root &&
  adb pull /system/lib/bootstrap/libc.so ${tempdir}/libc.so.fromdevice >/dev/null ||
  adb pull /system/lib/bootstrap/libc.so ${tempdir}/libc.so.fromdevice >/dev/null ||
  die "pull libc.so from device"
  die "pull libc.so from device"
diff ${tempdir}/libc.so ${tempdir}/libc.so.fromdevice > /dev/null || die "libc.so differ"
diff ${tempdir}/libc.so ${tempdir}/libc.so.fromdevice > /dev/null || die "libc.so differ"
rm -r ${tempdir}
rm -rf ${tempdir}
cleanup() {
  true
}
echo "${GREEN}[       OK ]${NORMAL} /system/lib/bootstrap/libc.so content remains after reboot" >&2
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
echo "${GREEN}[ RUN      ]${NORMAL} flash vendor, confirm its content disappears" >&2
@@ -762,9 +870,13 @@ elif [ ! -s "${ANDROID_PRODUCT_OUT}/vendor.img" ]; then
  echo "${ORANGE}[  WARNING ]${NORMAL} vendor image missing, skipping"
  echo "${ORANGE}[  WARNING ]${NORMAL} vendor image missing, skipping"
elif [ "${ANDROID_PRODUCT_OUT}" = "${ANDROID_PRODUCT_OUT%*/${H}}" ]; then
elif [ "${ANDROID_PRODUCT_OUT}" = "${ANDROID_PRODUCT_OUT%*/${H}}" ]; then
  echo "${ORANGE}[  WARNING ]${NORMAL} wrong vendor image, skipping"
  echo "${ORANGE}[  WARNING ]${NORMAL} wrong vendor image, skipping"
elif [ -z "${ANDROID_HOST_OUT}" ]; then
  echo "${ORANGE}[  WARNING ]${NORMAL} please run lunch, skipping"
else
else
  adb reboot-fastboot &&
  adb reboot-fastboot ||
    fastboot_wait 2m &&
    die "fastbootd not supported (wrong adb in path?)"
  fastboot_wait 2m ||
    die "reboot into fastboot to flash vendor `usb_status`"
  fastboot flash vendor ||
  fastboot flash vendor ||
    ( fastboot reboot && false) ||
    ( fastboot reboot && false) ||
    die "fastboot flash vendor"
    die "fastboot flash vendor"
@@ -804,7 +916,7 @@ else
    die "can not reboot out of fastboot"
    die "can not reboot out of fastboot"
  echo "${ORANGE}[  WARNING ]${NORMAL} adb after fastboot"
  echo "${ORANGE}[  WARNING ]${NORMAL} adb after fastboot"
  adb_wait 2m ||
  adb_wait 2m ||
    die "did not reboot after flash"
    die "did not reboot after flash `usb_status`"
  if ${overlayfs_needed}; then
  if ${overlayfs_needed}; then
    adb_root &&
    adb_root &&
      D=`adb_sh df -k </dev/null` &&
      D=`adb_sh df -k </dev/null` &&
@@ -847,7 +959,7 @@ T=`adb_date`
H=`adb remount 2>&1`
H=`adb remount 2>&1`
err=${?}
err=${?}
L=
L=
D="${H%?Now reboot your device for settings to take effect}"
D="${H%?Now reboot your device for settings to take effect*}"
if [ X"${H}" != X"${D}" ]; then
if [ X"${H}" != X"${D}" ]; then
  echo "${ORANGE}[  WARNING ]${NORMAL} adb remount requires a reboot after partial flash (legacy avb)"
  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`
  L=`adb_logcat -b all -v nsec -t ${T} 2>&1`
@@ -878,17 +990,18 @@ if [ -n "${scratch_partition}" ]; then


  adb reboot-fastboot ||
  adb reboot-fastboot ||
    die "Reboot into fastbootd"
    die "Reboot into fastbootd"
  img=${TMPDIR}/adb-remount-test-${$}.img
  cleanup() {
  cleanup() {
    rm /tmp/adb-remount-test.img
    rm ${img}
  }
  }
  dd if=/dev/zero of=/tmp/adb-remount-test.img bs=4096 count=16 2>/dev/null &&
  dd if=/dev/zero of=${img} bs=4096 count=16 2>/dev/null &&
    fastboot_wait 2m ||
    fastboot_wait 2m ||
    die "reboot into fastboot"
    die "reboot into fastboot `usb_status`"
  fastboot flash --force ${scratch_partition} /tmp/adb-remount-test.img
  fastboot flash --force ${scratch_partition} ${img}
  err=${?}
  err=${?}
  cleanup
  cleanup
  cleanup() {
  cleanup() {
    :
    true
  }
  }
  fastboot reboot ||
  fastboot reboot ||
    die "can not reboot out of fastboot"
    die "can not reboot out of fastboot"
@@ -900,14 +1013,32 @@ if [ -n "${scratch_partition}" ]; then
  T=`adb_date`
  T=`adb_date`
  D=`adb disable-verity 2>&1`
  D=`adb disable-verity 2>&1`
  err=${?}
  err=${?}
  adb remount ||
  if [ X"${D}" != "${D%?Now reboot your device for settings to take effect*}" ]
    die "remount failed"
  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}"
  echo "${D}"
  [ ${err} = 0 ] &&
  [ ${err} = 0 ] &&
    [ X"${D}" = X"${D##*setup failed}" ] &&
    [ X"${D}" = X"${D##*setup failed}" ] &&
    [ X"${D}" != X"${D##*using overlayfs}" ] &&
    [ X"${D}" != X"${D##*[Uu]sing overlayfs}" ] &&
    echo "${GREEN}[       OK ]${NORMAL} ${scratch_partition} recreated" >&2 ||
    echo "${GREEN}[       OK ]${NORMAL} ${scratch_partition} recreated" >&2 ||
    die -t ${T} "setup for overlayfs"
    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
fi


echo "${GREEN}[ RUN      ]${NORMAL} test raw remount commands" >&2
echo "${GREEN}[ RUN      ]${NORMAL} test raw remount commands" >&2
@@ -924,12 +1055,12 @@ adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null ||
  die "/vendor is not read-write"
  die "/vendor is not read-write"
echo "${GREEN}[       OK ]${NORMAL} mount -o rw,remount command works" >&2
echo "${GREEN}[       OK ]${NORMAL} mount -o rw,remount command works" >&2


if $VERITY_WAS_ENABLED && $overlayfs_supported; then
restore
  adb_root &&
err=${?}
    adb enable-verity &&
restore() {
    adb_reboot &&
  true
    adb_wait 2m ||
}
[ ${err} = 0 ] ||
  die "failed to restore verity" >&2
  die "failed to restore verity" >&2
fi


echo "${GREEN}[  PASSED  ]${NORMAL} adb remount" >&2
echo "${GREEN}[  PASSED  ]${NORMAL} adb remount" >&2