fastboot: Mount /metadata before overlayfs teardown.

fs_mgr_overlayfs needs access to /metadata to tell whether or not the
scratch partition exists on /data.

Bug: 134949511
Test: adb remount, fastboot flash system
Change-Id: I3a09aae495d691e9c1a1e25a8fb3514e355ecd05
This commit is contained in:
David Anderson 2019-12-17 00:58:31 -08:00
parent 18c6248ffe
commit 23243497fd
4 changed files with 43 additions and 37 deletions

View file

@ -31,7 +31,6 @@
#include <cutils/android_reboot.h>
#include <ext4_utils/wipe.h>
#include <fs_mgr.h>
#include <fs_mgr/roots.h>
#include <libgsi/libgsi.h>
#include <liblp/builder.h>
#include <liblp/liblp.h>
@ -550,42 +549,6 @@ bool UpdateSuperHandler(FastbootDevice* device, const std::vector<std::string>&
return UpdateSuper(device, args[1], wipe);
}
class AutoMountMetadata {
public:
AutoMountMetadata() {
android::fs_mgr::Fstab proc_mounts;
if (!ReadFstabFromFile("/proc/mounts", &proc_mounts)) {
LOG(ERROR) << "Could not read /proc/mounts";
return;
}
auto iter = std::find_if(proc_mounts.begin(), proc_mounts.end(),
[](const auto& entry) { return entry.mount_point == "/metadata"; });
if (iter != proc_mounts.end()) {
mounted_ = true;
return;
}
if (!ReadDefaultFstab(&fstab_)) {
LOG(ERROR) << "Could not read default fstab";
return;
}
mounted_ = EnsurePathMounted(&fstab_, "/metadata");
should_unmount_ = true;
}
~AutoMountMetadata() {
if (mounted_ && should_unmount_) {
EnsurePathUnmounted(&fstab_, "/metadata");
}
}
explicit operator bool() const { return mounted_; }
private:
android::fs_mgr::Fstab fstab_;
bool mounted_ = false;
bool should_unmount_ = false;
};
bool GsiHandler(FastbootDevice* device, const std::vector<std::string>& args) {
if (args.size() != 2) {
return device->WriteFail("Invalid arguments");

View file

@ -21,6 +21,7 @@
#include <algorithm>
#include <memory>
#include <optional>
#include <set>
#include <string>
@ -56,6 +57,7 @@ void WipeOverlayfsForPartition(FastbootDevice* device, const std::string& partit
Fstab fstab;
ReadDefaultFstab(&fstab);
std::optional<AutoMountMetadata> mount_metadata;
for (const auto& entry : fstab) {
auto partition = android::base::Basename(entry.mount_point);
if ("/" == entry.mount_point) {
@ -63,6 +65,7 @@ void WipeOverlayfsForPartition(FastbootDevice* device, const std::string& partit
}
if ((partition + device->GetCurrentSlot()) == partition_name) {
mount_metadata.emplace();
fs_mgr_overlayfs_teardown(entry.mount_point.c_str());
}
}

View file

@ -26,6 +26,7 @@
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <fs_mgr.h>
#include <fs_mgr/roots.h>
#include <fs_mgr_dm_linear.h>
#include <liblp/builder.h>
#include <liblp/liblp.h>
@ -240,3 +241,29 @@ std::string GetSuperSlotSuffix(FastbootDevice* device, const std::string& partit
}
return current_slot_suffix;
}
AutoMountMetadata::AutoMountMetadata() {
android::fs_mgr::Fstab proc_mounts;
if (!ReadFstabFromFile("/proc/mounts", &proc_mounts)) {
LOG(ERROR) << "Could not read /proc/mounts";
return;
}
if (GetEntryForMountPoint(&proc_mounts, "/metadata")) {
mounted_ = true;
return;
}
if (!ReadDefaultFstab(&fstab_)) {
LOG(ERROR) << "Could not read default fstab";
return;
}
mounted_ = EnsurePathMounted(&fstab_, "/metadata");
should_unmount_ = true;
}
AutoMountMetadata::~AutoMountMetadata() {
if (mounted_ && should_unmount_) {
EnsurePathUnmounted(&fstab_, "/metadata");
}
}

View file

@ -20,6 +20,7 @@
#include <android-base/unique_fd.h>
#include <android/hardware/boot/1.0/IBootControl.h>
#include <fstab/fstab.h>
#include <liblp/liblp.h>
// Logical partitions are only mapped to a block device as needed, and
@ -51,6 +52,18 @@ class PartitionHandle {
std::function<void()> closer_;
};
class AutoMountMetadata {
public:
AutoMountMetadata();
~AutoMountMetadata();
explicit operator bool() const { return mounted_; }
private:
android::fs_mgr::Fstab fstab_;
bool mounted_ = false;
bool should_unmount_ = false;
};
class FastbootDevice;
// On normal devices, the super partition is always named "super". On retrofit