Merge "libsnapshot: Do not map snapshots for partitions that were reflashed."
This commit is contained in:
commit
f5960a1ac7
|
@ -86,6 +86,7 @@ cc_test {
|
|||
"libcutils",
|
||||
"libcrypto",
|
||||
"libfs_mgr",
|
||||
"libgmock",
|
||||
"liblp",
|
||||
"libsnapshot",
|
||||
],
|
||||
|
|
|
@ -158,6 +158,7 @@ class SnapshotManager final {
|
|||
FRIEND_TEST(SnapshotTest, CreateSnapshot);
|
||||
FRIEND_TEST(SnapshotTest, FirstStageMountAfterRollback);
|
||||
FRIEND_TEST(SnapshotTest, FirstStageMountAndMerge);
|
||||
FRIEND_TEST(SnapshotTest, FlashSuperDuringUpdate);
|
||||
FRIEND_TEST(SnapshotTest, MapPartialSnapshot);
|
||||
FRIEND_TEST(SnapshotTest, MapSnapshot);
|
||||
FRIEND_TEST(SnapshotTest, Merge);
|
||||
|
|
|
@ -1041,6 +1041,12 @@ bool SnapshotManager::CreateLogicalAndSnapshotPartitions(const std::string& supe
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!(partition.attributes & LP_PARTITION_ATTR_UPDATED)) {
|
||||
LOG(INFO) << "Detected re-flashing of partition, will skip snapshot: "
|
||||
<< partition_name;
|
||||
live_snapshots.erase(partition_name);
|
||||
}
|
||||
|
||||
CreateLogicalPartitionParams params = {
|
||||
.block_device = super_device,
|
||||
.metadata = metadata.get(),
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <libdm/dm.h>
|
||||
#include <libfiemap/image_manager.h>
|
||||
#include <liblp/builder.h>
|
||||
#include <liblp/mock_property_fetcher.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
|
@ -43,7 +44,10 @@ using android::dm::DmDeviceState;
|
|||
using android::fiemap::IImageManager;
|
||||
using android::fs_mgr::BlockDeviceInfo;
|
||||
using android::fs_mgr::CreateLogicalPartitionParams;
|
||||
using android::fs_mgr::DestroyLogicalPartition;
|
||||
using android::fs_mgr::MetadataBuilder;
|
||||
using namespace ::testing;
|
||||
using namespace android::fs_mgr::testing;
|
||||
using namespace std::chrono_literals;
|
||||
using namespace std::string_literals;
|
||||
|
||||
|
@ -67,6 +71,7 @@ class SnapshotTest : public ::testing::Test {
|
|||
|
||||
protected:
|
||||
void SetUp() override {
|
||||
ResetMockPropertyFetcher();
|
||||
InitializeState();
|
||||
CleanupTestArtifacts();
|
||||
FormatFakeSuper();
|
||||
|
@ -78,6 +83,7 @@ class SnapshotTest : public ::testing::Test {
|
|||
lock_ = nullptr;
|
||||
|
||||
CleanupTestArtifacts();
|
||||
ResetMockPropertyFetcher();
|
||||
}
|
||||
|
||||
void InitializeState() {
|
||||
|
@ -95,7 +101,8 @@ class SnapshotTest : public ::testing::Test {
|
|||
// get an accurate list to remove.
|
||||
lock_ = nullptr;
|
||||
|
||||
std::vector<std::string> snapshots = {"test-snapshot", "test_partition_b"};
|
||||
std::vector<std::string> snapshots = {"test-snapshot", "test_partition_a",
|
||||
"test_partition_b"};
|
||||
for (const auto& snapshot : snapshots) {
|
||||
DeleteSnapshotDevice(snapshot);
|
||||
DeleteBackingImage(image_manager_, snapshot + "-cow");
|
||||
|
@ -154,11 +161,10 @@ class SnapshotTest : public ::testing::Test {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Update both slots for convenience.
|
||||
// Update the source slot.
|
||||
auto metadata = builder->Export();
|
||||
if (!metadata) return false;
|
||||
if (!UpdatePartitionTable(opener, "super", *metadata.get(), 0) ||
|
||||
!UpdatePartitionTable(opener, "super", *metadata.get(), 1)) {
|
||||
if (!UpdatePartitionTable(opener, "super", *metadata.get(), 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -174,6 +180,35 @@ class SnapshotTest : public ::testing::Test {
|
|||
return CreateLogicalPartition(params, path);
|
||||
}
|
||||
|
||||
bool MapUpdatePartitions() {
|
||||
TestPartitionOpener opener(fake_super);
|
||||
auto builder = MetadataBuilder::NewForUpdate(opener, "super", 0, 1);
|
||||
if (!builder) return false;
|
||||
|
||||
auto metadata = builder->Export();
|
||||
if (!metadata) return false;
|
||||
|
||||
// Update the destination slot, mark it as updated.
|
||||
if (!UpdatePartitionTable(opener, "super", *metadata.get(), 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& partition : metadata->partitions) {
|
||||
CreateLogicalPartitionParams params = {
|
||||
.block_device = fake_super,
|
||||
.metadata = metadata.get(),
|
||||
.partition = &partition,
|
||||
.force_writable = true,
|
||||
.timeout_ms = 10s,
|
||||
};
|
||||
std::string ignore_path;
|
||||
if (!CreateLogicalPartition(params, &ignore_path)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeleteSnapshotDevice(const std::string& snapshot) {
|
||||
DeleteDevice(snapshot);
|
||||
DeleteDevice(snapshot + "-inner");
|
||||
|
@ -370,17 +405,22 @@ TEST_F(SnapshotTest, MergeCannotRemoveCow) {
|
|||
}
|
||||
|
||||
TEST_F(SnapshotTest, FirstStageMountAndMerge) {
|
||||
ON_CALL(*GetMockedPropertyFetcher(), GetBoolProperty("ro.virtual_ab.enabled", _))
|
||||
.WillByDefault(Return(true));
|
||||
|
||||
ASSERT_TRUE(AcquireLock());
|
||||
|
||||
static const uint64_t kDeviceSize = 1024 * 1024;
|
||||
|
||||
ASSERT_TRUE(CreatePartition("test_partition_b", kDeviceSize));
|
||||
ASSERT_TRUE(CreatePartition("test_partition_a", kDeviceSize));
|
||||
ASSERT_TRUE(MapUpdatePartitions());
|
||||
ASSERT_TRUE(sm->CreateSnapshot(lock_.get(), "test_partition_b", kDeviceSize, kDeviceSize,
|
||||
kDeviceSize));
|
||||
|
||||
// Simulate a reboot into the new slot.
|
||||
lock_ = nullptr;
|
||||
ASSERT_TRUE(sm->FinishedSnapshotWrites());
|
||||
ASSERT_TRUE(DestroyLogicalPartition("test_partition_b"));
|
||||
|
||||
auto rebooted = new TestDeviceInfo(fake_super);
|
||||
rebooted->set_slot_suffix("_b");
|
||||
|
@ -403,6 +443,47 @@ TEST_F(SnapshotTest, FirstStageMountAndMerge) {
|
|||
ASSERT_EQ(DeviceMapper::GetTargetType(target.spec), "snapshot");
|
||||
}
|
||||
|
||||
TEST_F(SnapshotTest, FlashSuperDuringUpdate) {
|
||||
ON_CALL(*GetMockedPropertyFetcher(), GetBoolProperty("ro.virtual_ab.enabled", _))
|
||||
.WillByDefault(Return(true));
|
||||
|
||||
ASSERT_TRUE(AcquireLock());
|
||||
|
||||
static const uint64_t kDeviceSize = 1024 * 1024;
|
||||
|
||||
ASSERT_TRUE(CreatePartition("test_partition_a", kDeviceSize));
|
||||
ASSERT_TRUE(MapUpdatePartitions());
|
||||
ASSERT_TRUE(sm->CreateSnapshot(lock_.get(), "test_partition_b", kDeviceSize, kDeviceSize,
|
||||
kDeviceSize));
|
||||
|
||||
// Simulate a reboot into the new slot.
|
||||
lock_ = nullptr;
|
||||
ASSERT_TRUE(sm->FinishedSnapshotWrites());
|
||||
ASSERT_TRUE(DestroyLogicalPartition("test_partition_b"));
|
||||
|
||||
// Reflash the super partition.
|
||||
FormatFakeSuper();
|
||||
ASSERT_TRUE(CreatePartition("test_partition_b", kDeviceSize));
|
||||
|
||||
auto rebooted = new TestDeviceInfo(fake_super);
|
||||
rebooted->set_slot_suffix("_b");
|
||||
|
||||
auto init = SnapshotManager::NewForFirstStageMount(rebooted);
|
||||
ASSERT_NE(init, nullptr);
|
||||
ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
|
||||
ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super"));
|
||||
|
||||
ASSERT_TRUE(AcquireLock());
|
||||
|
||||
SnapshotManager::SnapshotStatus status;
|
||||
ASSERT_TRUE(init->ReadSnapshotStatus(lock_.get(), "test_partition_b", &status));
|
||||
|
||||
// We should not get a snapshot device now.
|
||||
DeviceMapper::TargetInfo target;
|
||||
auto dm_name = init->GetSnapshotDeviceName("test_partition_b", status);
|
||||
ASSERT_FALSE(init->IsSnapshotDevice(dm_name, &target));
|
||||
}
|
||||
|
||||
} // namespace snapshot
|
||||
} // namespace android
|
||||
|
||||
|
|
Loading…
Reference in New Issue