• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#! /bin/bash
2#
3# Divided into four section:
4#
5##  USAGE
6##  Helper Variables
7##  Helper Functions
8##  MAINLINE
9
10##
11##  USAGE
12##
13
14USAGE="USAGE: `basename ${0}` [--help] [--serial <SerialNumber>] [options]
15
16adb remount tests
17
18--help        This help
19--serial      Specify device (must if multiple are present)
20--color       Dress output with highlighting colors
21--print-time  Report the test duration
22
23Conditions:
24 - Must be a userdebug build.
25 - Must be in adb mode.
26 - Also tests overlayfs
27  - Kernel must have overlayfs enabled and patched to support override_creds.
28  - Must have either erofs, squashfs, ext4-dedupe or full partitions.
29  - Minimum expectation system and vender are overlayfs covered partitions.
30"
31
32##
33##  Helper Variables
34##
35
36SPACE=" "
37# A _real_ embedded tab character
38TAB="`echo | tr '\n' '\t'`"
39# A _real_ embedded escape character
40ESCAPE="`echo | tr '\n' '\033'`"
41# A _real_ embedded carriage return character
42CR="`echo | tr '\n' '\r'`"
43GREEN="${ESCAPE}[38;5;40m"
44RED="${ESCAPE}[38;5;196m"
45ORANGE="${ESCAPE}[38;5;255:165:0m"
46BLUE="${ESCAPE}[35m"
47NORMAL="${ESCAPE}[0m"
48TMPDIR=${TMPDIR:-/tmp}
49print_time=false
50start_time=`date +%s`
51ACTIVE_SLOT=
52
53##
54##  Helper Functions
55##
56
57[ "USAGE: inFastboot
58
59Returns: true if device is in fastboot mode" ]
60inFastboot() {
61  fastboot devices |
62    if [ -n "${ANDROID_SERIAL}" ]; then
63      grep "^${ANDROID_SERIAL}[${SPACE}${TAB}]" > /dev/null
64    else
65      wc -l | grep '^1$' >/dev/null
66    fi
67}
68
69[ "USAGE: inAdb
70
71Returns: true if device is in adb mode" ]
72inAdb() {
73  adb devices |
74    grep -v -e 'List of devices attached' -e '^$' -e "[${SPACE}${TAB}]recovery\$" |
75    if [ -n "${ANDROID_SERIAL}" ]; then
76      grep "^${ANDROID_SERIAL}[${SPACE}${TAB}]" > /dev/null
77    else
78      wc -l | grep '^1$' >/dev/null
79    fi
80}
81
82[ "USAGE: inRecovery
83
84Returns: true if device is in recovery mode" ]
85inRecovery() {
86  local list="`adb devices |
87              grep -v -e 'List of devices attached' -e '^$'`"
88  if [ -n "${ANDROID_SERIAL}" ]; then
89    echo "${list}" |
90      grep "^${ANDROID_SERIAL}[${SPACE}${TAB}][${SPACE}${TAB}]*recovery\$" >/dev/null
91    return ${?}
92  fi
93  if echo "${list}" | wc -l | grep '^1$' >/dev/null; then
94    echo "${list}" |
95      grep "[${SPACE}${TAB}]recovery\$" >/dev/null
96    return ${?}
97  fi
98  false
99}
100
101[ "USAGE: adb_sh <commands> </dev/stdin >/dev/stdout 2>/dev/stderr
102
103Returns: true if the command succeeded" ]
104adb_sh() {
105  local args=
106  for i in "${@}"; do
107    [ -z "${args}" ] || args="${args} "
108    if [ X"${i}" != X"${i#\'}" ]; then
109      args="${args}${i}"
110    elif [ X"${i}" != X"${i#* }" ]; then
111      args="${args}'${i}'"
112    elif [ X"${i}" != X"${i#*${TAB}}" ]; then
113      args="${args}'${i}'"
114    else
115      args="${args}${i}"
116    fi
117  done
118  adb shell "${args}"
119}
120
121[ "USAGE: adb_date >/dev/stdout
122
123Returns: report device epoch time (suitable for logcat -t)" ]
124adb_date() {
125  adb_sh date +%s.%N </dev/null
126}
127
128[ "USAGE: adb_logcat [arguments] >/dev/stdout
129
130Returns: the logcat output" ]
131adb_logcat() {
132  echo "${RED}[     INFO ]${NORMAL} logcat ${@}" >&2 &&
133  adb logcat "${@}" </dev/null |
134    grep -v 'logd    : logdr: UID=' |
135    sed -e '${/------- beginning of kernel/d}' -e 's/^[0-1][0-9]-[0-3][0-9] //'
136}
137
138[ "USAGE: get_property <prop>
139
140Returns the property value" ]
141get_property() {
142  adb_sh getprop ${1} </dev/null
143}
144
145[ "USAGE: isDebuggable
146
147Returns: true if device is (likely) a debug build" ]
148isDebuggable() {
149  if inAdb && [ 1 != "`get_property ro.debuggable`" ]; then
150    false
151  fi
152}
153
154[ "USAGE: adb_su <commands> </dev/stdin >/dev/stdout 2>/dev/stderr
155
156Returns: true if the command running as root succeeded" ]
157adb_su() {
158  adb_sh su root "${@}"
159}
160
161[ "USAGE: adb_cat <file> >stdout
162
163Returns: content of file to stdout with carriage returns skipped,
164         true of the file exists" ]
165adb_cat() {
166    local OUTPUT="`adb_sh cat ${1} </dev/null 2>&1`"
167    local ret=${?}
168    echo "${OUTPUT}" | tr -d '\r'
169    return ${ret}
170}
171
172[ "USAGE: adb_reboot
173
174Returns: true if the reboot command succeeded" ]
175adb_reboot() {
176  adb reboot remount-test || true
177  sleep 2
178}
179
180[ "USAGE: format_duration [<seconds>|<seconds>s|<minutes>m|<hours>h|<days>d]
181
182human readable output whole seconds, whole minutes or mm:ss" ]
183format_duration() {
184  if [ -z "${1}" ]; then
185    echo unknown
186    return
187  fi
188  local duration="${1}"
189  if [ X"${duration}" != X"${duration%s}" ]; then
190    duration=${duration%s}
191  elif [ X"${duration}" != X"${duration%m}" ]; then
192    duration=`expr ${duration%m} \* 60`
193  elif [ X"${duration}" != X"${duration%h}" ]; then
194    duration=`expr ${duration%h} \* 3600`
195  elif [ X"${duration}" != X"${duration%d}" ]; then
196    duration=`expr ${duration%d} \* 86400`
197  fi
198  local seconds=`expr ${duration} % 60`
199  local minutes=`expr \( ${duration} / 60 \) % 60`
200  local hours=`expr ${duration} / 3600`
201  if [ 0 -eq ${minutes} -a 0 -eq ${hours} ]; then
202    if [ 1 -eq ${duration} ]; then
203      echo 1 second
204      return
205    fi
206    echo ${duration} seconds
207    return
208  elif [ 60 -eq ${duration} ]; then
209    echo 1 minute
210    return
211  elif [ 0 -eq ${seconds} -a 0 -eq ${hours} ]; then
212    echo ${minutes} minutes
213    return
214  fi
215  if [ 0 -eq ${hours} ]; then
216    echo ${minutes}:`expr ${seconds} / 10``expr ${seconds} % 10`
217    return
218  fi
219  echo ${hours}:`expr ${minutes} / 10``expr ${minutes} % 10`:`expr ${seconds} / 10``expr ${seconds} % 10`
220}
221
222[ "USAGE: adb_wait [timeout]
223
224Returns: waits until the device has returned for adb or optional timeout" ]
225adb_wait() {
226  local ret
227  if [ -n "${1}" ]; then
228    echo -n ". . . waiting `format_duration ${1}`" ${ANDROID_SERIAL} ${USB_ADDRESS} "${CR}"
229    timeout --preserve-status --signal=KILL ${1} adb wait-for-device 2>/dev/null
230    ret=${?}
231    echo -n "                                                                             ${CR}"
232  else
233    adb wait-for-device
234    ret=${?}
235  fi
236  if [ 0 = ${ret} -a -n "${ACTIVE_SLOT}" ]; then
237    local active_slot=`get_active_slot`
238    if [ X"${ACTIVE_SLOT}" != X"${active_slot}" ]; then
239      echo "${ORANGE}[  WARNING ]${NORMAL} Active slot changed from ${ACTIVE_SLOT} to ${active_slot}" >&2
240    fi
241  fi
242  return ${ret}
243}
244
245[ "USAGE: usb_status > stdout
246
247If adb_wait failed, check if device is in adb, recovery or fastboot mode
248and report status string.
249
250Returns: \"(USB stack borken?)\", \"(In fastboot mode)\" or \"(in adb mode)\"" ]
251usb_status() {
252  if inFastboot; then
253    echo "(In fastboot mode)"
254  elif inRecovery; then
255    echo "(In recovery mode)"
256  elif inAdb; then
257    echo "(In adb mode)"
258  else
259    echo "(USB stack borken?)"
260  fi
261}
262
263[ "USAGE: fastboot_wait [timeout]
264
265Returns: waits until the device has returned for fastboot or optional timeout" ]
266fastboot_wait() {
267  local ret
268  # fastboot has no wait-for-device, but it does an automatic
269  # wait and requires (even a nonsensical) command to do so.
270  if [ -n "${1}" ]; then
271    echo -n ". . . waiting `format_duration ${1}`" ${ANDROID_SERIAL} ${USB_ADDRESS} "${CR}"
272    timeout --preserve-status --signal=KILL ${1} fastboot wait-for-device >/dev/null 2>/dev/null
273    ret=${?}
274    echo -n "                                                                             ${CR}"
275    ( exit ${ret} )
276  else
277    fastboot wait-for-device >/dev/null 2>/dev/null
278  fi ||
279    inFastboot
280  ret=${?}
281  if [ 0 = ${ret} -a -n "${ACTIVE_SLOT}" ]; then
282    local active_slot=`get_active_slot`
283    if [ X"${ACTIVE_SLOT}" != X"${active_slot}" ]; then
284      echo "${ORANGE}[  WARNING ]${NORMAL} Active slot changed from ${ACTIVE_SLOT} to ${active_slot}" >&2
285    fi
286  fi
287  return ${ret}
288}
289
290[ "USAGE: recovery_wait [timeout]
291
292Returns: waits until the device has returned for recovery or optional timeout" ]
293recovery_wait() {
294  local ret
295  if [ -n "${1}" ]; then
296    echo -n ". . . waiting `format_duration ${1}`" ${ANDROID_SERIAL} ${USB_ADDRESS} "${CR}"
297    timeout --preserve-status --signal=KILL ${1} adb wait-for-recovery 2>/dev/null
298    ret=${?}
299    echo -n "                                                                             ${CR}"
300  else
301    adb wait-for-recovery
302    ret=${?}
303  fi
304  if [ 0 = ${ret} -a -n "${ACTIVE_SLOT}" ]; then
305    local active_slot=`get_active_slot`
306    if [ X"${ACTIVE_SLOT}" != X"${active_slot}" ]; then
307      echo "${ORANGE}[  WARNING ]${NORMAL} Active slot changed from ${ACTIVE_SLOT} to ${active_slot}" >&2
308    fi
309  fi
310  return ${ret}
311}
312
313[ "any_wait [timeout]
314
315Returns: waits until a device has returned or optional timeout" ]
316any_wait() {
317  (
318    adb_wait ${1} &
319    adb_pid=${!}
320    fastboot_wait ${1} &
321    fastboot_pid=${!}
322    recovery_wait ${1} &
323    recovery_pid=${!}
324    wait -n
325    kill "${adb_pid}" "${fastboot_pid}" "${recovery_pid}"
326  ) >/dev/null 2>/dev/null
327  inFastboot || inAdb || inRecovery
328}
329
330[ "USAGE: adb_root
331
332NB: This can be flakey on devices due to USB state
333
334Returns: true if device in root state" ]
335adb_root() {
336  [ root != "`adb_sh echo '${USER}' </dev/null`" ] || return 0
337  adb root >/dev/null </dev/null 2>/dev/null
338  sleep 2
339  adb_wait 2m &&
340    [ root = "`adb_sh echo '${USER}' </dev/null`" ]
341}
342
343[ "USAGE: adb_unroot
344
345NB: This can be flakey on devices due to USB state
346
347Returns: true if device in un root state" ]
348adb_unroot() {
349  [ root = "`adb_sh echo '${USER}' </dev/null`" ] || return 0
350  adb unroot >/dev/null </dev/null 2>/dev/null
351  sleep 2
352  adb_wait 2m &&
353    [ root != "`adb_sh echo '${USER}' </dev/null`" ]
354}
355
356[ "USAGE: fastboot_getvar var expected >/dev/stderr
357
358Returns: true if var output matches expected" ]
359fastboot_getvar() {
360  local O=`fastboot getvar ${1} 2>&1`
361  local ret=${?}
362  O="${O#< waiting for * >?}"
363  O="${O%%?Finished. Total time: *}"
364  if [ 0 -ne ${ret} ]; then
365    echo ${O} >&2
366    false
367    return
368  fi
369  if [ "${O}" != "${O#*FAILED}" ]; then
370    O="${1}: <empty>"
371  fi
372  if [ -n "${2}" -a "${1}: ${2}" != "${O}" ]; then
373    echo "${2} != ${O}" >&2
374    false
375    return
376  fi
377  echo ${O} >&2
378}
379
380[ "USAGE: get_active_slot >/dev/stdout
381
382Returns: with a or b string reporting active slot" ]
383get_active_slot() {
384  if inAdb || inRecovery; then
385    get_property ro.boot.slot_suffix | tr -d _
386  elif inFastboot; then
387    fastboot_getvar current-slot 2>&1 | sed -n 's/current-slot: //p'
388  else
389    false
390  fi
391}
392
393[ "USAGE: restore
394
395Do nothing: should be redefined when necessary.  Called after cleanup.
396
397Returns: reverses configurations" ]
398restore() {
399  true
400}
401
402[ "USAGE: cleanup
403
404Do nothing: should be redefined when necessary
405
406Returns: cleans up any latent resources" ]
407cleanup() {
408  true
409}
410
411[ "USAGE: test_duration >/dev/stderr
412
413Prints the duration of the test
414
415Returns: reports duration" ]
416test_duration() {
417  if ${print_time}; then
418    echo "${BLUE}[     INFO ]${NORMAL} end `date`"
419    [ -n "${start_time}" ] || return
420    end_time=`date +%s`
421    local diff_time=`expr ${end_time} - ${start_time}`
422    echo "${BLUE}[     INFO ]${NORMAL} duration `format_duration ${diff_time}`"
423  fi >&2
424}
425
426[ "USAGE: die [-d|-t <epoch>] [message] >/dev/stderr
427
428If -d, or -t <epoch> argument is supplied, dump logcat.
429
430Returns: exit failure, report status" ]
431die() {
432  if [ X"-d" = X"${1}" ]; then
433    adb_logcat -b all -v nsec -d >&2
434    shift
435  elif [ X"-t" = X"${1}" ]; then
436    if [ -n "${2}" ]; then
437      adb_logcat -b all -v nsec -t ${2} >&2
438    else
439      adb_logcat -b all -v nsec -d >&2
440    fi
441    shift 2
442  fi
443  echo "${RED}[  FAILED  ]${NORMAL} ${@}" >&2
444  cleanup
445  restore
446  test_duration
447  exit 1
448}
449
450[ "USAGE: EXPECT_EQ <lval> <rval> [--warning [message]]
451
452Returns true if (regex) lval matches rval" ]
453EXPECT_EQ() {
454  local lval="${1}"
455  local rval="${2}"
456  shift 2
457  local error=1
458  local prefix="${RED}[    ERROR ]${NORMAL}"
459  if [ X"${1}" = X"--warning" ]; then
460      prefix="${RED}[  WARNING ]${NORMAL}"
461      error=0
462      shift 1
463  fi
464  if ! ( echo X"${rval}" | grep '^X'"${lval}"'$' >/dev/null 2>/dev/null ); then
465    if [ `echo ${lval}${rval}${*} | wc -c` -gt 50 -o "${rval}" != "${rval%
466*}" ]; then
467      echo "${prefix} expected \"${lval}\"" >&2
468      echo "${prefix} got \"${rval}\"" |
469        sed ': again
470             N
471             s/\(\n\)\([^ ]\)/\1             \2/
472             t again' >&2
473      if [ -n "${*}" ] ; then
474        echo "${prefix} ${*}" >&2
475      fi
476    else
477      echo "${prefix} expected \"${lval}\" got \"${rval}\" ${*}" >&2
478    fi
479    return ${error}
480  fi
481  if [ -n "${*}" ] ; then
482    prefix="${GREEN}[     INFO ]${NORMAL}"
483    if [ X"${lval}" != X"${rval}" ]; then  # we were supplied a regex?
484      if [ `echo ${lval}${rval}${*} | wc -c` -gt 60 -o "${rval}" != "${rval% *}" ]; then
485        echo "${prefix} ok \"${lval}\"" >&2
486        echo "       = \"${rval}\"" |
487          sed ': again
488               N
489               s/\(\n\)\([^ ]\)/\1          \2/
490               t again' >&2
491        if [ -n "${*}" ] ; then
492          echo "${prefix} ${*}" >&2
493        fi
494      else
495        echo "${prefix} ok \"${lval}\" = \"${rval}\" ${*}" >&2
496      fi
497    else
498      echo "${prefix} ok \"${lval}\" ${*}" >&2
499    fi
500  fi
501  return 0
502}
503
504[ "USAGE: check_eq <lval> <rval> [--warning [message]]
505
506Exits if (regex) lval mismatches rval" ]
507check_eq() {
508  local lval="${1}"
509  local rval="${2}"
510  shift 2
511  if [ X"${1}" = X"--warning" ]; then
512      EXPECT_EQ "${lval}" "${rval}" ${*}
513      return
514  fi
515  EXPECT_EQ "${lval}" "${rval}" ||
516    die "${@}"
517}
518
519[ "USAGE: skip_administrative_mounts [data] < /proc/mounts
520
521Filters out all administrative (eg: sysfs) mounts uninteresting to the test" ]
522skip_administrative_mounts() {
523  if [ "data" = "${1}" ]; then
524    grep -v " /data "
525  else
526    cat -
527  fi |
528  grep -v \
529    -e "^\(overlay\|tmpfs\|none\|sysfs\|proc\|selinuxfs\|debugfs\|bpf\) " \
530    -e "^\(binfmt_misc\|cg2_bpf\|pstore\|tracefs\|adb\|mtp\|ptp\|devpts\) " \
531    -e "^\(/data/media\|/dev/block/loop[0-9]*\) " \
532    -e "^rootfs / rootfs rw," \
533    -e " /\(cache\|mnt/scratch\|mnt/vendor/persist\|persist\|metadata\) "
534}
535
536[ "USAGE: skip_unrelated_mounts < /proc/mounts
537
538or output from df
539
540Filters out all apex and vendor override administrative overlay mounts
541uninteresting to the test" ]
542skip_unrelated_mounts() {
543    grep -v "^overlay.* /\(apex\|bionic\|system\|vendor\)/[^ ]" |
544      grep -v "[%] /\(apex\|bionic\|system\|vendor\)/[^ ][^ ]*$"
545}
546
547##
548##  MAINLINE
549##
550
551OPTIONS=`getopt --alternative --unquoted \
552                --longoptions help,serial:,colour,color,no-colour,no-color \
553                --longoptions gtest_print_time,print-time \
554                -- "?hs:" ${*}` ||
555  ( echo "${USAGE}" >&2 ; false ) ||
556  die "getopt failure"
557set -- ${OPTIONS}
558
559color=false
560while [ ${#} -gt 0 ]; do
561  case ${1} in
562    -h | --help | -\?)
563      echo "${USAGE}" >&2
564      exit 0
565      ;;
566    -s | --serial)
567      export ANDROID_SERIAL=${2}
568      shift
569      ;;
570    --color | --colour)
571      color=true
572      ;;
573    --no-color | --no-colour)
574      color=false
575      ;;
576    --print-time | --gtest_print_time)
577      print_time=true
578      ;;
579    --)
580      shift
581      break
582      ;;
583    -*)
584      echo "${USAGE}" >&2
585      die "${0}: error unknown option ${1}"
586      ;;
587    *)
588      break
589      ;;
590  esac
591  shift
592done
593if ! ${color}; then
594  GREEN=""
595  RED=""
596  ORANGE=""
597  BLUE=""
598  NORMAL=""
599fi
600
601if ${print_time}; then
602  echo "${BLUE}[     INFO ]${NORMAL}" start `date` >&2
603fi
604
605inFastboot && die "device in fastboot mode"
606inRecovery && die "device in recovery mode"
607if ! inAdb; then
608  echo "${ORANGE}[  WARNING ]${NORMAL} device not in adb mode" >&2
609  adb_wait 2m
610fi
611inAdb || die "specified device not in adb mode"
612isDebuggable || die "device not a debug build"
613enforcing=true
614if ! adb_su getenforce </dev/null | grep 'Enforcing' >/dev/null; then
615  echo "${ORANGE}[  WARNING ]${NORMAL} device does not have sepolicy in enforcing mode" >&2
616  enforcing=false
617fi
618
619# Do something.
620
621D=`get_property ro.serialno`
622[ -n "${D}" ] || D=`get_property ro.boot.serialno`
623[ -z "${D}" -o -n "${ANDROID_SERIAL}" ] || ANDROID_SERIAL=${D}
624USB_SERIAL=
625[ -z "${ANDROID_SERIAL}" ] || USB_SERIAL=`find /sys/devices -name serial |
626                                          grep usb |
627                                          xargs grep -l ${ANDROID_SERIAL}`
628USB_ADDRESS=
629if [ -n "${USB_SERIAL}" ]; then
630  USB_ADDRESS=${USB_SERIAL%/serial}
631  USB_ADDRESS=usb${USB_ADDRESS##*/}
632fi
633[ -z "${ANDROID_SERIAL}${USB_ADDRESS}" ] ||
634  echo "${BLUE}[     INFO ]${NORMAL}" ${ANDROID_SERIAL} ${USB_ADDRESS} >&2
635BUILD_DESCRIPTION=`get_property ro.build.description`
636[ -z "${BUILD_DESCRIPTION}" ] ||
637  echo "${BLUE}[     INFO ]${NORMAL} ${BUILD_DESCRIPTION}" >&2
638ACTIVE_SLOT=`get_active_slot`
639[ -z "${ACTIVE_SLOT}" ] ||
640  echo "${BLUE}[     INFO ]${NORMAL} active slot is ${ACTIVE_SLOT}" >&2
641
642# Report existing partition sizes
643adb_sh ls -l /dev/block/by-name/ </dev/null 2>/dev/null |
644  sed -n 's@.* \([^ ]*\) -> /dev/block/\([^ ]*\)$@\1 \2@p' |
645  while read name device; do
646    case ${name} in
647      system_[ab] | system | vendor_[ab] | vendor | super | cache)
648        case ${device} in
649          sd*)
650            device=${device%%[0-9]*}/${device}
651            ;;
652        esac
653        size=`adb_su cat /sys/block/${device}/size 2>/dev/null </dev/null` &&
654          size=`expr ${size} / 2` &&
655          echo "${BLUE}[     INFO ]${NORMAL} partition ${name} device ${device} size ${size}K" >&2
656        ;;
657    esac
658  done
659
660# Can we test remount -R command?
661overlayfs_supported=true
662if [ "orange" = "`get_property ro.boot.verifiedbootstate`" -a \
663     "2" = "`get_property partition.system.verified`" ]; then
664  restore() {
665    ${overlayfs_supported} || return 0
666    inFastboot &&
667      fastboot reboot &&
668      adb_wait 2m
669    inAdb &&
670      adb_root &&
671      adb enable-verity >/dev/null 2>/dev/null &&
672      adb_reboot &&
673      adb_wait 2m
674  }
675
676  echo "${GREEN}[ RUN      ]${NORMAL} Testing adb shell su root remount -R command" >&2
677
678  adb_su remount -R system </dev/null || true
679  sleep 2
680  adb_wait 2m ||
681    die "waiting for device after remount -R `usb_status`"
682  if [ "orange" != "`get_property ro.boot.verifiedbootstate`" -o \
683       "2" = "`get_property partition.system.verified`" ]; then
684    die "remount -R command failed"
685  fi
686
687  echo "${GREEN}[       OK ]${NORMAL} adb shell su root remount -R command" >&2
688fi
689
690echo "${GREEN}[ RUN      ]${NORMAL} Testing kernel support for overlayfs" >&2
691
692adb_wait || die "wait for device failed"
693adb_sh ls -d /sys/module/overlay </dev/null >/dev/null 2>/dev/null ||
694  adb_sh grep "nodev${TAB}overlay" /proc/filesystems </dev/null >/dev/null 2>/dev/null &&
695  echo "${GREEN}[       OK ]${NORMAL} overlay module present" >&2 ||
696  (
697    echo "${ORANGE}[  WARNING ]${NORMAL} overlay module not present" >&2 &&
698      false
699  ) ||
700  overlayfs_supported=false
701if ${overlayfs_supported}; then
702  adb_su ls /sys/module/overlay/parameters/override_creds </dev/null >/dev/null 2>/dev/null &&
703    echo "${GREEN}[       OK ]${NORMAL} overlay module supports override_creds" >&2 ||
704    case `adb_sh uname -r </dev/null` in
705      4.[456789].* | 4.[1-9][0-9]* | [56789].*)
706        echo "${ORANGE}[  WARNING ]${NORMAL} overlay module does not support override_creds" >&2 &&
707        overlayfs_supported=false
708        ;;
709      *)
710        echo "${GREEN}[       OK ]${NORMAL} overlay module uses caller's creds" >&2
711        ;;
712    esac
713fi
714
715adb_root ||
716  die "initial setup"
717
718echo "${GREEN}[ RUN      ]${NORMAL} Checking current overlayfs status" >&2
719
720# We can not universally use adb enable-verity to ensure device is
721# in a overlayfs disabled state since it can prevent reboot on
722# devices that remount the physical content rather than overlayfs.
723# So lets do our best to surgically wipe the overlayfs state without
724# having to go through enable-verity transition.
725reboot=false
726OVERLAYFS_BACKING="cache mnt/scratch"
727for d in ${OVERLAYFS_BACKING}; do
728  if adb_sh ls -d /${d}/overlay </dev/null >/dev/null 2>/dev/null; then
729    echo "${ORANGE}[  WARNING ]${NORMAL} /${d}/overlay is setup, surgically wiping" >&2
730    adb_sh rm -rf /${d}/overlay </dev/null ||
731      die "/${d}/overlay wipe"
732    reboot=true
733  fi
734done
735if ${reboot}; then
736  echo "${ORANGE}[  WARNING ]${NORMAL} rebooting before test" >&2
737  adb_reboot &&
738    adb_wait 2m ||
739    die "lost device after reboot after wipe `usb_status`"
740  adb_root ||
741    die "lost device after elevation to root after wipe `usb_status`"
742fi
743D=`adb_sh df -k </dev/null` &&
744  H=`echo "${D}" | head -1` &&
745  D=`echo "${D}" | grep -v " /vendor/..*$" | grep "^overlay "` &&
746  echo "${H}" &&
747  echo "${D}" &&
748  echo "${ORANGE}[  WARNING ]${NORMAL} overlays present before setup" >&2 ||
749  echo "${GREEN}[       OK ]${NORMAL} no overlay present before setup" >&2
750overlayfs_needed=true
751D=`adb_sh cat /proc/mounts </dev/null |
752   skip_administrative_mounts data`
753if echo "${D}" | grep /dev/root >/dev/null; then
754  D=`echo / /
755     echo "${D}" | grep -v /dev/root`
756fi
757D=`echo "${D}" | cut -s -d' ' -f1 | sort -u`
758no_dedupe=true
759for d in ${D}; do
760  adb_sh tune2fs -l $d </dev/null 2>&1 |
761    grep "Filesystem features:.*shared_blocks" >/dev/null &&
762  no_dedupe=false
763done
764D=`adb_sh df -k ${D} </dev/null |
765   sed 's@\([%] /\)\(apex\|bionic\|system\|vendor\)/[^ ][^ ]*$@\1@'`
766echo "${D}"
767if [ X"${D}" = X"${D##* 100[%] }" ] && ${no_dedupe} ; then
768  overlayfs_needed=false
769elif ! ${overlayfs_supported}; then
770  die "need overlayfs, but do not have it"
771fi
772
773echo "${GREEN}[ RUN      ]${NORMAL} disable verity" >&2
774
775T=`adb_date`
776H=`adb disable-verity 2>&1`
777err=${?}
778L=
779D="${H%?Now reboot your device for settings to take effect*}"
780if [ X"${D}" != X"${D##*[Uu]sing overlayfs}" ]; then
781  echo "${GREEN}[       OK ]${NORMAL} using overlayfs" >&2
782fi
783if [ ${err} != 0 ]; then
784  echo "${H}"
785  ( [ -n "${L}" ] && echo "${L}" && false ) ||
786  die -t "${T}" "disable-verity"
787fi
788rebooted=false
789if [ X"${D}" != X"${H}" ]; then
790  echo "${H}"
791  if [ X"${D}" != X"${D##*setup failed}" ]; then
792    echo "${ORANGE}[  WARNING ]${NORMAL} overlayfs setup whined" >&2
793  fi
794  D=`adb_sh df -k </dev/null` &&
795    H=`echo "${D}" | head -1` &&
796    D=`echo "${D}" | grep -v " /vendor/..*$" | grep "^overlay " || true` &&
797    [ -z "${D}" ] ||
798    ( echo "${H}" && echo "${D}" && false ) ||
799    die -t ${T} "overlay takeover unexpected at this phase"
800  echo "${GREEN}[     INFO ]${NORMAL} rebooting as requested" >&2
801  L=`adb_logcat -b all -v nsec -t ${T} 2>&1`
802  adb_reboot &&
803    adb_wait 2m ||
804    die "lost device after reboot requested `usb_status`"
805  adb_root ||
806    die "lost device after elevation to root `usb_status`"
807  rebooted=true
808  # re-disable verity to see the setup remarks expected
809  T=`adb_date`
810  H=`adb disable-verity 2>&1`
811  err=${?}
812  D="${H%?Now reboot your device for settings to take effect*}"
813  if [ X"${D}" != X"${D##*[Uu]sing overlayfs}" ]; then
814    echo "${GREEN}[       OK ]${NORMAL} using overlayfs" >&2
815  fi
816  if [ ${err} != 0 ]; then
817    T=
818  fi
819fi
820if ${overlayfs_supported} && ${overlayfs_needed} && [ X"${D}" != X"${D##*setup failed}" ]; then
821  echo "${D}"
822  ( [ -n "${L}" ] && echo "${L}" && false ) ||
823  die -t "${T}" "setup for overlay"
824fi
825if [ X"${D}" != X"${D##*Successfully disabled verity}" ]; then
826  echo "${H}"
827  D=`adb_sh df -k </dev/null` &&
828    H=`echo "${D}" | head -1` &&
829    D=`echo "${D}" | grep -v " /vendor/..*$" | grep "^overlay " || true` &&
830    [ -z "${D}" ] ||
831    ( echo "${H}" && echo "${D}" && false ) ||
832    ( [ -n "${L}" ] && echo "${L}" && false ) ||
833    die -t "${T}" "overlay takeover unexpected"
834  [ -n "${L}" ] && echo "${L}"
835  die -t "${T}" "unexpected report of verity being disabled a second time"
836elif ${rebooted}; then
837  echo "${GREEN}[       OK ]${NORMAL} verity already disabled" >&2
838else
839  echo "${ORANGE}[  WARNING ]${NORMAL} verity already disabled" >&2
840fi
841
842echo "${GREEN}[ RUN      ]${NORMAL} remount" >&2
843
844D=`adb remount 2>&1`
845ret=${?}
846echo "${D}"
847[ ${ret} != 0 ] ||
848  [ X"${D}" = X"${D##*remount failed}" ] ||
849  ( [ -n "${L}" ] && echo "${L}" && false ) ||
850  die -t "${T}" "adb remount failed"
851D=`adb_sh df -k </dev/null` &&
852  H=`echo "${D}" | head -1` &&
853  D=`echo "${D}" | skip_unrelated_mounts | grep "^overlay "` ||
854  ( [ -n "${L}" ] && echo "${L}" && false )
855ret=${?}
856uses_dynamic_scratch=false
857scratch_partition=
858if ${overlayfs_needed}; then
859  if [ ${ret} != 0 ]; then
860    die -t ${T} "overlay takeover failed"
861  fi
862  echo "${D}" | grep "^overlay .* /system\$" >/dev/null ||
863   echo "${ORANGE}[  WARNING ]${NORMAL} overlay takeover not complete" >&2
864  scratch_partition=scratch
865  if echo "${D}" | grep " /mnt/scratch" >/dev/null; then
866    echo "${BLUE}[     INFO ]${NORMAL} using ${scratch_partition} dynamic partition for overrides" >&2
867  fi
868  M=`adb_sh cat /proc/mounts </dev/null |
869     sed -n 's@\([^ ]*\) /mnt/scratch \([^ ]*\) .*@\2 on \1@p'`
870  [ -n "${M}" ] &&
871    echo "${BLUE}[     INFO ]${NORMAL} scratch filesystem ${M}"
872  uses_dynamic_scratch=true
873  if [ "${M}" != "${M##*/dev/block/by-name/}" ]; then
874    uses_dynamic_scratch=false
875    scratch_partition="${M##*/dev/block/by-name/}"
876  fi
877  scratch_size=`adb_sh df -k /mnt/scratch </dev/null 2>/dev/null |
878                while read device kblocks used available use mounted on; do
879                  if [ "/mnt/scratch" = "\${mounted}" ]; then
880                    echo \${kblocks}
881                  fi
882                done` &&
883    [ -n "${scratch_size}" ] ||
884    die "scratch size"
885  echo "${BLUE}[     INFO ]${NORMAL} scratch size ${scratch_size}KB" >&2
886  for d in ${OVERLAYFS_BACKING}; do
887    if adb_sh ls -d /${d}/overlay/system/upper </dev/null >/dev/null 2>/dev/null; then
888      echo "${BLUE}[     INFO ]${NORMAL} /${d}/overlay is setup" >&2
889    fi
890  done
891
892  echo "${H}" &&
893    echo "${D}" &&
894    echo "${D}" | grep "^overlay .* /system\$" >/dev/null ||
895    die  "overlay takeover after remount"
896  !(adb_sh grep "^overlay " /proc/mounts </dev/null |
897    skip_unrelated_mounts |
898    grep " overlay ro,") ||
899    die "remount overlayfs missed a spot (ro)"
900  D=`adb_sh grep " rw," /proc/mounts </dev/null |
901     skip_administrative_mounts data`
902  if echo "${D}" | grep /dev/root >/dev/null; then
903    D=`echo / /
904       echo "${D}" | grep -v /dev/root`
905  fi
906  D=`echo "${D}" | cut -s -d' ' -f1 | sort -u`
907  bad_rw=false
908  for d in ${D}; do
909    if adb_sh tune2fs -l $d </dev/null 2>&1 |
910       grep "Filesystem features:.*shared_blocks" >/dev/null; then
911      bad_rw=true
912    else
913      d=`adb_sh df -k ${D} </dev/null |
914       sed 's@\([%] /\)\(apex\|bionic\|system\|vendor\)/[^ ][^ ]*$@\1@'`
915      [ X"${d}" = X"${d##* 100[%] }" ] ||
916        bad_rw=true
917    fi
918  done
919  [ -z "${D}" ] ||
920    D=`adb_sh df -k ${D} </dev/null |
921       sed -e 's@\([%] /\)\(apex\|bionic\|system\|vendor\)/[^ ][^ ]*$@\1@' \
922           -e 's/^Filesystem      /Filesystem (rw) /'`
923  [ -z "${D}" ] || echo "${D}"
924  ${bad_rw} && die "remount overlayfs missed a spot (rw)"
925else
926  if [ ${ret} = 0 ]; then
927    die -t ${T} "unexpected overlay takeover"
928  fi
929fi
930
931# Check something.
932
933echo "${GREEN}[ RUN      ]${NORMAL} push content to /system and /vendor" >&2
934
935A="Hello World! $(date)"
936echo "${A}" | adb_sh cat - ">/system/hello"
937echo "${A}" | adb_sh cat - ">/vendor/hello"
938B="`adb_cat /system/hello`" ||
939  die "sytem hello"
940check_eq "${A}" "${B}" /system before reboot
941B="`adb_cat /vendor/hello`" ||
942  die "vendor hello"
943check_eq "${A}" "${B}" /vendor before reboot
944
945# Download libc.so, append some gargage, push back, and check if the file
946# is updated.
947tempdir="`mktemp -d`"
948cleanup() {
949  rm -rf ${tempdir}
950}
951adb pull /system/lib/bootstrap/libc.so ${tempdir} >/dev/null ||
952  die "pull libc.so from device"
953garbage="`hexdump -n 16 -e '4/4 "%08X" 1 "\n"' /dev/random`"
954echo ${garbage} >> ${tempdir}/libc.so
955adb push ${tempdir}/libc.so /system/lib/bootstrap/libc.so >/dev/null ||
956  die "push libc.so to device"
957adb pull /system/lib/bootstrap/libc.so ${tempdir}/libc.so.fromdevice >/dev/null ||
958  die "pull libc.so from device"
959diff ${tempdir}/libc.so ${tempdir}/libc.so.fromdevice > /dev/null ||
960  die "libc.so differ"
961
962echo "${GREEN}[ RUN      ]${NORMAL} reboot to confirm content persistent" >&2
963
964adb_reboot &&
965  adb_wait 2m ||
966  die "reboot after override content added failed `usb_status`"
967
968if ${overlayfs_needed}; then
969  D=`adb_su df -k </dev/null` &&
970    H=`echo "${D}" | head -1` &&
971    D=`echo "${D}" | grep -v " /vendor/..*$" | grep "^overlay "` ||
972    ( echo "${L}" && false ) ||
973    die -d "overlay takeover failed after reboot"
974
975  adb_su sed -n '1,/overlay \/system/p' /proc/mounts </dev/null |
976    skip_administrative_mounts |
977    grep -v ' \(erofs\|squashfs\|ext4\|f2fs\|vfat\) ' &&
978    echo "${ORANGE}[  WARNING ]${NORMAL} overlay takeover after first stage init" >&2 ||
979    echo "${GREEN}[       OK ]${NORMAL} overlay takeover in first stage init" >&2
980fi
981
982if ${enforcing}; then
983  adb_unroot ||
984    die "device not in unroot'd state"
985  B="`adb_cat /vendor/hello 2>&1`"
986  check_eq "cat: /vendor/hello: Permission denied" "${B}" vendor after reboot w/o root
987  echo "${GREEN}[       OK ]${NORMAL} /vendor content correct MAC after reboot" >&2
988fi
989B="`adb_cat /system/hello`"
990check_eq "${A}" "${B}" /system after reboot
991echo "${GREEN}[       OK ]${NORMAL} /system content remains after reboot" >&2
992# Only root can read vendor if sepolicy permissions are as expected.
993adb_root ||
994  die "adb root"
995B="`adb_cat /vendor/hello`"
996check_eq "${A}" "${B}" vendor after reboot
997echo "${GREEN}[       OK ]${NORMAL} /vendor content remains after reboot" >&2
998
999# Check if the updated libc.so is persistent after reboot.
1000adb_root &&
1001  adb pull /system/lib/bootstrap/libc.so ${tempdir}/libc.so.fromdevice >/dev/null ||
1002  die "pull libc.so from device"
1003diff ${tempdir}/libc.so ${tempdir}/libc.so.fromdevice > /dev/null || die "libc.so differ"
1004rm -rf ${tempdir}
1005cleanup() {
1006  true
1007}
1008echo "${GREEN}[       OK ]${NORMAL} /system/lib/bootstrap/libc.so content remains after reboot" >&2
1009
1010echo "${GREEN}[ RUN      ]${NORMAL} flash vendor, confirm its content disappears" >&2
1011
1012H=`adb_sh echo '${HOSTNAME}' </dev/null 2>/dev/null`
1013is_bootloader_fastboot=false
1014# cuttlefish?
1015[ X"${H}" != X"${H#vsoc}" ] || is_bootloader_fastboot=true
1016is_userspace_fastboot=false
1017
1018if ! ${is_bootloader_fastboot}; then
1019  echo "${ORANGE}[  WARNING ]${NORMAL} does not support fastboot, skipping"
1020elif [ -z "${ANDROID_PRODUCT_OUT}" ]; then
1021  echo "${ORANGE}[  WARNING ]${NORMAL} build tree not setup, skipping"
1022elif [ ! -s "${ANDROID_PRODUCT_OUT}/vendor.img" ]; then
1023  echo "${ORANGE}[  WARNING ]${NORMAL} vendor image missing, skipping"
1024elif [ "${ANDROID_PRODUCT_OUT}" = "${ANDROID_PRODUCT_OUT%*/${H}}" ]; then
1025  echo "${ORANGE}[  WARNING ]${NORMAL} wrong vendor image, skipping"
1026elif [ -z "${ANDROID_HOST_OUT}" ]; then
1027  echo "${ORANGE}[  WARNING ]${NORMAL} please run lunch, skipping"
1028else
1029  adb reboot fastboot ||
1030    die "fastbootd not supported (wrong adb in path?)"
1031  any_wait 2m &&
1032    inFastboot ||
1033    die "reboot into fastboot to flash vendor `usb_status` (bad bootloader?)"
1034  fastboot flash vendor ||
1035    ( fastboot reboot && false) ||
1036    die "fastboot flash vendor"
1037  fastboot_getvar is-userspace yes &&
1038    is_userspace_fastboot=true
1039  if [ -n "${scratch_paritition}" ]; then
1040    fastboot_getvar partition-type:${scratch_partition} raw ||
1041      ( fastboot reboot && false) ||
1042      die "fastboot can not see ${scratch_partition} parameters"
1043    if ${uses_dynamic_scratch}; then
1044      # check ${scratch_partition} via fastboot
1045      fastboot_getvar has-slot:${scratch_partition} no &&
1046        fastboot_getvar is-logical:${scratch_partition} yes ||
1047        ( fastboot reboot && false) ||
1048        die "fastboot can not see ${scratch_partition} parameters"
1049    else
1050      fastboot_getvar is-logical:${scratch_partition} no ||
1051        ( fastboot reboot && false) ||
1052        die "fastboot can not see ${scratch_partition} parameters"
1053    fi
1054    if ! ${uses_dynamic_scratch}; then
1055      fastboot reboot-bootloader ||
1056        die "Reboot into fastboot"
1057    fi
1058    if ${uses_dynamic_scratch}; then
1059      echo "${BLUE}[     INFO ]${NORMAL} expect fastboot erase ${scratch_partition} to fail" >&2
1060      fastboot erase ${scratch_partition} &&
1061        ( fastboot reboot || true) &&
1062        die "fastboot can erase ${scratch_partition}"
1063    fi
1064    echo "${BLUE}[     INFO ]${NORMAL} expect fastboot format ${scratch_partition} to fail" >&2
1065    fastboot format ${scratch_partition} &&
1066      ( fastboot reboot || true) &&
1067      die "fastboot can format ${scratch_partition}"
1068  fi
1069  fastboot reboot ||
1070    die "can not reboot out of fastboot"
1071  echo "${ORANGE}[  WARNING ]${NORMAL} adb after fastboot"
1072  adb_wait 2m ||
1073    die "did not reboot after flash `usb_status`"
1074  if ${overlayfs_needed}; then
1075    adb_root &&
1076      D=`adb_sh df -k </dev/null` &&
1077      H=`echo "${D}" | head -1` &&
1078      D=`echo "${D}" | skip_unrelated_mounts | grep "^overlay "` &&
1079      echo "${H}" &&
1080      echo "${D}" &&
1081      echo "${D}" | grep "^overlay .* /system\$" >/dev/null ||
1082      die  "overlay /system takeover after flash vendor"
1083    echo "${D}" | grep "^overlay .* /vendor\$" >/dev/null &&
1084      if ${is_userspace_fastboot}; then
1085        die  "overlay supposed to be minus /vendor takeover after flash vendor"
1086      else
1087        echo "${ORANGE}[  WARNING ]${NORMAL} user fastboot missing required to invalidate, ignoring a failure" >&2
1088        echo "${ORANGE}[  WARNING ]${NORMAL} overlay supposed to be minus /vendor takeover after flash vendor" >&2
1089      fi
1090  fi
1091  B="`adb_cat /system/hello`"
1092  check_eq "${A}" "${B}" system after flash vendor
1093  adb_root ||
1094    die "adb root"
1095  B="`adb_cat /vendor/hello`"
1096  if ${is_userspace_fastboot} || ! ${overlayfs_needed}; then
1097    check_eq "cat: /vendor/hello: No such file or directory" "${B}" \
1098             vendor content after flash vendor
1099  else
1100    echo "${ORANGE}[  WARNING ]${NORMAL} user fastboot missing required to invalidate, ignoring a failure" >&2
1101    check_eq "cat: /vendor/hello: No such file or directory" "${B}" \
1102             --warning vendor content after flash vendor
1103  fi
1104fi
1105
1106echo "${GREEN}[ RUN      ]${NORMAL} remove test content (cleanup)" >&2
1107
1108T=`adb_date`
1109H=`adb remount 2>&1`
1110err=${?}
1111L=
1112D="${H%?Now reboot your device for settings to take effect*}"
1113if [ X"${H}" != X"${D}" ]; then
1114  echo "${ORANGE}[  WARNING ]${NORMAL} adb remount requires a reboot after partial flash (legacy avb)"
1115  L=`adb_logcat -b all -v nsec -t ${T} 2>&1`
1116  adb_reboot &&
1117    adb_wait 2m &&
1118    adb_root ||
1119    die "failed to reboot"
1120  T=`adb_date`
1121  H=`adb remount 2>&1`
1122  err=${?}
1123fi
1124echo "${H}"
1125[ ${err} = 0 ] &&
1126  ( adb_sh rm /vendor/hello </dev/null 2>/dev/null || true ) &&
1127  adb_sh rm /system/hello </dev/null ||
1128  ( [ -n "${L}" ] && echo "${L}" && false ) ||
1129  die -t ${T} "cleanup hello"
1130B="`adb_cat /system/hello`"
1131check_eq "cat: /system/hello: No such file or directory" "${B}" after rm
1132B="`adb_cat /vendor/hello`"
1133check_eq "cat: /vendor/hello: No such file or directory" "${B}" after rm
1134
1135if [ -n "${scratch_partition}" ]; then
1136
1137  echo "${GREEN}[ RUN      ]${NORMAL} test fastboot flash to ${scratch_partition} recovery" >&2
1138
1139  adb reboot fastboot ||
1140    die "Reboot into fastbootd"
1141  img=${TMPDIR}/adb-remount-test-${$}.img
1142  cleanup() {
1143    rm ${img}
1144  }
1145  dd if=/dev/zero of=${img} bs=4096 count=16 2>/dev/null &&
1146    fastboot_wait 2m ||
1147    die "reboot into fastboot `usb_status`"
1148  fastboot flash --force ${scratch_partition} ${img}
1149  err=${?}
1150  cleanup
1151  cleanup() {
1152    true
1153  }
1154  fastboot reboot ||
1155    die "can not reboot out of fastboot"
1156  [ 0 -eq ${err} ] ||
1157    die "fastboot flash ${scratch_partition}"
1158  adb_wait 2m &&
1159    adb_root ||
1160    die "did not reboot after flash"
1161  T=`adb_date`
1162  D=`adb disable-verity 2>&1`
1163  err=${?}
1164  if [ X"${D}" != "${D%?Now reboot your device for settings to take effect*}" ]
1165  then
1166    echo "${ORANGE}[  WARNING ]${NORMAL} adb disable-verity requires a reboot after partial flash"
1167    adb_reboot &&
1168      adb_wait 2m &&
1169      adb_root ||
1170      die "failed to reboot"
1171    T=`adb_date`
1172    D="${D}
1173`adb disable-verity 2>&1`"
1174    err=${?}
1175  fi
1176
1177  echo "${D}"
1178  [ ${err} = 0 ] &&
1179    [ X"${D}" = X"${D##*setup failed}" ] &&
1180    [ X"${D}" != X"${D##*[Uu]sing overlayfs}" ] &&
1181    echo "${GREEN}[       OK ]${NORMAL} ${scratch_partition} recreated" >&2 ||
1182    die -t ${T} "setup for overlayfs"
1183  D=`adb remount 2>&1`
1184  err=${?}
1185  echo "${D}"
1186  [ ${err} != 0 ] ||
1187    [ X"${D}" = X"${D##*remount failed}" ] ||
1188    ( echo "${D}" && false ) ||
1189    die -t ${T} "remount failed"
1190fi
1191
1192echo "${GREEN}[ RUN      ]${NORMAL} test raw remount commands" >&2
1193
1194# Prerequisite is a prepped device from above.
1195adb_reboot &&
1196  adb_wait 2m ||
1197  die "lost device after reboot to ro state `usb_status`"
1198adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null &&
1199  die "/vendor is not read-only"
1200adb_su mount -o rw,remount /vendor </dev/null ||
1201  die "remount command"
1202adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null ||
1203  die "/vendor is not read-write"
1204echo "${GREEN}[       OK ]${NORMAL} mount -o rw,remount command works" >&2
1205
1206# Prerequisite is a prepped device from above.
1207adb_reboot &&
1208  adb_wait 2m ||
1209  die "lost device after reboot to ro state (USB stack broken?)"
1210adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null &&
1211  die "/vendor is not read-only"
1212adb_su remount vendor </dev/null ||
1213  die "remount command"
1214adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null ||
1215  die "/vendor is not read-write"
1216adb_sh grep " /system .* rw," /proc/mounts >/dev/null </dev/null &&
1217  die "/vendor is not read-only"
1218echo "${GREEN}[       OK ]${NORMAL} remount command works from setup" >&2
1219
1220# Prerequisite is an overlayfs deconstructed device but with verity disabled.
1221# This also saves a lot of 'noise' from the command doing a mkfs on backing
1222# storage and all the related tuning and adjustment.
1223for d in ${OVERLAYFS_BACKING}; do
1224  adb_su rm -rf /${d}/overlay </dev/null ||
1225    die "/${d}/overlay wipe"
1226done
1227adb_reboot &&
1228  adb_wait 2m ||
1229  die "lost device after reboot after wipe (USB stack broken?)"
1230adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null &&
1231  die "/vendor is not read-only"
1232adb_su remount vendor </dev/null ||
1233  die "remount command"
1234adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null ||
1235  die "/vendor is not read-write"
1236adb_sh grep " /system .* rw," /proc/mounts >/dev/null </dev/null &&
1237  die "/system is not read-only"
1238echo "${GREEN}[       OK ]${NORMAL} remount command works from scratch" >&2
1239
1240restore
1241err=${?}
1242
1243if [ ${err} = 0 ] && ${overlayfs_supported}; then
1244  echo "${GREEN}[ RUN      ]${NORMAL} test 'adb remount -R'" >&2
1245  adb_root &&
1246    adb remount -R &&
1247    adb_wait 2m ||
1248    die "adb remount -R"
1249  if [ "orange" != "`get_property ro.boot.verifiedbootstate`" -o \
1250       "2" = "`get_property partition.system.verified`" ]; then
1251    die "remount -R command failed to disable verity"
1252  fi
1253
1254  echo "${GREEN}[       OK ]${NORMAL} 'adb remount -R' command" >&2
1255
1256  restore
1257  err=${?}
1258fi
1259
1260restore() {
1261  true
1262}
1263
1264[ ${err} = 0 ] ||
1265  die "failed to restore verity" >&2
1266
1267echo "${GREEN}[  PASSED  ]${NORMAL} adb remount" >&2
1268
1269test_duration
1270