Merge changes from topic "dsu-overlayfs" am: 65f4f4359d am: 7d485cec05

Original change: https://android-review.googlesource.com/c/platform/system/core/+/1476596

Change-Id: I39947f6add6970db9ba456a4681357d4ccadcc38
This commit is contained in:
Yo Chiang 2020-11-04 04:09:56 +00:00 committed by Automerger Merge Worker
commit 16a46362c4
3 changed files with 80 additions and 50 deletions

View file

@ -67,7 +67,7 @@ void WipeOverlayfsForPartition(FastbootDevice* device, const std::string& partit
if ((partition + device->GetCurrentSlot()) == partition_name) { if ((partition + device->GetCurrentSlot()) == partition_name) {
mount_metadata.emplace(); mount_metadata.emplace();
fs_mgr_overlayfs_teardown(entry.mount_point.c_str()); android::fs_mgr::TeardownAllOverlayForMountPoint(entry.mount_point);
} }
} }
} }
@ -194,7 +194,7 @@ bool UpdateSuper(FastbootDevice* device, const std::string& super_name, bool wip
if (!FlashPartitionTable(super_name, *new_metadata.get())) { if (!FlashPartitionTable(super_name, *new_metadata.get())) {
return device->WriteFail("Unable to flash new partition table"); return device->WriteFail("Unable to flash new partition table");
} }
fs_mgr_overlayfs_teardown(); android::fs_mgr::TeardownAllOverlayForMountPoint();
sync(); sync();
return device->WriteOkay("Successfully flashed partition table"); return device->WriteOkay("Successfully flashed partition table");
} }
@ -234,7 +234,7 @@ bool UpdateSuper(FastbootDevice* device, const std::string& super_name, bool wip
if (!UpdateAllPartitionMetadata(device, super_name, *new_metadata.get())) { if (!UpdateAllPartitionMetadata(device, super_name, *new_metadata.get())) {
return device->WriteFail("Unable to write new partition table"); return device->WriteFail("Unable to write new partition table");
} }
fs_mgr_overlayfs_teardown(); android::fs_mgr::TeardownAllOverlayForMountPoint();
sync(); sync();
return device->WriteOkay("Successfully updated partition table"); return device->WriteOkay("Successfully updated partition table");
} }

View file

