fs_mgr: Add OverlayMountPoints() to get the list of overlayfs backing storage

Remove kOverlayMountPoints; add OverlayMountPoints().

Fix a regression where if host system didn't install a scratch_gsi
partition and physical /cache partition is mounted, then DSU guest
system could use /cache as its overlayfs backing storage. This is
generally unwanted as the /cache partition could be shared between host
and guest.
Dynamically return the list of overlayfs backing storage candidates, so
we don't accidentally fall back to use /cache storage within a DSU
system.

Bug: 165925766
Bug: 179980369
Test: 1. Prepare a DUT that have a physical cache partition, such as
  cuttlefish.
  2. Install a DSU system, and unsure that scratch_gsi is not installed.
  3. Reboot into DSU, verify that adb remount fails and overlayfs
     scratch is not created under /cache.
Change-Id: I1815ac5367c0aac8614aeaabebe0e2cb91cbe161
This commit is contained in:
Yi-Yo Chiang 2021-02-11 22:59:11 +08:00 committed by Yo Chiang
parent 9e22a46db9
commit d1ff1bcfbc

View file

@ -125,10 +125,38 @@ void TeardownAllOverlayForMountPoint(const std::string&) {}
namespace {
bool fs_mgr_in_recovery() {
// Check the existence of recovery binary instead of using the compile time
// macro, because first-stage-init is compiled with __ANDROID_RECOVERY__
// defined, albeit not in recovery. More details: system/core/init/README.md
return fs_mgr_access("/system/bin/recovery");
}
bool fs_mgr_is_dsu_running() {
// Since android::gsi::CanBootIntoGsi() or android::gsi::MarkSystemAsGsi() is
// never called in recovery, the return value of android::gsi::IsGsiRunning()
// is not well-defined. In this case, just return false as being in recovery
// implies not running a DSU system.
if (fs_mgr_in_recovery()) return false;
auto saved_errno = errno;
auto ret = android::gsi::IsGsiRunning();
errno = saved_errno;
return ret;
}
// list of acceptable overlayfs backing storage
const auto kScratchMountPoint = "/mnt/scratch"s;
const auto kCacheMountPoint = "/cache"s;
const std::vector<const std::string> kOverlayMountPoints = {kScratchMountPoint, kCacheMountPoint};
std::vector<const std::string> OverlayMountPoints() {
// Never fallback to legacy cache mount point if within a DSU system,
// because running a DSU system implies the device supports dynamic
// partitions, which means legacy cache mustn't be used.
if (fs_mgr_is_dsu_running()) {
return {kScratchMountPoint};
}
return {kScratchMountPoint, kCacheMountPoint};
}
// Return true if everything is mounted, but before adb is started. Right
// after 'trigger load_persist_props_action' is done.
@ -169,25 +197,6 @@ bool fs_mgr_filesystem_has_space(const std::string& mount_point) {
(vst.f_bfree * vst.f_bsize) >= kSizeThreshold;
}
bool fs_mgr_in_recovery() {
// Check the existence of recovery binary instead of using the compile time
// macro, because first-stage-init is compiled with __ANDROID_RECOVERY__
// defined, albeit not in recovery. More details: system/core/init/README.md
return fs_mgr_access("/system/bin/recovery");
}
bool fs_mgr_is_dsu_running() {
// Since android::gsi::CanBootIntoGsi() or android::gsi::MarkSystemAsGsi() is
// never called in recovery, the return value of android::gsi::IsGsiRunning()
// is not well-defined. In this case, just return false as being in recovery
// implies not running a DSU system.
if (fs_mgr_in_recovery()) return false;
auto saved_errno = errno;
auto ret = android::gsi::IsGsiRunning();
errno = saved_errno;
return ret;
}
const auto kPhysicalDevice = "/dev/block/by-name/"s;
constexpr char kScratchImageMetadata[] = "/metadata/gsi/remount/lp_metadata";
@ -300,7 +309,7 @@ const auto kOverlayTopDir = "/overlay"s;
std::string fs_mgr_get_overlayfs_candidate(const std::string& mount_point) {
if (!fs_mgr_is_dir(mount_point)) return "";
const auto base = android::base::Basename(mount_point) + "/";
for (const auto& overlay_mount_point : kOverlayMountPoints) {
for (const auto& overlay_mount_point : OverlayMountPoints()) {
auto dir = overlay_mount_point + kOverlayTopDir + "/" + base;
auto upper = dir + kUpperName;
if (!fs_mgr_is_dir(upper)) continue;
@ -1344,7 +1353,7 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool*
if (candidates.empty()) return ret;
std::string dir;
for (const auto& overlay_mount_point : kOverlayMountPoints) {
for (const auto& overlay_mount_point : OverlayMountPoints()) {
if (backing && backing[0] && (overlay_mount_point != backing)) continue;
if (overlay_mount_point == kScratchMountPoint) {
if (!fs_mgr_overlayfs_setup_scratch(fstab, change)) continue;
@ -1465,7 +1474,7 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) {
}
}
bool should_destroy_scratch = false;
for (const auto& overlay_mount_point : kOverlayMountPoints) {
for (const auto& overlay_mount_point : OverlayMountPoints()) {
ret &= fs_mgr_overlayfs_teardown_one(
overlay_mount_point, mount_point ? fs_mgr_mount_point(mount_point) : "", change,
overlay_mount_point == kScratchMountPoint ? &should_destroy_scratch : nullptr);
@ -1569,7 +1578,7 @@ void TeardownAllOverlayForMountPoint(const std::string& mount_point) {
constexpr bool* ignore_change = nullptr;
// Teardown legacy overlay mount points that's not backed by a scratch device.
for (const auto& overlay_mount_point : kOverlayMountPoints) {
for (const auto& overlay_mount_point : OverlayMountPoints()) {
if (overlay_mount_point == kScratchMountPoint) {
continue;
}