Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1df51d65 authored by David Anderson's avatar David Anderson Committed by Automerger Merge Worker
Browse files

Merge "libsnapshot: Ensure we can remove bad snapshots when beginning an...

Merge "libsnapshot: Ensure we can remove bad snapshots when beginning an update." am: 7ab8f2ee am: 2365c0d9 am: 695d5d04 am: bd77cc1d

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

Change-Id: Ia63a95d2379ab5d09adadfdc0ba35ddfe97bffac
parents 31cf6c54 bd77cc1d
Loading
Loading
Loading
Loading
+12 −0
Original line number Original line Diff line number Diff line
@@ -1619,6 +1619,18 @@ bool SnapshotManager::RemoveAllSnapshots(LockedFile* lock) {
        //    as dm-snapshot (for example, after merge completes).
        //    as dm-snapshot (for example, after merge completes).
        bool should_unmap = current_slot != Slot::Target;
        bool should_unmap = current_slot != Slot::Target;
        bool should_delete = ShouldDeleteSnapshot(flashing_status, current_slot, name);
        bool should_delete = ShouldDeleteSnapshot(flashing_status, current_slot, name);
        if (should_unmap && android::base::EndsWith(name, device_->GetSlotSuffix())) {
            // Something very unexpected has happened - we want to unmap this
            // snapshot, but it's on the wrong slot. We can't unmap an active
            // partition. If this is not really a snapshot, skip the unmap
            // step.
            auto& dm = DeviceMapper::Instance();
            if (dm.GetState(name) == DmDeviceState::INVALID || !IsSnapshotDevice(name)) {
                LOG(ERROR) << "Detected snapshot " << name << " on " << current_slot << " slot"
                           << " for source partition; removing without unmap.";
                should_unmap = false;
            }
        }


        bool partition_ok = true;
        bool partition_ok = true;
        if (should_unmap && !UnmapPartitionWithSnapshot(lock, name)) {
        if (should_unmap && !UnmapPartitionWithSnapshot(lock, name)) {
+28 −0
Original line number Original line Diff line number Diff line
@@ -2021,6 +2021,34 @@ TEST_F(SnapshotUpdateTest, MapAllSnapshots) {
    ASSERT_TRUE(IsPartitionUnchanged("sys_b"));
    ASSERT_TRUE(IsPartitionUnchanged("sys_b"));
}
}


TEST_F(SnapshotUpdateTest, CancelOnTargetSlot) {
    AddOperationForPartitions();

    // Execute the update from B->A.
    test_device->set_slot_suffix("_b");
    ASSERT_TRUE(sm->BeginUpdate());
    ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));

    std::string path;
    ASSERT_TRUE(CreateLogicalPartition(
            CreateLogicalPartitionParams{
                    .block_device = fake_super,
                    .metadata_slot = 0,
                    .partition_name = "sys_a",
                    .timeout_ms = 1s,
                    .partition_opener = opener_.get(),
            },
            &path));

    // Hold sys_a open so it can't be unmapped.
    unique_fd fd(open(path.c_str(), O_RDONLY));

    // Switch back to "A", make sure we can cancel. Instead of unmapping sys_a
    // we should simply delete the old snapshots.
    test_device->set_slot_suffix("_a");
    ASSERT_TRUE(sm->BeginUpdate());
}

class FlashAfterUpdateTest : public SnapshotUpdateTest,
class FlashAfterUpdateTest : public SnapshotUpdateTest,
                             public WithParamInterface<std::tuple<uint32_t, bool>> {
                             public WithParamInterface<std::tuple<uint32_t, bool>> {
  public:
  public: