From 89b88b4e2d69132012c6096415dc64b695a84da3 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Tue, 22 Jan 2019 14:05:32 -0800 Subject: [PATCH 1/4] fs_mgr: overlayfs: validate that kernel supports scratch filesystem Check for /sys/fs/ existence to confirm kernel has the file system type available. Test: adb-remount-test.sh Bug: 109821005 Bug: 123079041 Change-Id: Ic4388e2044bccea8b8edc7762d4ac9b3047206ac --- fs_mgr/fs_mgr_overlayfs.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp index 390868311..89d1d829d 100644 --- a/fs_mgr/fs_mgr_overlayfs.cpp +++ b/fs_mgr/fs_mgr_overlayfs.cpp @@ -626,8 +626,8 @@ 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)) return "f2fs"; - if (!access(kMkExt4.c_str(), X_OK)) return "ext4"; + 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"; return "auto"; } @@ -829,8 +829,9 @@ bool fs_mgr_overlayfs_mount_all(Fstab* fstab) { true /* readonly */)) { auto has_overlayfs_dir = fs_mgr_access(kScratchMountPoint + kOverlayTopDir); fs_mgr_overlayfs_umount_scratch(); - if (has_overlayfs_dir) + if (has_overlayfs_dir) { fs_mgr_overlayfs_mount_scratch(scratch_device, mount_type); + } } } } From 3fe0a8164d135ea5b67f93fab6691b550a53d8be Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Tue, 22 Jan 2019 14:27:59 -0800 Subject: [PATCH 2/4] fs_mgr: overlayfs: test: check for ext4 dedupe needing overlay Check if any system partition looks like it has ext dedupe or rather shared_blocks feature enabled, if so then we expect overlayfs to kick in. We do this to deal with any flakiness in the test when right-sizing is not applied to the platform. Minor: older devices mounted persist to /persist. Test: adb-remount-test.sh Bug: 109821005 Bug: 123079041 Change-Id: Iab7c6cf7f24f2c446aeb149e3f65d6793a42c6ea --- fs_mgr/tests/adb-remount-test.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh index 0765f04a2..98e4e29a2 100755 --- a/fs_mgr/tests/adb-remount-test.sh +++ b/fs_mgr/tests/adb-remount-test.sh @@ -309,7 +309,7 @@ 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 " /\(cache\|mnt/scratch\|mnt/vendor/persist\|metadata\) " + -e " /\(cache\|mnt/scratch\|mnt/vendor/persist\|persist\|metadata\) " } if [ X"-s" = X"${1}" -a -n "${2}" ]; then @@ -403,9 +403,15 @@ if echo "${D}" | grep /dev/root >/dev/null; then echo "${D}" | grep -v /dev/root` fi D=`echo "${D}" | cut -s -d' ' -f1 | sort -u` +no_dedupe=true +for d in ${D}; do + adb_sh tune2fs -l $d 2>&1 | + grep "Filesystem features:.*shared_blocks" >/dev/null && + no_dedupe=false +done D=`adb_sh df -k ${D} Date: Tue, 22 Jan 2019 14:49:44 -0800 Subject: [PATCH 3/4] fs_mgr: overlayfs: test: check for existence of userspace fastboot If there is no userspace fastboot, then overlayfs has a corner case bug where overlay content is not wiped when the partition is flashed. We will report a warning instead. This is done to reduce the flakiness of the test results as we do not intend to fix this specific corner case in the short term. We would require to record a sha representing the flash image, and the risks were evaluated as too high of an impact on libavb to add interfaces to expose the signatures, especially at first stage mount time. All new devices must support Dynamic Android Partitions (DAP), which means they all have support for userspace fastboot, it will be considered a misconfiguration and thus the position is we will not fix this issue and only use this test adjustment to deal with legacy products. If a legacy non-DAP product wishes to close the issue today, they must supply a user space fastboot. Test: adb-remount-test.sh Bug: 109821005 Bug: 123079041 Change-Id: I420cb87c19e3e184a974dfc373fb17c097d4858f --- fs_mgr/tests/adb-remount-test.sh | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh index 98e4e29a2..42f3f2903 100755 --- a/fs_mgr/tests/adb-remount-test.sh +++ b/fs_mgr/tests/adb-remount-test.sh @@ -603,6 +603,7 @@ echo "${GREEN}[ OK ]${NORMAL} /vendor content remains after reboot" >&2 echo "${GREEN}[ RUN ]${NORMAL} flash vendor, confirm its content disappears" >&2 H=`adb_sh echo '${HOSTNAME}' /dev/null` +is_userspace_fastboot=false if [ -z "${ANDROID_PRODUCT_OUT}" ]; then echo "${ORANGE}[ WARNING ]${NORMAL} build tree not setup, skipping" elif [ ! -s "${ANDROID_PRODUCT_OUT}/vendor.img" ]; then @@ -615,6 +616,8 @@ else fastboot flash vendor || ( fastboot reboot && false) || die "fastboot flash vendor" + fastboot_getvar is-userspace yes && + is_userspace_fastboot=true if [ -n "${scratch_paritition}" ]; then fastboot_getvar partition-type:${scratch_partition} raw || ( fastboot reboot && false) || @@ -660,7 +663,12 @@ else echo "${D}" | grep "^overlay .* /system\$" >/dev/null || die "overlay /system takeover after flash vendor" echo "${D}" | grep "^overlay .* /vendor\$" >/dev/null && - die "overlay supposed to be minus /vendor takeover after flash vendor" + 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" ) + fi fi B="`adb_cat /system/hello`" || die "re-read /system/hello after flash vendor" @@ -668,8 +676,17 @@ else adb_root || die "adb root" B="`adb_cat /vendor/hello`" && - die "re-read /vendor/hello after flash vendor" - check_eq "cat: /vendor/hello: No such file or directory" "${B}" vendor after flash vendor + 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" ) + fi + if ${is_userspace_fastboot} || ! ${overlayfs_needed}; then + check_eq "cat: /vendor/hello: No such file or directory" "${B}" vendor after flash vendor + else + ( check_eq "cat: /vendor/hello: No such file or directory" "${B}" vendor after flash vendor ) + fi fi echo "${GREEN}[ RUN ]${NORMAL} remove test content (cleanup)" >&2 From 264b7dfa5e8a2bbc34001ec8d96f545ff21615a6 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Tue, 22 Jan 2019 11:24:13 -0800 Subject: [PATCH 4/4] fs_mgr: overlay: support non-DAP A/B devices Loosen some tests and borrow logic from retrofit Dynamic Android Partitions (DAP) A/B devices. In non-DAP A/B device case /mnt/scratch is used, backed by the system other partition. Tested on taimen with CONFIG_OVERLAY_FS added to its pre 4.6 kernel, and BOARD_EXT4_SHARE_DUP_BLOCKS := true added to board config. Also tested on a retrofit DAP A/B device and an untouched taimen. Test: adb_remount_test.sh Bug: 120448575 Change-Id: I72aaf4d68db1c3ac380aba425346ab6443cadad3 --- fs_mgr/fs_mgr_overlayfs.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp index 89d1d829d..2c4299a25 100644 --- a/fs_mgr/fs_mgr_overlayfs.cpp +++ b/fs_mgr/fs_mgr_overlayfs.cpp @@ -642,7 +642,11 @@ std::string fs_mgr_overlayfs_scratch_device() { // Create from within single super device; auto& dm = DeviceMapper::Instance(); const auto partition_name = android::base::Basename(kScratchMountPoint); - if (!dm.GetDmDevicePathByName(partition_name, &path)) return ""; + if (!dm.GetDmDevicePathByName(partition_name, &path)) { + // non-DAP A/B device? + if (fs_mgr_access(super_device)) return ""; + path = kPhysicalDevice + "system" + (slot_number ? "_a" : "_b"); + } } return scratch_device_cache = path; } @@ -883,10 +887,6 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* for (const auto& overlay_mount_point : kOverlayMountPoints) { if (backing && backing[0] && (overlay_mount_point != backing)) continue; if (overlay_mount_point == kScratchMountPoint) { - if (!fs_mgr_rw_access(fs_mgr_overlayfs_super_device(fs_mgr_overlayfs_slot_number())) || - !fs_mgr_overlayfs_has_logical(fstab)) { - continue; - } if (!fs_mgr_overlayfs_setup_scratch(fstab, change)) continue; } else { if (std::find_if(fstab.begin(), fstab.end(), [&overlay_mount_point](const auto& entry) {