@ -132,8 +132,11 @@ bool fs_mgr_overlayfs_is_setup() {
namespace android { namespace android {
namespace fs_mgr { namespace fs_mgr {
void MapScratchPartitionIfNeeded(Fstab*, void MapScratchPartitionIfNeeded(Fstab*, const std::function<bool(const std::set<std::string>&)>&) {
const std::function<bool(const std::set<std::string>&)>&) {} }
void TeardownAllOverlayForMountPoint(const std::string&) {}
} // namespace fs_mgr } // namespace fs_mgr
} // namespace android } // namespace android
@ -1376,6 +1379,11 @@ static bool EnsureScratchMapped(std::string* device, bool* mapped) {
return true; return true;
} }
if (!fs_mgr_in_recovery()) {
errno = EINVAL;
return false;
}
auto partition_name = android::base::Basename(kScratchMountPoint); auto partition_name = android::base::Basename(kScratchMountPoint);
// Check for scratch on /data first, before looking for a modified super // Check for scratch on /data first, before looking for a modified super
@ -1417,47 +1425,28 @@ static bool EnsureScratchMapped(std::string* device, bool* mapped) {
return true; return true;
} }
static void UnmapScratchDevice() { // This should only be reachable in recovery, where DSU scratch is not
// This should only be reachable in recovery, where scratch is not // automatically mapped.
// automatically mapped and therefore can be unmapped. static bool MapDsuScratchDevice(std::string* device) {
DestroyLogicalPartition(android::base::Basename(kScratchMountPoint));
}
#if !defined __ANDROID_RECOVERY__
// Provide stubs for non-recovery variant.
static void fs_mgr_overlayfs_teardown_dsu(const char*) {}
#else
// Note: This should only be called from recovery or fastbootd.
static void fs_mgr_overlayfs_teardown_dsu(const char* mount_point) {
std::string dsu_slot; std::string dsu_slot;
if (!android::gsi::IsGsiInstalled() || !android::gsi::GetActiveDsu(&dsu_slot) || if (!android::gsi::IsGsiInstalled() || !android::gsi::GetActiveDsu(&dsu_slot) ||
dsu_slot.empty()) { dsu_slot.empty()) {
// Nothing to do if no DSU installation present. // Nothing to do if no DSU installation present.
return; return false;
} }
auto images = IImageManager::Open("dsu/" + dsu_slot, 10s); auto images = IImageManager::Open("dsu/" + dsu_slot, 10s);
if (!images || !images->BackingImageExists(android::gsi::kDsuScratch)) { if (!images || !images->BackingImageExists(android::gsi::kDsuScratch)) {
// Nothing to do if DSU scratch device doesn't exist. // Nothing to do if DSU scratch device doesn't exist.
return; return false;
}
std::string scratch_device;
images->UnmapImageDevice(android::gsi::kDsuScratch);
if (!images->MapImageDevice(android::gsi::kDsuScratch, 10s, &scratch_device)) {
return;
}
fs_mgr_overlayfs_umount_scratch();
if (fs_mgr_overlayfs_mount_scratch(scratch_device, fs_mgr_overlayfs_scratch_mount_type())) {
fs_mgr_overlayfs_teardown_one(kScratchMountPoint,
mount_point ? fs_mgr_mount_point(mount_point) : "", nullptr);
fs_mgr_overlayfs_umount_scratch();
} }
images->UnmapImageDevice(android::gsi::kDsuScratch); images->UnmapImageDevice(android::gsi::kDsuScratch);
if (!images->MapImageDevice(android::gsi::kDsuScratch, 10s, device)) {
return false;
}
return true;
} }
#endif
// Returns false if teardown not permitted, errno set to last error. // Returns false if teardown not permitted, errno set to last error.
// If something is altered, set *change. // If something is altered, set *change.
@ -1468,10 +1457,9 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) {
// If scratch exists, but is not mounted, lets gain access to clean // If scratch exists, but is not mounted, lets gain access to clean
// specific override entries. // specific override entries.
auto mount_scratch = false; auto mount_scratch = false;
bool unmap = false;
if ((mount_point != nullptr) && !fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) { if ((mount_point != nullptr) && !fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) {
std::string scratch_device; std::string scratch_device = GetBootScratchDevice();
if (EnsureScratchMapped(&scratch_device, &unmap)) { if (!scratch_device.empty()) {
mount_scratch = fs_mgr_overlayfs_mount_scratch(scratch_device, mount_scratch = fs_mgr_overlayfs_mount_scratch(scratch_device,
fs_mgr_overlayfs_scratch_mount_type()); fs_mgr_overlayfs_scratch_mount_type());
} }
@ -1485,15 +1473,11 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) {
// Do not attempt to destroy DSU scratch if within a DSU system, // Do not attempt to destroy DSU scratch if within a DSU system,
// because DSU scratch partition is managed by gsid. // because DSU scratch partition is managed by gsid.
if (should_destroy_scratch && !fs_mgr_is_dsu_running()) { if (should_destroy_scratch && !fs_mgr_is_dsu_running()) {
// Note: Reaching here in recovery or fastbootd means that a scratch device
// is mounted and cleaned up. Such scratch device mustn't be the DSU scratch,
// because EnsureScratchMapped() is not allowed to map the DSU scratch in
// recovery. In other words, it is safe to destroy the scratch device here.
ret &= fs_mgr_overlayfs_teardown_scratch(kScratchMountPoint, change); ret &= fs_mgr_overlayfs_teardown_scratch(kScratchMountPoint, change);
} }
if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) { if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) {
// After obligatory teardown to make sure everything is clean, but if // After obligatory teardown to make sure everything is clean, but if
// we didn't want overlayfs in the the first place, we do not want to // we didn't want overlayfs in the first place, we do not want to
// waste time on a reboot (or reboot request message). // waste time on a reboot (or reboot request message).
if (change) *change = false; if (change) *change = false;
} }
@ -1507,15 +1491,6 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) {
if (mount_scratch) { if (mount_scratch) {
fs_mgr_overlayfs_umount_scratch(); fs_mgr_overlayfs_umount_scratch();
} }
if (unmap) {
UnmapScratchDevice();
}
if (fs_mgr_in_recovery()) {
// Destroy DSU overlay if present.
fs_mgr_overlayfs_teardown_dsu(mount_point);
}
return ret; return ret;
} }
@ -1583,6 +1558,54 @@ void CleanupOldScratchFiles() {
} }
} }
void TeardownAllOverlayForMountPoint(const std::string& mount_point) {
if (!fs_mgr_in_recovery()) {
LERROR << __FUNCTION__ << "(): must be called within recovery.";
return;
}
// Empty string means teardown everything.
const std::string teardown_dir = mount_point.empty() ? "" : fs_mgr_mount_point(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) {
if (overlay_mount_point == kScratchMountPoint) {
continue;
}
fs_mgr_overlayfs_teardown_one(overlay_mount_point, teardown_dir, ignore_change);
}
// Map scratch device, mount kScratchMountPoint and teardown kScratchMountPoint.
bool mapped = false;
std::string scratch_device;
if (EnsureScratchMapped(&scratch_device, &mapped)) {
fs_mgr_overlayfs_umount_scratch();
if (fs_mgr_overlayfs_mount_scratch(scratch_device, fs_mgr_overlayfs_scratch_mount_type())) {
bool should_destroy_scratch = false;
fs_mgr_overlayfs_teardown_one(kScratchMountPoint, teardown_dir, ignore_change,
&should_destroy_scratch);
if (should_destroy_scratch) {
fs_mgr_overlayfs_teardown_scratch(kScratchMountPoint, nullptr);
}
fs_mgr_overlayfs_umount_scratch();
}
if (mapped) {
DestroyLogicalPartition(android::base::Basename(kScratchMountPoint));
}
}
// Teardown DSU overlay if present.
if (MapDsuScratchDevice(&scratch_device)) {
fs_mgr_overlayfs_umount_scratch();
if (fs_mgr_overlayfs_mount_scratch(scratch_device, fs_mgr_overlayfs_scratch_mount_type())) {
fs_mgr_overlayfs_teardown_one(kScratchMountPoint, teardown_dir, ignore_change);
fs_mgr_overlayfs_umount_scratch();
}
DestroyLogicalPartition(android::gsi::kDsuScratch);
}
}
} // namespace fs_mgr } // namespace fs_mgr
} // namespace android } // namespace android

View file

@ -49,5 +49,12 @@ void MapScratchPartitionIfNeeded(Fstab* fstab,
const std::function<bool(const std::set<std::string>&)>& init); const std::function<bool(const std::set<std::string>&)>& init);
void CleanupOldScratchFiles(); void CleanupOldScratchFiles();
// Teardown overlays of all sources (cache dir, scratch device, DSU) for |mount_point|.
// Teardown all overlays if |mount_point| is empty.
//
// Note: This should be called if and only if in recovery or fastbootd to teardown
// overlays if any partition is flashed or updated.
void TeardownAllOverlayForMountPoint(const std::string& mount_point = {});
} // namespace fs_mgr } // namespace fs_mgr
} // namespace android } // namespace android