From e8ccb88addfae09c98fb7a6a77c7797ad477bffb Mon Sep 17 00:00:00 2001 From: Simon Shields Date: Wed, 2 Oct 2019 00:21:45 +1000 Subject: [PATCH] recovery_utils: add support for unmounting entire volumes When wiping /system, the partition isn't actually mounted at /system or / - it's mounted at /mnt/system. This breaks 'format system' from recovery if the partition has been mounted. This patch adds an ensure_volume_unmounted function that finds all mounts of a given device and unmounts them, meaning the device can be safely formatted. Change-Id: Id4f727f845308a89e865f1ba60dc284f5ebc66e1 --- install/wipe_data.cpp | 6 ++++- recovery_utils/include/recovery_utils/roots.h | 4 ++++ recovery_utils/roots.cpp | 22 +++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/install/wipe_data.cpp b/install/wipe_data.cpp index 0f57384a..34e70b7e 100644 --- a/install/wipe_data.cpp +++ b/install/wipe_data.cpp @@ -48,7 +48,11 @@ static bool EraseVolume(const char* volume, RecoveryUI* ui, std::string_view new ui->Print("Formatting %s...\n", volume); - ensure_path_unmounted(volume); + Volume* vol = volume_for_mount_point(volume); + if (ensure_volume_unmounted(vol->blk_device) == -1) { + PLOG(ERROR) << "Failed to unmount volume!"; + return false; + } int result = format_volume(volume, "", new_fstype); diff --git a/recovery_utils/include/recovery_utils/roots.h b/recovery_utils/include/recovery_utils/roots.h index 6afefb81..d88fe564 100644 --- a/recovery_utils/include/recovery_utils/roots.h +++ b/recovery_utils/include/recovery_utils/roots.h @@ -39,6 +39,10 @@ int ensure_path_mounted_at(const std::string& path, const std::string& mount_poi // success (volume is unmounted); int ensure_path_unmounted(const std::string& path); +// Make sure that the volume at 'blk_device' is unmounted. +// Returns 0 on success. +int ensure_volume_unmounted(const std::string& blk_device); + // Reformat the given volume (must be the mount point only, eg // "/cache"), no paths permitted. Attempts to unmount the volume if // it is mounted. diff --git a/recovery_utils/roots.cpp b/recovery_utils/roots.cpp index e7a7d652..1ecb8db0 100644 --- a/recovery_utils/roots.cpp +++ b/recovery_utils/roots.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -89,6 +90,27 @@ int ensure_path_unmounted(const std::string& path) { return android::fs_mgr::EnsurePathUnmounted(&fstab, path) ? 0 : -1; } +int ensure_volume_unmounted(const std::string& blk_device) { + android::fs_mgr::Fstab mounted_fstab; + if (!android::fs_mgr::ReadFstabFromFile("/proc/mounts", &mounted_fstab)) { + LOG(ERROR) << "Failed to read /proc/mounts"; + return -1; + } + + /* find any entries with the volume */ + for (auto& entry : mounted_fstab) { + if (entry.blk_device == blk_device) { + int result = umount(entry.mount_point.c_str()); + if (result == -1) { + LOG(ERROR) << "Failed to unmount " << blk_device << " from " << entry.mount_point << ": " + << errno; + return -1; + } + } + } + return 0; +} + static int exec_cmd(const std::vector& args) { CHECK(!args.empty()); auto argv = StringVectorToNullTerminatedArray(args);