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

Commit 6dc0dfe7 authored by Mark Salyzyn's avatar Mark Salyzyn
Browse files

fs_mgr: overlayfs: test: add inRecovery check

Handle a device in recovery mode gracefully.  Handle a device
that fails to boot into a commanded state more gracefully.

Deal with regression where die() calls restore(), and we can not
have this under the conditions where we are ignoring the error
in a subshell.

Test: adb-remount-test.sh
Bug: 118225373
Bug: 123079041
Change-Id: Ie37beb245d0ec55eb00757cdb93da34ff9c42827
parent d5345f58
Loading
Loading
Loading
Loading
+113 −54
Original line number Diff line number Diff line
@@ -70,19 +70,37 @@ inFastboot() {
Returns: true if device is in adb mode" ]
inAdb() {
  adb devices |
    grep -v -e 'List of devices attached' -e '^$' |
    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() {
  args=
  local args=
  for i in "${@}"; do
    [ -z "${args}" ] || args="${args} "
    if [ X"${i}" != X"${i#\'}" ]; then
@@ -143,10 +161,10 @@ adb_su() {
Returns: content of file to stdout with carriage returns skipped,
         true of the file exists" ]
adb_cat() {
    OUTPUT="`adb_sh cat ${1} </dev/null 2>&1`"
    retval=${?}
    local OUTPUT="`adb_sh cat ${1} </dev/null 2>&1`"
    local ret=${?}
    echo "${OUTPUT}" | tr -d '\r'
    return ${retval}
    return ${ret}
}

[ "USAGE: adb_reboot
@@ -165,7 +183,7 @@ format_duration() {
    echo unknown
    return
  fi
  duration="${1}"
  local duration="${1}"
  if [ X"${duration}" != X"${duration%s}" ]; then
    duration=${duration%s}
  elif [ X"${duration}" != X"${duration%m}" ]; then
@@ -175,9 +193,9 @@ format_duration() {
  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`
  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
@@ -205,10 +223,10 @@ 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=${?}
    timeout --preserve-status --signal=KILL ${1} adb wait-for-device 2>/dev/null
    local ret=${?}
    echo -n "                                                                             ${CR}"
    return ${retval}
    return ${ret}
  else
    adb wait-for-device
  fi
@@ -216,12 +234,15 @@ adb_wait() {

[ "USAGE: usb_status > stdout

If adb_wait failed, check if device is in fastboot mode and report status
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
@@ -238,15 +259,47 @@ fastboot_wait() {
  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
    retval=${?}
    local ret=${?}
    echo -n "                                                                             ${CR}"
    ( exit ${retval} )
    ( exit ${ret} )
  else
    fastboot wait-for-device >/dev/null 2>/dev/null
  fi ||
    inFastboot
}

[ "USAGE: recovery_wait [timeout]

Returns: waits until the device has returned for recovery or optional timeout" ]
recovery_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-recovery 2>/dev/null
    local ret=${?}
    echo -n "                                                                             ${CR}"
    return ${ret}
  else
    adb wait-for-recovery
  fi
}

[ "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
@@ -277,11 +330,11 @@ adb_unroot() {

Returns: true if var output matches expected" ]
fastboot_getvar() {
  O=`fastboot getvar ${1} 2>&1`
  err=${?}
  local O=`fastboot getvar ${1} 2>&1`
  local ret=${?}
  O="${O#< waiting for * >?}"
  O="${O%%?Finished. Total time: *}"
  if [ 0 -ne ${err} ]; then
  if [ 0 -ne ${ret} ]; then
    echo ${O} >&2
    false
    return
@@ -325,7 +378,7 @@ test_duration() {
    echo "${BLUE}[     INFO ]${NORMAL} end `date`"
    [ -n "${start_time}" ] || return
    end_time=`date +%s`
    diff_time=`expr ${end_time} - ${start_time}`
    local diff_time=`expr ${end_time} - ${start_time}`
    echo "${BLUE}[     INFO ]${NORMAL} duration `format_duration ${diff_time}`"
  fi >&2
}
@@ -358,8 +411,8 @@ die() {

Returns true if (regex) lval matches rval" ]
EXPECT_EQ() {
  lval="${1}"
  rval="${2}"
  local lval="${1}"
  local rval="${2}"
  shift 2
  if ! ( echo X"${rval}" | grep '^X'"${lval}"'$' >/dev/null 2>/dev/null ); then
    if [ `echo ${lval}${rval}${*} | wc -c` -gt 50 -o "${rval}" != "${rval%
@@ -404,10 +457,10 @@ EXPECT_EQ() {

Exits if (regex) lval mismatches rval" ]
check_eq() {
  left="${1}"
  right="${2}"
  local lval="${1}"
  local rval="${2}"
  shift 2
  EXPECT_EQ "${left}" "${right}" ||
  EXPECT_EQ "${lval}" "${rval}" ||
    die "${@}"
}

@@ -498,15 +551,16 @@ if ${print_time}; then
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"
  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"
  echo "${ORANGE}[  WARNING ]${NORMAL} device does not have sepolicy in enforcing mode" >&2
  enforcing=false
fi

@@ -577,7 +631,7 @@ adb_sh ls -d /sys/module/overlay </dev/null >/dev/null 2>/dev/null ||
  ) ||
  overlayfs_supported=false
if ${overlayfs_supported}; then
  adb_su ls /sys/module/overlay/parameters/override_creds </dev/null >/dev/null &&
  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].*)
@@ -857,21 +911,20 @@ if ${overlayfs_needed}; then
    echo "${GREEN}[       OK ]${NORMAL} overlay takeover in first stage init" >&2
fi

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.
if ${enforcing}; then
  adb_unroot
  B="`adb_cat /vendor/hello`" &&
    die "re-read /vendor/hello after reboot w/o root"
  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
adb_root &&
  B="`adb_cat /vendor/hello`" ||
  die "re-read /vendor/hello after reboot"
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

@@ -901,8 +954,9 @@ elif [ -z "${ANDROID_HOST_OUT}" ]; then
else
  adb reboot-fastboot ||
    die "fastbootd not supported (wrong adb in path?)"
  fastboot_wait 2m ||
    die "reboot into fastboot to flash vendor `usb_status`"
  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"
@@ -956,12 +1010,11 @@ else
      if ${is_userspace_fastboot}; then
        die  "overlay supposed to be minus /vendor takeover after flash vendor"
      else
        echo "${ORANGE}[  WARNING ]${NORMAL} user fastboot missing, ignoring a failure"
        ( die  "overlay supposed to be minus /vendor takeover after flash vendor" )
        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`" ||
    die "re-read /system/hello after flash vendor"
  B="`adb_cat /system/hello`"
  check_eq "${A}" "${B}" system after flash vendor
  adb_root ||
    die "adb root"
@@ -969,13 +1022,21 @@ else
    if ${is_userspace_fastboot} || ! ${overlayfs_needed}; then
      die "re-read /vendor/hello after flash vendor"
    else
      echo "${ORANGE}[  WARNING ]${NORMAL} user fastboot missing, ignoring a failure"
      ( die "re-read /vendor/hello after flash vendor" )
      echo "${ORANGE}[  WARNING ]${NORMAL} user fastboot missing required to invalidate, ignoring a failure" >&2
      echo "${ORANGE}[  WARNING ]${NORMAL} re-read /vendor/hello after flash vendor" >&2
    fi
  if ${is_userspace_fastboot} || ! ${overlayfs_needed}; then
    check_eq "cat: /vendor/hello: No such file or directory" "${B}" vendor after flash vendor
    check_eq "cat: /vendor/hello: No such file or directory" "${B}" \
             vendor content after flash vendor
  else
    ( check_eq "cat: /vendor/hello: No such file or directory" "${B}" vendor after flash vendor )
    (
      echo "${ORANGE}[  WARNING ]${NORMAL} user fastboot missing required to invalidate, ignoring a failure" >&2
      restore() {
        true
      }
      check_eq "cat: /vendor/hello: No such file or directory" "${B}" \
               vendor content after flash vendor
    )
  fi
fi

@@ -1003,12 +1064,10 @@ echo "${H}"
  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"
check_eq "cat: /system/hello: No such file or directory" "${B}" after flash rm
B="`adb_cat /vendor/hello`" &&
  die "re-read /vendor/hello after rm"
check_eq "cat: /vendor/hello: No such file or directory" "${B}" after flash rm
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