remount: Detect when flashall has happened in the bootloader.
This adds a new metadata header flag to the super partition. This flag is set when "adb remount" is used, and is implicitly cleared when flashing. If there is a scratch partition present on /data, we require that the flag be set in order to proceed using overlays. If not set, scratch is not mapped in first-stage init, and scratch images are removed later during startup. Bug: 297923468 Test: adb remount -R, touch file in out/, sync, flashall Change-Id: I9cc411a1632101b5fc043193b38db8ffb9c20e7f
This commit is contained in:
parent
e2c6171f65
commit
adb91b0e59
8 changed files with 67 additions and 7 deletions
|
@ -1675,7 +1675,7 @@ bool AddResizeTasks(const FlashingPlan* fp, std::vector<std::unique_ptr<Task>>*
|
|||
}
|
||||
for (size_t i = 0; i < tasks->size(); i++) {
|
||||
if (auto flash_task = tasks->at(i)->AsFlashTask()) {
|
||||
if (FlashTask::IsDynamicParitition(fp->source.get(), flash_task)) {
|
||||
if (FlashTask::IsDynamicPartition(fp->source.get(), flash_task)) {
|
||||
if (!loc) {
|
||||
loc = i;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ FlashTask::FlashTask(const std::string& slot, const std::string& pname, const st
|
|||
const bool apply_vbmeta, const FlashingPlan* fp)
|
||||
: pname_(pname), fname_(fname), slot_(slot), apply_vbmeta_(apply_vbmeta), fp_(fp) {}
|
||||
|
||||
bool FlashTask::IsDynamicParitition(const ImageSource* source, const FlashTask* task) {
|
||||
bool FlashTask::IsDynamicPartition(const ImageSource* source, const FlashTask* task) {
|
||||
std::vector<char> contents;
|
||||
if (!source->ReadFile("super_empty.img", &contents)) {
|
||||
return false;
|
||||
|
@ -152,7 +152,7 @@ bool OptimizedFlashSuperTask::CanOptimize(const ImageSource* source,
|
|||
continue;
|
||||
}
|
||||
auto flash_task = tasks[i + 2]->AsFlashTask();
|
||||
if (!FlashTask::IsDynamicParitition(source, flash_task)) {
|
||||
if (!FlashTask::IsDynamicPartition(source, flash_task)) {
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -52,7 +52,7 @@ class FlashTask : public Task {
|
|||
const bool apply_vbmeta, const FlashingPlan* fp);
|
||||
virtual FlashTask* AsFlashTask() override { return this; }
|
||||
|
||||
static bool IsDynamicParitition(const ImageSource* source, const FlashTask* task);
|
||||
static bool IsDynamicPartition(const ImageSource* source, const FlashTask* task);
|
||||
void Run() override;
|
||||
std::string ToString() const override;
|
||||
std::string GetPartition() const { return pname_; }
|
||||
|
|
|
@ -233,7 +233,7 @@ TEST_F(ParseTest, CorrectTaskLists) {
|
|||
<< "size of fastboot-info task list: " << fastboot_info_tasks.size()
|
||||
<< " size of hardcoded task list: " << hardcoded_tasks.size();
|
||||
}
|
||||
TEST_F(ParseTest, IsDynamicParitiontest) {
|
||||
TEST_F(ParseTest, IsDynamicPartitiontest) {
|
||||
if (!get_android_product_out()) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
@ -258,7 +258,7 @@ TEST_F(ParseTest, IsDynamicParitiontest) {
|
|||
ParseFastbootInfoLine(fp.get(), android::base::Tokenize(test.first, " "));
|
||||
auto flash_task = task->AsFlashTask();
|
||||
ASSERT_FALSE(flash_task == nullptr);
|
||||
ASSERT_EQ(FlashTask::IsDynamicParitition(fp->source.get(), flash_task), test.second);
|
||||
ASSERT_EQ(FlashTask::IsDynamicPartition(fp->source.get(), flash_task), test.second);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,7 +358,7 @@ TEST_F(ParseTest, OptimizedFlashSuperPatternMatchTest) {
|
|||
contains_optimized_task = true;
|
||||
}
|
||||
if (auto flash_task = task->AsFlashTask()) {
|
||||
if (FlashTask::IsDynamicParitition(fp->source.get(), flash_task)) {
|
||||
if (FlashTask::IsDynamicPartition(fp->source.get(), flash_task)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -219,6 +219,35 @@ OverlayfsTeardownResult TeardownDataScratch(IImageManager* images,
|
|||
return OverlayfsTeardownResult::Ok;
|
||||
}
|
||||
|
||||
bool GetOverlaysActiveFlag() {
|
||||
auto slot_number = fs_mgr_overlayfs_slot_number();
|
||||
const auto super_device = kPhysicalDevice + fs_mgr_get_super_partition_name();
|
||||
|
||||
auto metadata = ReadMetadata(super_device, slot_number);
|
||||
if (!metadata) {
|
||||
return false;
|
||||
}
|
||||
return !!(metadata->header.flags & LP_HEADER_FLAG_OVERLAYS_ACTIVE);
|
||||
}
|
||||
|
||||
bool SetOverlaysActiveFlag(bool flag) {
|
||||
// Mark overlays as active in the partition table, to detect re-flash.
|
||||
auto slot_number = fs_mgr_overlayfs_slot_number();
|
||||
const auto super_device = kPhysicalDevice + fs_mgr_get_super_partition_name();
|
||||
auto builder = MetadataBuilder::New(super_device, slot_number);
|
||||
if (!builder) {
|
||||
LERROR << "open " << super_device << " metadata";
|
||||
return false;
|
||||
}
|
||||
builder->SetOverlaysActiveFlag(flag);
|
||||
auto metadata = builder->Export();
|
||||
if (!metadata || !UpdatePartitionTable(super_device, *metadata.get(), slot_number)) {
|
||||
LERROR << "update super metadata";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
OverlayfsTeardownResult fs_mgr_overlayfs_teardown_scratch(const std::string& overlay,
|
||||
bool* change) {
|
||||
// umount and delete kScratchMountPoint storage if we have logical partitions
|
||||
|
@ -232,6 +261,10 @@ OverlayfsTeardownResult fs_mgr_overlayfs_teardown_scratch(const std::string& ove
|
|||
return OverlayfsTeardownResult::Error;
|
||||
}
|
||||
|
||||
// Note: we don't care if SetOverlaysActiveFlag fails, since
|
||||
// the overlays are removed no matter what.
|
||||
SetOverlaysActiveFlag(false);
|
||||
|
||||
bool was_mounted = fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false);
|
||||
if (was_mounted) {
|
||||
fs_mgr_overlayfs_umount_scratch();
|
||||
|
@ -448,6 +481,7 @@ static bool CreateDynamicScratch(std::string* scratch_device, bool* partition_ex
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// land the update back on to the partition
|
||||
if (changed) {
|
||||
auto metadata = builder->Export();
|
||||
|
@ -592,6 +626,12 @@ bool fs_mgr_overlayfs_setup_scratch(const Fstab& fstab) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!SetOverlaysActiveFlag(true)) {
|
||||
LOG(ERROR) << "Failed to update dynamic partition data";
|
||||
fs_mgr_overlayfs_teardown_scratch(kScratchMountPoint, nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the partition exists, assume first that it can be mounted.
|
||||
if (partition_exists) {
|
||||
if (MountScratch(scratch_device)) {
|
||||
|
@ -856,6 +896,9 @@ void MapScratchPartitionIfNeeded(Fstab* fstab,
|
|||
return;
|
||||
}
|
||||
|
||||
if (!GetOverlaysActiveFlag()) {
|
||||
return;
|
||||
}
|
||||
if (ScratchIsOnData()) {
|
||||
if (auto images = IImageManager::Open("remount", 0ms)) {
|
||||
images->MapAllImages(init);
|
||||
|
@ -879,6 +922,9 @@ void CleanupOldScratchFiles() {
|
|||
}
|
||||
if (auto images = IImageManager::Open("remount", 0ms)) {
|
||||
images->RemoveDisabledImages();
|
||||
if (!GetOverlaysActiveFlag()) {
|
||||
fs_mgr_overlayfs_teardown_scratch(kScratchMountPoint, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1211,6 +1211,15 @@ void MetadataBuilder::SetVirtualABDeviceFlag() {
|
|||
header_.flags |= LP_HEADER_FLAG_VIRTUAL_AB_DEVICE;
|
||||
}
|
||||
|
||||
void MetadataBuilder::SetOverlaysActiveFlag(bool flag) {
|
||||
RequireExpandedMetadataHeader();
|
||||
if (flag) {
|
||||
header_.flags |= LP_HEADER_FLAG_OVERLAYS_ACTIVE;
|
||||
} else {
|
||||
header_.flags &= ~LP_HEADER_FLAG_OVERLAYS_ACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
bool MetadataBuilder::IsABDevice() {
|
||||
return !IPropertyFetcher::GetInstance()->GetProperty("ro.boot.slot_suffix", "").empty();
|
||||
}
|
||||
|
|
|
@ -346,6 +346,8 @@ class MetadataBuilder {
|
|||
void SetAutoSlotSuffixing();
|
||||
// Set the LP_HEADER_FLAG_VIRTUAL_AB_DEVICE flag.
|
||||
void SetVirtualABDeviceFlag();
|
||||
// Set or unset the LP_HEADER_FLAG_OVERLAYS_ACTIVE flag.
|
||||
void SetOverlaysActiveFlag(bool flag);
|
||||
|
||||
bool GetBlockDeviceInfo(const std::string& partition_name, BlockDeviceInfo* info) const;
|
||||
bool UpdateBlockDeviceInfo(const std::string& partition_name, const BlockDeviceInfo& info);
|
||||
|
|
|
@ -240,6 +240,9 @@ typedef struct LpMetadataHeader {
|
|||
*/
|
||||
#define LP_HEADER_FLAG_VIRTUAL_AB_DEVICE 0x1
|
||||
|
||||
/* This device has overlays activated via "adb remount". */
|
||||
#define LP_HEADER_FLAG_OVERLAYS_ACTIVE 0x2
|
||||
|
||||
/* This struct defines a logical partition entry, similar to what would be
|
||||
* present in a GUID Partition Table.
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue