1 // Copyright (C) 2018 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <libsnapshot/snapshot.h>
16 
17 #include <fcntl.h>
18 #include <sys/file.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 
22 #include <chrono>
23 #include <deque>
24 #include <future>
25 #include <iostream>
26 
27 #include <android-base/file.h>
28 #include <android-base/logging.h>
29 #include <android-base/properties.h>
30 #include <android-base/strings.h>
31 #include <android-base/unique_fd.h>
32 #include <fs_mgr/roots.h>
33 #include <fs_mgr_dm_linear.h>
34 #include <gtest/gtest.h>
35 #include <libdm/dm.h>
36 #include <libfiemap/image_manager.h>
37 #include <liblp/builder.h>
38 #include <storage_literals/storage_literals.h>
39 
40 #include <android/snapshot/snapshot.pb.h>
41 #include <libsnapshot/test_helpers.h>
42 #include "utility.h"
43 
44 // Mock classes are not used. Header included to ensure mocked class definition aligns with the
45 // class itself.
46 #include <libsnapshot/mock_device_info.h>
47 #include <libsnapshot/mock_snapshot.h>
48 
49 namespace android {
50 namespace snapshot {
51 
52 using android::base::unique_fd;
53 using android::dm::DeviceMapper;
54 using android::dm::DmDeviceState;
55 using android::fiemap::FiemapStatus;
56 using android::fiemap::IImageManager;
57 using android::fs_mgr::BlockDeviceInfo;
58 using android::fs_mgr::CreateLogicalPartitionParams;
59 using android::fs_mgr::DestroyLogicalPartition;
60 using android::fs_mgr::EnsurePathMounted;
61 using android::fs_mgr::EnsurePathUnmounted;
62 using android::fs_mgr::Extent;
63 using android::fs_mgr::Fstab;
64 using android::fs_mgr::GetPartitionGroupName;
65 using android::fs_mgr::GetPartitionName;
66 using android::fs_mgr::Interval;
67 using android::fs_mgr::MetadataBuilder;
68 using android::fs_mgr::SlotSuffixForSlotNumber;
69 using chromeos_update_engine::DeltaArchiveManifest;
70 using chromeos_update_engine::DynamicPartitionGroup;
71 using chromeos_update_engine::PartitionUpdate;
72 using namespace ::testing;
73 using namespace android::storage_literals;
74 using namespace std::chrono_literals;
75 using namespace std::string_literals;
76 
77 // Global states. See test_helpers.h.
78 std::unique_ptr<SnapshotManager> sm;
79 TestDeviceInfo* test_device = nullptr;
80 std::string fake_super;
81 
82 void MountMetadata();
83 
84 class SnapshotTest : public ::testing::Test {
85   public:
SnapshotTest()86     SnapshotTest() : dm_(DeviceMapper::Instance()) {
87         is_virtual_ab_ = android::base::GetBoolProperty("ro.virtual_ab.enabled", false);
88     }
89 
90     // This is exposed for main.
Cleanup()91     void Cleanup() {
92         InitializeState();
93         CleanupTestArtifacts();
94     }
95 
96   protected:
SetUp()97     void SetUp() override {
98         if (!is_virtual_ab_) GTEST_SKIP() << "Test for Virtual A/B devices only";
99 
100         SnapshotTestPropertyFetcher::SetUp();
101         InitializeState();
102         CleanupTestArtifacts();
103         FormatFakeSuper();
104         MountMetadata();
105         ASSERT_TRUE(sm->BeginUpdate());
106     }
107 
TearDown()108     void TearDown() override {
109         if (!is_virtual_ab_) return;
110 
111         lock_ = nullptr;
112 
113         CleanupTestArtifacts();
114         SnapshotTestPropertyFetcher::TearDown();
115     }
116 
InitializeState()117     void InitializeState() {
118         ASSERT_TRUE(sm->EnsureImageManager());
119         image_manager_ = sm->image_manager();
120 
121         test_device->set_slot_suffix("_a");
122     }
123 
CleanupTestArtifacts()124     void CleanupTestArtifacts() {
125         // Normally cancelling inside a merge is not allowed. Since these
126         // are tests, we don't care, destroy everything that might exist.
127         // Note we hardcode this list because of an annoying quirk: when
128         // completing a merge, the snapshot stops existing, so we can't
129         // get an accurate list to remove.
130         lock_ = nullptr;
131 
132         std::vector<std::string> snapshots = {"test-snapshot", "test_partition_a",
133                                               "test_partition_b"};
134         for (const auto& snapshot : snapshots) {
135             ASSERT_TRUE(DeleteSnapshotDevice(snapshot));
136             DeleteBackingImage(image_manager_, snapshot + "-cow-img");
137 
138             auto status_file = sm->GetSnapshotStatusFilePath(snapshot);
139             android::base::RemoveFileIfExists(status_file);
140         }
141 
142         // Remove stale partitions in fake super.
143         std::vector<std::string> partitions = {
144                 "base-device",
145                 "test_partition_b",
146                 "test_partition_b-base",
147         };
148         for (const auto& partition : partitions) {
149             DeleteDevice(partition);
150         }
151 
152         if (sm->GetUpdateState() != UpdateState::None) {
153             auto state_file = sm->GetStateFilePath();
154             unlink(state_file.c_str());
155         }
156     }
157 
AcquireLock()158     bool AcquireLock() {
159         lock_ = sm->LockExclusive();
160         return !!lock_;
161     }
162 
163     // This is so main() can instantiate this to invoke Cleanup.
TestBody()164     virtual void TestBody() override {}
165 
FormatFakeSuper()166     void FormatFakeSuper() {
167         BlockDeviceInfo super_device("super", kSuperSize, 0, 0, 4096);
168         std::vector<BlockDeviceInfo> devices = {super_device};
169 
170         auto builder = MetadataBuilder::New(devices, "super", 65536, 2);
171         ASSERT_NE(builder, nullptr);
172 
173         auto metadata = builder->Export();
174         ASSERT_NE(metadata, nullptr);
175 
176         TestPartitionOpener opener(fake_super);
177         ASSERT_TRUE(FlashPartitionTable(opener, fake_super, *metadata.get()));
178     }
179 
180     // If |path| is non-null, the partition will be mapped after creation.
CreatePartition(const std::string & name,uint64_t size,std::string * path=nullptr)181     bool CreatePartition(const std::string& name, uint64_t size, std::string* path = nullptr) {
182         TestPartitionOpener opener(fake_super);
183         auto builder = MetadataBuilder::New(opener, "super", 0);
184         if (!builder) return false;
185 
186         auto partition = builder->AddPartition(name, 0);
187         if (!partition) return false;
188         if (!builder->ResizePartition(partition, size)) {
189             return false;
190         }
191 
192         // Update the source slot.
193         auto metadata = builder->Export();
194         if (!metadata) return false;
195         if (!UpdatePartitionTable(opener, "super", *metadata.get(), 0)) {
196             return false;
197         }
198 
199         if (!path) return true;
200 
201         CreateLogicalPartitionParams params = {
202                 .block_device = fake_super,
203                 .metadata = metadata.get(),
204                 .partition_name = name,
205                 .force_writable = true,
206                 .timeout_ms = 10s,
207         };
208         return CreateLogicalPartition(params, path);
209     }
210 
MapUpdatePartitions()211     bool MapUpdatePartitions() {
212         TestPartitionOpener opener(fake_super);
213         auto builder = MetadataBuilder::NewForUpdate(opener, "super", 0, 1);
214         if (!builder) return false;
215 
216         auto metadata = builder->Export();
217         if (!metadata) return false;
218 
219         // Update the destination slot, mark it as updated.
220         if (!UpdatePartitionTable(opener, "super", *metadata.get(), 1)) {
221             return false;
222         }
223 
224         for (const auto& partition : metadata->partitions) {
225             CreateLogicalPartitionParams params = {
226                     .block_device = fake_super,
227                     .metadata = metadata.get(),
228                     .partition = &partition,
229                     .force_writable = true,
230                     .timeout_ms = 10s,
231                     .device_name = GetPartitionName(partition) + "-base",
232             };
233             std::string ignore_path;
234             if (!CreateLogicalPartition(params, &ignore_path)) {
235                 return false;
236             }
237         }
238         return true;
239     }
240 
DeleteSnapshotDevice(const std::string & snapshot)241     AssertionResult DeleteSnapshotDevice(const std::string& snapshot) {
242         AssertionResult res = AssertionSuccess();
243         if (!(res = DeleteDevice(snapshot))) return res;
244         if (!(res = DeleteDevice(snapshot + "-inner"))) return res;
245         if (!(res = DeleteDevice(snapshot + "-cow"))) return res;
246         if (!image_manager_->UnmapImageIfExists(snapshot + "-cow-img")) {
247             return AssertionFailure() << "Cannot unmap image " << snapshot << "-cow-img";
248         }
249         if (!(res = DeleteDevice(snapshot + "-base"))) return res;
250         return AssertionSuccess();
251     }
252 
DeleteDevice(const std::string & device)253     AssertionResult DeleteDevice(const std::string& device) {
254         if (!dm_.DeleteDeviceIfExists(device)) {
255             return AssertionFailure() << "Can't delete " << device;
256         }
257         return AssertionSuccess();
258     }
259 
CreateCowImage(const std::string & name)260     AssertionResult CreateCowImage(const std::string& name) {
261         if (!sm->CreateCowImage(lock_.get(), name)) {
262             return AssertionFailure() << "Cannot create COW image " << name;
263         }
264         std::string cow_device;
265         auto map_res = MapCowImage(name, 10s, &cow_device);
266         if (!map_res) {
267             return map_res;
268         }
269         if (!InitializeCow(cow_device)) {
270             return AssertionFailure() << "Cannot zero fill " << cow_device;
271         }
272         if (!sm->UnmapCowImage(name)) {
273             return AssertionFailure() << "Cannot unmap " << name << " after zero filling it";
274         }
275         return AssertionSuccess();
276     }
277 
MapCowImage(const std::string & name,const std::chrono::milliseconds & timeout_ms,std::string * path)278     AssertionResult MapCowImage(const std::string& name,
279                                 const std::chrono::milliseconds& timeout_ms, std::string* path) {
280         auto cow_image_path = sm->MapCowImage(name, timeout_ms);
281         if (!cow_image_path.has_value()) {
282             return AssertionFailure() << "Cannot map cow image " << name;
283         }
284         *path = *cow_image_path;
285         return AssertionSuccess();
286     }
287 
288     // Prepare A/B slot for a partition named "test_partition".
PrepareOneSnapshot(uint64_t device_size,std::string * out_snap_device=nullptr)289     AssertionResult PrepareOneSnapshot(uint64_t device_size,
290                                        std::string* out_snap_device = nullptr) {
291         std::string base_device, cow_device, snap_device;
292         if (!CreatePartition("test_partition_a", device_size)) {
293             return AssertionFailure();
294         }
295         if (!MapUpdatePartitions()) {
296             return AssertionFailure();
297         }
298         if (!dm_.GetDmDevicePathByName("test_partition_b-base", &base_device)) {
299             return AssertionFailure();
300         }
301         SnapshotStatus status;
302         status.set_name("test_partition_b");
303         status.set_device_size(device_size);
304         status.set_snapshot_size(device_size);
305         status.set_cow_file_size(device_size);
306         if (!sm->CreateSnapshot(lock_.get(), &status)) {
307             return AssertionFailure();
308         }
309         if (!CreateCowImage("test_partition_b")) {
310             return AssertionFailure();
311         }
312         if (!MapCowImage("test_partition_b", 10s, &cow_device)) {
313             return AssertionFailure();
314         }
315         if (!sm->MapSnapshot(lock_.get(), "test_partition_b", base_device, cow_device, 10s,
316                              &snap_device)) {
317             return AssertionFailure();
318         }
319         if (out_snap_device) {
320             *out_snap_device = std::move(snap_device);
321         }
322         return AssertionSuccess();
323     }
324 
325     // Simulate a reboot into the new slot.
SimulateReboot()326     AssertionResult SimulateReboot() {
327         lock_ = nullptr;
328         if (!sm->FinishedSnapshotWrites(false)) {
329             return AssertionFailure();
330         }
331         if (!dm_.DeleteDevice("test_partition_b")) {
332             return AssertionFailure();
333         }
334         if (!DestroyLogicalPartition("test_partition_b-base")) {
335             return AssertionFailure();
336         }
337         if (!sm->UnmapCowImage("test_partition_b")) {
338             return AssertionFailure();
339         }
340         return AssertionSuccess();
341     }
342 
343     static constexpr std::chrono::milliseconds snapshot_timeout_ = 5s;
344     bool is_virtual_ab_;
345     DeviceMapper& dm_;
346     std::unique_ptr<SnapshotManager::LockedFile> lock_;
347     android::fiemap::IImageManager* image_manager_ = nullptr;
348     std::string fake_super_;
349 };
350 
TEST_F(SnapshotTest,CreateSnapshot)351 TEST_F(SnapshotTest, CreateSnapshot) {
352     ASSERT_TRUE(AcquireLock());
353 
354     static const uint64_t kDeviceSize = 1024 * 1024;
355     SnapshotStatus status;
356     status.set_name("test-snapshot");
357     status.set_device_size(kDeviceSize);
358     status.set_snapshot_size(kDeviceSize);
359     status.set_cow_file_size(kDeviceSize);
360     ASSERT_TRUE(sm->CreateSnapshot(lock_.get(), &status));
361     ASSERT_TRUE(CreateCowImage("test-snapshot"));
362 
363     std::vector<std::string> snapshots;
364     ASSERT_TRUE(sm->ListSnapshots(lock_.get(), &snapshots));
365     ASSERT_EQ(snapshots.size(), 1);
366     ASSERT_EQ(snapshots[0], "test-snapshot");
367 
368     // Scope so delete can re-acquire the snapshot file lock.
369     {
370         SnapshotStatus status;
371         ASSERT_TRUE(sm->ReadSnapshotStatus(lock_.get(), "test-snapshot", &status));
372         ASSERT_EQ(status.state(), SnapshotState::CREATED);
373         ASSERT_EQ(status.device_size(), kDeviceSize);
374         ASSERT_EQ(status.snapshot_size(), kDeviceSize);
375     }
376 
377     ASSERT_TRUE(sm->UnmapSnapshot(lock_.get(), "test-snapshot"));
378     ASSERT_TRUE(sm->UnmapCowImage("test-snapshot"));
379     ASSERT_TRUE(sm->DeleteSnapshot(lock_.get(), "test-snapshot"));
380 }
381 
TEST_F(SnapshotTest,MapSnapshot)382 TEST_F(SnapshotTest, MapSnapshot) {
383     ASSERT_TRUE(AcquireLock());
384 
385     static const uint64_t kDeviceSize = 1024 * 1024;
386     SnapshotStatus status;
387     status.set_name("test-snapshot");
388     status.set_device_size(kDeviceSize);
389     status.set_snapshot_size(kDeviceSize);
390     status.set_cow_file_size(kDeviceSize);
391     ASSERT_TRUE(sm->CreateSnapshot(lock_.get(), &status));
392     ASSERT_TRUE(CreateCowImage("test-snapshot"));
393 
394     std::string base_device;
395     ASSERT_TRUE(CreatePartition("base-device", kDeviceSize, &base_device));
396 
397     std::string cow_device;
398     ASSERT_TRUE(MapCowImage("test-snapshot", 10s, &cow_device));
399 
400     std::string snap_device;
401     ASSERT_TRUE(sm->MapSnapshot(lock_.get(), "test-snapshot", base_device, cow_device, 10s,
402                                 &snap_device));
403     ASSERT_TRUE(android::base::StartsWith(snap_device, "/dev/block/dm-"));
404 }
405 
TEST_F(SnapshotTest,MapPartialSnapshot)406 TEST_F(SnapshotTest, MapPartialSnapshot) {
407     ASSERT_TRUE(AcquireLock());
408 
409     static const uint64_t kSnapshotSize = 1024 * 1024;
410     static const uint64_t kDeviceSize = 1024 * 1024 * 2;
411     SnapshotStatus status;
412     status.set_name("test-snapshot");
413     status.set_device_size(kDeviceSize);
414     status.set_snapshot_size(kSnapshotSize);
415     status.set_cow_file_size(kSnapshotSize);
416     ASSERT_TRUE(sm->CreateSnapshot(lock_.get(), &status));
417     ASSERT_TRUE(CreateCowImage("test-snapshot"));
418 
419     std::string base_device;
420     ASSERT_TRUE(CreatePartition("base-device", kDeviceSize, &base_device));
421 
422     std::string cow_device;
423     ASSERT_TRUE(MapCowImage("test-snapshot", 10s, &cow_device));
424 
425     std::string snap_device;
426     ASSERT_TRUE(sm->MapSnapshot(lock_.get(), "test-snapshot", base_device, cow_device, 10s,
427                                 &snap_device));
428     ASSERT_TRUE(android::base::StartsWith(snap_device, "/dev/block/dm-"));
429 }
430 
TEST_F(SnapshotTest,NoMergeBeforeReboot)431 TEST_F(SnapshotTest, NoMergeBeforeReboot) {
432     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
433 
434     // Merge should fail, since the slot hasn't changed.
435     ASSERT_FALSE(sm->InitiateMerge());
436 }
437 
TEST_F(SnapshotTest,CleanFirstStageMount)438 TEST_F(SnapshotTest, CleanFirstStageMount) {
439     // If there's no update in progress, there should be no first-stage mount
440     // needed.
441     TestDeviceInfo* info = new TestDeviceInfo(fake_super);
442     auto sm = SnapshotManager::NewForFirstStageMount(info);
443     ASSERT_NE(sm, nullptr);
444     ASSERT_FALSE(sm->NeedSnapshotsInFirstStageMount());
445 }
446 
TEST_F(SnapshotTest,FirstStageMountAfterRollback)447 TEST_F(SnapshotTest, FirstStageMountAfterRollback) {
448     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
449 
450     // We didn't change the slot, so we shouldn't need snapshots.
451     TestDeviceInfo* info = new TestDeviceInfo(fake_super);
452     auto sm = SnapshotManager::NewForFirstStageMount(info);
453     ASSERT_NE(sm, nullptr);
454     ASSERT_FALSE(sm->NeedSnapshotsInFirstStageMount());
455 
456     auto indicator = sm->GetRollbackIndicatorPath();
457     ASSERT_EQ(access(indicator.c_str(), R_OK), 0);
458 }
459 
TEST_F(SnapshotTest,Merge)460 TEST_F(SnapshotTest, Merge) {
461     ASSERT_TRUE(AcquireLock());
462 
463     static const uint64_t kDeviceSize = 1024 * 1024;
464     std::string snap_device;
465     ASSERT_TRUE(PrepareOneSnapshot(kDeviceSize, &snap_device));
466 
467     std::string test_string = "This is a test string.";
468     {
469         unique_fd fd(open(snap_device.c_str(), O_RDWR | O_CLOEXEC | O_SYNC));
470         ASSERT_GE(fd, 0);
471         ASSERT_TRUE(android::base::WriteFully(fd, test_string.data(), test_string.size()));
472     }
473 
474     // Note: we know there is no inner/outer dm device since we didn't request
475     // a linear segment.
476     DeviceMapper::TargetInfo target;
477     ASSERT_TRUE(sm->IsSnapshotDevice("test_partition_b", &target));
478     ASSERT_EQ(DeviceMapper::GetTargetType(target.spec), "snapshot");
479 
480     // Release the lock.
481     lock_ = nullptr;
482 
483     // Done updating.
484     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
485 
486     test_device->set_slot_suffix("_b");
487     ASSERT_TRUE(sm->InitiateMerge());
488 
489     // The device should have been switched to a snapshot-merge target.
490     ASSERT_TRUE(sm->IsSnapshotDevice("test_partition_b", &target));
491     ASSERT_EQ(DeviceMapper::GetTargetType(target.spec), "snapshot-merge");
492 
493     // We should not be able to cancel an update now.
494     ASSERT_FALSE(sm->CancelUpdate());
495 
496     ASSERT_EQ(sm->ProcessUpdateState(), UpdateState::MergeCompleted);
497     ASSERT_EQ(sm->GetUpdateState(), UpdateState::None);
498 
499     // The device should no longer be a snapshot or snapshot-merge.
500     ASSERT_FALSE(sm->IsSnapshotDevice("test_partition_b"));
501 
502     // Test that we can read back the string we wrote to the snapshot. Note
503     // that the base device is gone now. |snap_device| contains the correct
504     // partition.
505     unique_fd fd(open(snap_device.c_str(), O_RDONLY | O_CLOEXEC));
506     ASSERT_GE(fd, 0);
507 
508     std::string buffer(test_string.size(), '\0');
509     ASSERT_TRUE(android::base::ReadFully(fd, buffer.data(), buffer.size()));
510     ASSERT_EQ(test_string, buffer);
511 }
512 
TEST_F(SnapshotTest,FirstStageMountAndMerge)513 TEST_F(SnapshotTest, FirstStageMountAndMerge) {
514     ASSERT_TRUE(AcquireLock());
515 
516     static const uint64_t kDeviceSize = 1024 * 1024;
517     ASSERT_TRUE(PrepareOneSnapshot(kDeviceSize));
518     ASSERT_TRUE(SimulateReboot());
519 
520     auto init = SnapshotManager::NewForFirstStageMount(new TestDeviceInfo(fake_super, "_b"));
521     ASSERT_NE(init, nullptr);
522     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
523     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
524 
525     ASSERT_TRUE(AcquireLock());
526 
527     // Validate that we have a snapshot device.
528     SnapshotStatus status;
529     ASSERT_TRUE(init->ReadSnapshotStatus(lock_.get(), "test_partition_b", &status));
530     ASSERT_EQ(status.state(), SnapshotState::CREATED);
531 
532     DeviceMapper::TargetInfo target;
533     auto dm_name = init->GetSnapshotDeviceName("test_partition_b", status);
534     ASSERT_TRUE(init->IsSnapshotDevice(dm_name, &target));
535     ASSERT_EQ(DeviceMapper::GetTargetType(target.spec), "snapshot");
536 }
537 
TEST_F(SnapshotTest,FlashSuperDuringUpdate)538 TEST_F(SnapshotTest, FlashSuperDuringUpdate) {
539     ASSERT_TRUE(AcquireLock());
540 
541     static const uint64_t kDeviceSize = 1024 * 1024;
542     ASSERT_TRUE(PrepareOneSnapshot(kDeviceSize));
543     ASSERT_TRUE(SimulateReboot());
544 
545     // Reflash the super partition.
546     FormatFakeSuper();
547     ASSERT_TRUE(CreatePartition("test_partition_b", kDeviceSize));
548 
549     auto init = SnapshotManager::NewForFirstStageMount(new TestDeviceInfo(fake_super, "_b"));
550     ASSERT_NE(init, nullptr);
551     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
552     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
553 
554     ASSERT_TRUE(AcquireLock());
555 
556     SnapshotStatus status;
557     ASSERT_TRUE(init->ReadSnapshotStatus(lock_.get(), "test_partition_b", &status));
558 
559     // We should not get a snapshot device now.
560     DeviceMapper::TargetInfo target;
561     auto dm_name = init->GetSnapshotDeviceName("test_partition_b", status);
562     ASSERT_FALSE(init->IsSnapshotDevice(dm_name, &target));
563 
564     // We should see a cancelled update as well.
565     lock_ = nullptr;
566     ASSERT_EQ(sm->ProcessUpdateState(), UpdateState::Cancelled);
567 }
568 
TEST_F(SnapshotTest,FlashSuperDuringMerge)569 TEST_F(SnapshotTest, FlashSuperDuringMerge) {
570     ASSERT_TRUE(AcquireLock());
571 
572     static const uint64_t kDeviceSize = 1024 * 1024;
573     ASSERT_TRUE(PrepareOneSnapshot(kDeviceSize));
574     ASSERT_TRUE(SimulateReboot());
575 
576     auto init = SnapshotManager::NewForFirstStageMount(new TestDeviceInfo(fake_super, "_b"));
577     ASSERT_NE(init, nullptr);
578     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
579     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
580     ASSERT_TRUE(init->InitiateMerge());
581 
582     // Now, reflash super. Note that we haven't called ProcessUpdateState, so the
583     // status is still Merging.
584     ASSERT_TRUE(DeleteSnapshotDevice("test_partition_b"));
585     ASSERT_TRUE(init->image_manager()->UnmapImageIfExists("test_partition_b-cow-img"));
586     FormatFakeSuper();
587     ASSERT_TRUE(CreatePartition("test_partition_b", kDeviceSize));
588     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
589     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
590 
591     // Because the status is Merging, we must call ProcessUpdateState, which should
592     // detect a cancelled update.
593     ASSERT_EQ(sm->ProcessUpdateState(), UpdateState::Cancelled);
594     ASSERT_EQ(sm->GetUpdateState(), UpdateState::None);
595 }
596 
TEST_F(SnapshotTest,UpdateBootControlHal)597 TEST_F(SnapshotTest, UpdateBootControlHal) {
598     ASSERT_TRUE(AcquireLock());
599 
600     ASSERT_TRUE(sm->WriteUpdateState(lock_.get(), UpdateState::None));
601     ASSERT_EQ(test_device->merge_status(), MergeStatus::NONE);
602 
603     ASSERT_TRUE(sm->WriteUpdateState(lock_.get(), UpdateState::Initiated));
604     ASSERT_EQ(test_device->merge_status(), MergeStatus::NONE);
605 
606     ASSERT_TRUE(sm->WriteUpdateState(lock_.get(), UpdateState::Unverified));
607     ASSERT_EQ(test_device->merge_status(), MergeStatus::SNAPSHOTTED);
608 
609     ASSERT_TRUE(sm->WriteUpdateState(lock_.get(), UpdateState::Merging));
610     ASSERT_EQ(test_device->merge_status(), MergeStatus::MERGING);
611 
612     ASSERT_TRUE(sm->WriteUpdateState(lock_.get(), UpdateState::MergeNeedsReboot));
613     ASSERT_EQ(test_device->merge_status(), MergeStatus::NONE);
614 
615     ASSERT_TRUE(sm->WriteUpdateState(lock_.get(), UpdateState::MergeCompleted));
616     ASSERT_EQ(test_device->merge_status(), MergeStatus::NONE);
617 
618     ASSERT_TRUE(sm->WriteUpdateState(lock_.get(), UpdateState::MergeFailed));
619     ASSERT_EQ(test_device->merge_status(), MergeStatus::MERGING);
620 }
621 
622 enum class Request { UNKNOWN, LOCK_SHARED, LOCK_EXCLUSIVE, UNLOCK, EXIT };
operator <<(std::ostream & os,Request request)623 std::ostream& operator<<(std::ostream& os, Request request) {
624     switch (request) {
625         case Request::LOCK_SHARED:
626             return os << "Shared";
627         case Request::LOCK_EXCLUSIVE:
628             return os << "Exclusive";
629         case Request::UNLOCK:
630             return os << "Unlock";
631         case Request::EXIT:
632             return os << "Exit";
633         case Request::UNKNOWN:
634             [[fallthrough]];
635         default:
636             return os << "Unknown";
637     }
638 }
639 
640 class LockTestConsumer {
641   public:
MakeRequest(Request new_request)642     AssertionResult MakeRequest(Request new_request) {
643         {
644             std::unique_lock<std::mutex> ulock(mutex_);
645             requests_.push_back(new_request);
646         }
647         cv_.notify_all();
648         return AssertionSuccess() << "Request " << new_request << " successful";
649     }
650 
651     template <typename R, typename P>
WaitFulfill(std::chrono::duration<R,P> timeout)652     AssertionResult WaitFulfill(std::chrono::duration<R, P> timeout) {
653         std::unique_lock<std::mutex> ulock(mutex_);
654         if (cv_.wait_for(ulock, timeout, [this] { return requests_.empty(); })) {
655             return AssertionSuccess() << "All requests_ fulfilled.";
656         }
657         return AssertionFailure() << "Timeout waiting for fulfilling " << requests_.size()
658                                   << " request(s), first one is "
659                                   << (requests_.empty() ? Request::UNKNOWN : requests_.front());
660     }
661 
StartHandleRequestsInBackground()662     void StartHandleRequestsInBackground() {
663         future_ = std::async(std::launch::async, &LockTestConsumer::HandleRequests, this);
664     }
665 
666   private:
HandleRequests()667     void HandleRequests() {
668         static constexpr auto consumer_timeout = 3s;
669 
670         auto next_request = Request::UNKNOWN;
671         do {
672             // Peek next request.
673             {
674                 std::unique_lock<std::mutex> ulock(mutex_);
675                 if (cv_.wait_for(ulock, consumer_timeout, [this] { return !requests_.empty(); })) {
676                     next_request = requests_.front();
677                 } else {
678                     next_request = Request::EXIT;
679                 }
680             }
681 
682             // Handle next request.
683             switch (next_request) {
684                 case Request::LOCK_SHARED: {
685                     lock_ = sm->LockShared();
686                 } break;
687                 case Request::LOCK_EXCLUSIVE: {
688                     lock_ = sm->LockExclusive();
689                 } break;
690                 case Request::EXIT:
691                     [[fallthrough]];
692                 case Request::UNLOCK: {
693                     lock_.reset();
694                 } break;
695                 case Request::UNKNOWN:
696                     [[fallthrough]];
697                 default:
698                     break;
699             }
700 
701             // Pop next request. This thread is the only thread that
702             // pops from the front of the requests_ deque.
703             {
704                 std::unique_lock<std::mutex> ulock(mutex_);
705                 if (next_request == Request::EXIT) {
706                     requests_.clear();
707                 } else {
708                     requests_.pop_front();
709                 }
710             }
711             cv_.notify_all();
712         } while (next_request != Request::EXIT);
713     }
714 
715     std::mutex mutex_;
716     std::condition_variable cv_;
717     std::deque<Request> requests_;
718     std::unique_ptr<SnapshotManager::LockedFile> lock_;
719     std::future<void> future_;
720 };
721 
722 class LockTest : public ::testing::Test {
723   public:
SetUp()724     void SetUp() {
725         first_consumer.StartHandleRequestsInBackground();
726         second_consumer.StartHandleRequestsInBackground();
727     }
728 
TearDown()729     void TearDown() {
730         EXPECT_TRUE(first_consumer.MakeRequest(Request::EXIT));
731         EXPECT_TRUE(second_consumer.MakeRequest(Request::EXIT));
732     }
733 
734     static constexpr auto request_timeout = 500ms;
735     LockTestConsumer first_consumer;
736     LockTestConsumer second_consumer;
737 };
738 
TEST_F(LockTest,SharedShared)739 TEST_F(LockTest, SharedShared) {
740     ASSERT_TRUE(first_consumer.MakeRequest(Request::LOCK_SHARED));
741     ASSERT_TRUE(first_consumer.WaitFulfill(request_timeout));
742     ASSERT_TRUE(second_consumer.MakeRequest(Request::LOCK_SHARED));
743     ASSERT_TRUE(second_consumer.WaitFulfill(request_timeout));
744 }
745 
746 using LockTestParam = std::pair<Request, Request>;
747 class LockTestP : public LockTest, public ::testing::WithParamInterface<LockTestParam> {};
TEST_P(LockTestP,Test)748 TEST_P(LockTestP, Test) {
749     ASSERT_TRUE(first_consumer.MakeRequest(GetParam().first));
750     ASSERT_TRUE(first_consumer.WaitFulfill(request_timeout));
751     ASSERT_TRUE(second_consumer.MakeRequest(GetParam().second));
752     ASSERT_FALSE(second_consumer.WaitFulfill(request_timeout))
753             << "Should not be able to " << GetParam().second << " while separate thread "
754             << GetParam().first;
755     ASSERT_TRUE(first_consumer.MakeRequest(Request::UNLOCK));
756     ASSERT_TRUE(second_consumer.WaitFulfill(request_timeout))
757             << "Should be able to hold lock that is released by separate thread";
758 }
759 INSTANTIATE_TEST_SUITE_P(
760         LockTest, LockTestP,
761         testing::Values(LockTestParam{Request::LOCK_EXCLUSIVE, Request::LOCK_EXCLUSIVE},
762                         LockTestParam{Request::LOCK_EXCLUSIVE, Request::LOCK_SHARED},
763                         LockTestParam{Request::LOCK_SHARED, Request::LOCK_EXCLUSIVE}),
__anon4de4482e0302(const testing::TestParamInfo<LockTestP::ParamType>& info) 764         [](const testing::TestParamInfo<LockTestP::ParamType>& info) {
765             std::stringstream ss;
766             ss << info.param.first << info.param.second;
767             return ss.str();
768         });
769 
770 class SnapshotUpdateTest : public SnapshotTest {
771   public:
SetUp()772     void SetUp() override {
773         if (!is_virtual_ab_) GTEST_SKIP() << "Test for Virtual A/B devices only";
774 
775         SnapshotTest::SetUp();
776         Cleanup();
777 
778         // Cleanup() changes slot suffix, so initialize it again.
779         test_device->set_slot_suffix("_a");
780 
781         opener_ = std::make_unique<TestPartitionOpener>(fake_super);
782 
783         // Create a fake update package metadata.
784         // Not using full name "system", "vendor", "product" because these names collide with the
785         // mapped partitions on the running device.
786         // Each test modifies manifest_ slightly to indicate changes to the partition layout.
787         group_ = manifest_.mutable_dynamic_partition_metadata()->add_groups();
788         group_->set_name("group");
789         group_->set_size(kGroupSize);
790         group_->add_partition_names("sys");
791         group_->add_partition_names("vnd");
792         group_->add_partition_names("prd");
793         sys_ = manifest_.add_partitions();
794         sys_->set_partition_name("sys");
795         SetSize(sys_, 3_MiB);
796         vnd_ = manifest_.add_partitions();
797         vnd_->set_partition_name("vnd");
798         SetSize(vnd_, 3_MiB);
799         prd_ = manifest_.add_partitions();
800         prd_->set_partition_name("prd");
801         SetSize(prd_, 3_MiB);
802 
803         // Initialize source partition metadata using |manifest_|.
804         src_ = MetadataBuilder::New(*opener_, "super", 0);
805         ASSERT_NE(src_, nullptr);
806         ASSERT_TRUE(FillFakeMetadata(src_.get(), manifest_, "_a"));
807         // Add sys_b which is like system_other.
808         ASSERT_TRUE(src_->AddGroup("group_b", kGroupSize));
809         auto partition = src_->AddPartition("sys_b", "group_b", 0);
810         ASSERT_NE(nullptr, partition);
811         ASSERT_TRUE(src_->ResizePartition(partition, 1_MiB));
812         auto metadata = src_->Export();
813         ASSERT_NE(nullptr, metadata);
814         ASSERT_TRUE(UpdatePartitionTable(*opener_, "super", *metadata.get(), 0));
815 
816         // Map source partitions. Additionally, map sys_b to simulate system_other after flashing.
817         std::string path;
818         for (const auto& name : {"sys_a", "vnd_a", "prd_a", "sys_b"}) {
819             ASSERT_TRUE(CreateLogicalPartition(
820                     CreateLogicalPartitionParams{
821                             .block_device = fake_super,
822                             .metadata_slot = 0,
823                             .partition_name = name,
824                             .timeout_ms = 1s,
825                             .partition_opener = opener_.get(),
826                     },
827                     &path));
828             ASSERT_TRUE(WriteRandomData(path));
829             auto hash = GetHash(path);
830             ASSERT_TRUE(hash.has_value());
831             hashes_[name] = *hash;
832         }
833     }
TearDown()834     void TearDown() override {
835         if (!is_virtual_ab_) return;
836 
837         Cleanup();
838         SnapshotTest::TearDown();
839     }
Cleanup()840     void Cleanup() {
841         if (!image_manager_) {
842             InitializeState();
843         }
844         MountMetadata();
845         for (const auto& suffix : {"_a", "_b"}) {
846             test_device->set_slot_suffix(suffix);
847             EXPECT_TRUE(sm->CancelUpdate()) << suffix;
848         }
849         EXPECT_TRUE(UnmapAll());
850     }
851 
IsPartitionUnchanged(const std::string & name)852     AssertionResult IsPartitionUnchanged(const std::string& name) {
853         std::string path;
854         if (!dm_.GetDmDevicePathByName(name, &path)) {
855             return AssertionFailure() << "Path of " << name << " cannot be determined";
856         }
857         auto hash = GetHash(path);
858         if (!hash.has_value()) {
859             return AssertionFailure() << "Cannot read partition " << name << ": " << path;
860         }
861         auto it = hashes_.find(name);
862         if (it == hashes_.end()) {
863             return AssertionFailure() << "No existing hash for " << name << ". Bad test code?";
864         }
865         if (it->second != *hash) {
866             return AssertionFailure() << "Content of " << name << " has changed";
867         }
868         return AssertionSuccess();
869     }
870 
GetSnapshotSize(const std::string & name)871     std::optional<uint64_t> GetSnapshotSize(const std::string& name) {
872         if (!AcquireLock()) {
873             return std::nullopt;
874         }
875         auto local_lock = std::move(lock_);
876 
877         SnapshotStatus status;
878         if (!sm->ReadSnapshotStatus(local_lock.get(), name, &status)) {
879             return std::nullopt;
880         }
881         return status.snapshot_size();
882     }
883 
UnmapAll()884     AssertionResult UnmapAll() {
885         for (const auto& name : {"sys", "vnd", "prd"}) {
886             if (!dm_.DeleteDeviceIfExists(name + "_a"s)) {
887                 return AssertionFailure() << "Cannot unmap " << name << "_a";
888             }
889             if (!DeleteSnapshotDevice(name + "_b"s)) {
890                 return AssertionFailure() << "Cannot delete snapshot " << name << "_b";
891             }
892         }
893         return AssertionSuccess();
894     }
895 
MapUpdateSnapshot(const std::string & name,std::string * path=nullptr)896     AssertionResult MapUpdateSnapshot(const std::string& name, std::string* path = nullptr) {
897         std::string real_path;
898         if (!sm->MapUpdateSnapshot(
899                     CreateLogicalPartitionParams{
900                             .block_device = fake_super,
901                             .metadata_slot = 1,
902                             .partition_name = name,
903                             .timeout_ms = 10s,
904                             .partition_opener = opener_.get(),
905                     },
906                     &real_path)) {
907             return AssertionFailure() << "Unable to map snapshot " << name;
908         }
909         if (path) {
910             *path = real_path;
911         }
912         return AssertionSuccess() << "Mapped snapshot " << name << " to " << real_path;
913     }
914 
WriteSnapshotAndHash(const std::string & name,std::optional<size_t> size=std::nullopt)915     AssertionResult WriteSnapshotAndHash(const std::string& name,
916                                          std::optional<size_t> size = std::nullopt) {
917         std::string path;
918         auto res = MapUpdateSnapshot(name, &path);
919         if (!res) {
920             return res;
921         }
922 
923         std::string size_string = size ? (std::to_string(*size) + " bytes") : "";
924 
925         if (!WriteRandomData(path, size, &hashes_[name])) {
926             return AssertionFailure() << "Unable to write " << size_string << " to " << path
927                                       << " for partition " << name;
928         }
929 
930         return AssertionSuccess() << "Written " << size_string << " to " << path
931                                   << " for snapshot partition " << name
932                                   << ", hash: " << hashes_[name];
933     }
934 
MapUpdateSnapshots(const std::vector<std::string> & names={"sys_b", "vnd_b", "prd_b"})935     AssertionResult MapUpdateSnapshots(const std::vector<std::string>& names = {"sys_b", "vnd_b",
936                                                                                 "prd_b"}) {
937         for (const auto& name : names) {
938             auto res = MapUpdateSnapshot(name);
939             if (!res) {
940                 return res;
941             }
942         }
943         return AssertionSuccess();
944     }
945 
946     // Create fake install operations to grow the COW device size.
AddOperation(PartitionUpdate * partition_update,uint64_t size_bytes=0)947     void AddOperation(PartitionUpdate* partition_update, uint64_t size_bytes = 0) {
948         auto e = partition_update->add_operations()->add_dst_extents();
949         e->set_start_block(0);
950         if (size_bytes == 0) {
951             size_bytes = GetSize(partition_update);
952         }
953         e->set_num_blocks(size_bytes / manifest_.block_size());
954     }
955 
AddOperationForPartitions(std::vector<PartitionUpdate * > partitions={})956     void AddOperationForPartitions(std::vector<PartitionUpdate*> partitions = {}) {
957         if (partitions.empty()) {
958             partitions = {sys_, vnd_, prd_};
959         }
960         for (auto* partition : partitions) {
961             AddOperation(partition);
962         }
963     }
964 
965     std::unique_ptr<TestPartitionOpener> opener_;
966     DeltaArchiveManifest manifest_;
967     std::unique_ptr<MetadataBuilder> src_;
968     std::map<std::string, std::string> hashes_;
969 
970     PartitionUpdate* sys_ = nullptr;
971     PartitionUpdate* vnd_ = nullptr;
972     PartitionUpdate* prd_ = nullptr;
973     DynamicPartitionGroup* group_ = nullptr;
974 };
975 
976 // Test full update flow executed by update_engine. Some partitions uses super empty space,
977 // some uses images, and some uses both.
978 // Also test UnmapUpdateSnapshot unmaps everything.
979 // Also test first stage mount and merge after this.
TEST_F(SnapshotUpdateTest,FullUpdateFlow)980 TEST_F(SnapshotUpdateTest, FullUpdateFlow) {
981     // OTA client blindly unmaps all partitions that are possibly mapped.
982     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
983         ASSERT_TRUE(sm->UnmapUpdateSnapshot(name));
984     }
985 
986     // Grow all partitions.
987     constexpr uint64_t partition_size = 3788_KiB;
988     SetSize(sys_, partition_size);
989     SetSize(vnd_, partition_size);
990     SetSize(prd_, partition_size);
991 
992     AddOperationForPartitions();
993 
994     // Execute the update.
995     ASSERT_TRUE(sm->BeginUpdate());
996     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
997 
998     // Test that partitions prioritize using space in super.
999     auto tgt = MetadataBuilder::New(*opener_, "super", 1);
1000     ASSERT_NE(tgt, nullptr);
1001     ASSERT_NE(nullptr, tgt->FindPartition("sys_b-cow"));
1002     ASSERT_NE(nullptr, tgt->FindPartition("vnd_b-cow"));
1003     ASSERT_EQ(nullptr, tgt->FindPartition("prd_b-cow"));
1004 
1005     // Write some data to target partitions.
1006     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
1007         ASSERT_TRUE(WriteSnapshotAndHash(name, partition_size));
1008     }
1009 
1010     // Assert that source partitions aren't affected.
1011     for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
1012         ASSERT_TRUE(IsPartitionUnchanged(name));
1013     }
1014 
1015     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1016 
1017     // Simulate shutting down the device.
1018     ASSERT_TRUE(UnmapAll());
1019 
1020     // After reboot, init does first stage mount.
1021     auto init = SnapshotManager::NewForFirstStageMount(new TestDeviceInfo(fake_super, "_b"));
1022     ASSERT_NE(init, nullptr);
1023     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
1024     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1025 
1026     auto indicator = sm->GetRollbackIndicatorPath();
1027     ASSERT_NE(access(indicator.c_str(), R_OK), 0);
1028 
1029     // Check that the target partitions have the same content.
1030     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
1031         ASSERT_TRUE(IsPartitionUnchanged(name));
1032     }
1033 
1034     // Initiate the merge and wait for it to be completed.
1035     ASSERT_TRUE(init->InitiateMerge());
1036     ASSERT_EQ(UpdateState::MergeCompleted, init->ProcessUpdateState());
1037 
1038     // Check that the target partitions have the same content after the merge.
1039     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
1040         ASSERT_TRUE(IsPartitionUnchanged(name))
1041                 << "Content of " << name << " changes after the merge";
1042     }
1043 }
1044 
1045 // Test that if new system partitions uses empty space in super, that region is not snapshotted.
TEST_F(SnapshotUpdateTest,DirectWriteEmptySpace)1046 TEST_F(SnapshotUpdateTest, DirectWriteEmptySpace) {
1047     GTEST_SKIP() << "b/141889746";
1048     SetSize(sys_, 4_MiB);
1049     // vnd_b and prd_b are unchanged.
1050     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1051     ASSERT_EQ(3_MiB, GetSnapshotSize("sys_b").value_or(0));
1052 }
1053 
1054 // Test that if new system partitions uses space of old vendor partition, that region is
1055 // snapshotted.
TEST_F(SnapshotUpdateTest,SnapshotOldPartitions)1056 TEST_F(SnapshotUpdateTest, SnapshotOldPartitions) {
1057     SetSize(sys_, 4_MiB);  // grows
1058     SetSize(vnd_, 2_MiB);  // shrinks
1059     // prd_b is unchanged
1060     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1061     ASSERT_EQ(4_MiB, GetSnapshotSize("sys_b").value_or(0));
1062 }
1063 
1064 // Test that even if there seem to be empty space in target metadata, COW partition won't take
1065 // it because they are used by old partitions.
TEST_F(SnapshotUpdateTest,CowPartitionDoNotTakeOldPartitions)1066 TEST_F(SnapshotUpdateTest, CowPartitionDoNotTakeOldPartitions) {
1067     SetSize(sys_, 2_MiB);  // shrinks
1068     // vnd_b and prd_b are unchanged.
1069     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1070 
1071     auto tgt = MetadataBuilder::New(*opener_, "super", 1);
1072     ASSERT_NE(nullptr, tgt);
1073     auto metadata = tgt->Export();
1074     ASSERT_NE(nullptr, metadata);
1075     std::vector<std::string> written;
1076     // Write random data to all COW partitions in super
1077     for (auto p : metadata->partitions) {
1078         if (GetPartitionGroupName(metadata->groups[p.group_index]) != kCowGroupName) {
1079             continue;
1080         }
1081         std::string path;
1082         ASSERT_TRUE(CreateLogicalPartition(
1083                 CreateLogicalPartitionParams{
1084                         .block_device = fake_super,
1085                         .metadata = metadata.get(),
1086                         .partition = &p,
1087                         .timeout_ms = 1s,
1088                         .partition_opener = opener_.get(),
1089                 },
1090                 &path));
1091         ASSERT_TRUE(WriteRandomData(path));
1092         written.push_back(GetPartitionName(p));
1093     }
1094     ASSERT_FALSE(written.empty())
1095             << "No COW partitions are created even if there are empty space in super partition";
1096 
1097     // Make sure source partitions aren't affected.
1098     for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
1099         ASSERT_TRUE(IsPartitionUnchanged(name));
1100     }
1101 }
1102 
1103 // Test that it crashes after creating snapshot status file but before creating COW image, then
1104 // calling CreateUpdateSnapshots again works.
TEST_F(SnapshotUpdateTest,SnapshotStatusFileWithoutCow)1105 TEST_F(SnapshotUpdateTest, SnapshotStatusFileWithoutCow) {
1106     // Write some trash snapshot files to simulate leftovers from previous runs.
1107     {
1108         ASSERT_TRUE(AcquireLock());
1109         auto local_lock = std::move(lock_);
1110         SnapshotStatus status;
1111         status.set_name("sys_b");
1112         ASSERT_TRUE(sm->WriteSnapshotStatus(local_lock.get(), status));
1113         ASSERT_TRUE(image_manager_->CreateBackingImage("sys_b-cow-img", 1_MiB,
1114                                                        IImageManager::CREATE_IMAGE_DEFAULT));
1115     }
1116 
1117     // Redo the update.
1118     ASSERT_TRUE(sm->BeginUpdate());
1119     ASSERT_TRUE(sm->UnmapUpdateSnapshot("sys_b"));
1120 
1121     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1122 
1123     // Check that target partitions can be mapped.
1124     EXPECT_TRUE(MapUpdateSnapshots());
1125 }
1126 
1127 // Test that the old partitions are not modified.
TEST_F(SnapshotUpdateTest,TestRollback)1128 TEST_F(SnapshotUpdateTest, TestRollback) {
1129     // Execute the update.
1130     ASSERT_TRUE(sm->BeginUpdate());
1131     ASSERT_TRUE(sm->UnmapUpdateSnapshot("sys_b"));
1132 
1133     AddOperationForPartitions();
1134 
1135     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1136 
1137     // Write some data to target partitions.
1138     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
1139         ASSERT_TRUE(WriteSnapshotAndHash(name));
1140     }
1141 
1142     // Assert that source partitions aren't affected.
1143     for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
1144         ASSERT_TRUE(IsPartitionUnchanged(name));
1145     }
1146 
1147     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1148 
1149     // Simulate shutting down the device.
1150     ASSERT_TRUE(UnmapAll());
1151 
1152     // After reboot, init does first stage mount.
1153     auto init = SnapshotManager::NewForFirstStageMount(new TestDeviceInfo(fake_super, "_b"));
1154     ASSERT_NE(init, nullptr);
1155     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
1156     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1157 
1158     // Check that the target partitions have the same content.
1159     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
1160         ASSERT_TRUE(IsPartitionUnchanged(name));
1161     }
1162 
1163     // Simulate shutting down the device again.
1164     ASSERT_TRUE(UnmapAll());
1165     init = SnapshotManager::NewForFirstStageMount(new TestDeviceInfo(fake_super, "_a"));
1166     ASSERT_NE(init, nullptr);
1167     ASSERT_FALSE(init->NeedSnapshotsInFirstStageMount());
1168     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1169 
1170     // Assert that the source partitions aren't affected.
1171     for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
1172         ASSERT_TRUE(IsPartitionUnchanged(name));
1173     }
1174 }
1175 
1176 // Test that if an update is applied but not booted into, it can be canceled.
TEST_F(SnapshotUpdateTest,CancelAfterApply)1177 TEST_F(SnapshotUpdateTest, CancelAfterApply) {
1178     ASSERT_TRUE(sm->BeginUpdate());
1179     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1180     ASSERT_TRUE(sm->CancelUpdate());
1181 }
1182 
ToIntervals(const std::vector<std::unique_ptr<Extent>> & extents)1183 static std::vector<Interval> ToIntervals(const std::vector<std::unique_ptr<Extent>>& extents) {
1184     std::vector<Interval> ret;
1185     std::transform(extents.begin(), extents.end(), std::back_inserter(ret),
1186                    [](const auto& extent) { return extent->AsLinearExtent()->AsInterval(); });
1187     return ret;
1188 }
1189 
1190 // Test that at the second update, old COW partition spaces are reclaimed.
TEST_F(SnapshotUpdateTest,ReclaimCow)1191 TEST_F(SnapshotUpdateTest, ReclaimCow) {
1192     // Execute the first update.
1193     ASSERT_TRUE(sm->BeginUpdate());
1194     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1195     ASSERT_TRUE(MapUpdateSnapshots());
1196     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1197 
1198     // Simulate shutting down the device.
1199     ASSERT_TRUE(UnmapAll());
1200 
1201     // After reboot, init does first stage mount.
1202     auto init = SnapshotManager::NewForFirstStageMount(new TestDeviceInfo(fake_super, "_b"));
1203     ASSERT_NE(init, nullptr);
1204     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
1205     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1206     init = nullptr;
1207 
1208     // Initiate the merge and wait for it to be completed.
1209     auto new_sm = SnapshotManager::New(new TestDeviceInfo(fake_super, "_b"));
1210     ASSERT_TRUE(new_sm->InitiateMerge());
1211     ASSERT_EQ(UpdateState::MergeCompleted, new_sm->ProcessUpdateState());
1212 
1213     // Execute the second update.
1214     ASSERT_TRUE(new_sm->BeginUpdate());
1215     ASSERT_TRUE(new_sm->CreateUpdateSnapshots(manifest_));
1216 
1217     // Check that the old COW space is reclaimed and does not occupy space of mapped partitions.
1218     auto src = MetadataBuilder::New(*opener_, "super", 1);
1219     ASSERT_NE(src, nullptr);
1220     auto tgt = MetadataBuilder::New(*opener_, "super", 0);
1221     ASSERT_NE(tgt, nullptr);
1222     for (const auto& cow_part_name : {"sys_a-cow", "vnd_a-cow", "prd_a-cow"}) {
1223         auto* cow_part = tgt->FindPartition(cow_part_name);
1224         ASSERT_NE(nullptr, cow_part) << cow_part_name << " does not exist in target metadata";
1225         auto cow_intervals = ToIntervals(cow_part->extents());
1226         for (const auto& old_part_name : {"sys_b", "vnd_b", "prd_b"}) {
1227             auto* old_part = src->FindPartition(old_part_name);
1228             ASSERT_NE(nullptr, old_part) << old_part_name << " does not exist in source metadata";
1229             auto old_intervals = ToIntervals(old_part->extents());
1230 
1231             auto intersect = Interval::Intersect(cow_intervals, old_intervals);
1232             ASSERT_TRUE(intersect.empty()) << "COW uses space of source partitions";
1233         }
1234     }
1235 }
1236 
TEST_F(SnapshotUpdateTest,RetrofitAfterRegularAb)1237 TEST_F(SnapshotUpdateTest, RetrofitAfterRegularAb) {
1238     constexpr auto kRetrofitGroupSize = kGroupSize / 2;
1239 
1240     // Initialize device-mapper / disk
1241     ASSERT_TRUE(UnmapAll());
1242     FormatFakeSuper();
1243 
1244     // Setup source partition metadata to have both _a and _b partitions.
1245     src_ = MetadataBuilder::New(*opener_, "super", 0);
1246     ASSERT_NE(nullptr, src_);
1247     for (const auto& suffix : {"_a"s, "_b"s}) {
1248         ASSERT_TRUE(src_->AddGroup(group_->name() + suffix, kRetrofitGroupSize));
1249         for (const auto& name : {"sys"s, "vnd"s, "prd"s}) {
1250             auto partition = src_->AddPartition(name + suffix, group_->name() + suffix, 0);
1251             ASSERT_NE(nullptr, partition);
1252             ASSERT_TRUE(src_->ResizePartition(partition, 2_MiB));
1253         }
1254     }
1255     auto metadata = src_->Export();
1256     ASSERT_NE(nullptr, metadata);
1257     ASSERT_TRUE(UpdatePartitionTable(*opener_, "super", *metadata.get(), 0));
1258 
1259     // Flash source partitions
1260     std::string path;
1261     for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
1262         ASSERT_TRUE(CreateLogicalPartition(
1263                 CreateLogicalPartitionParams{
1264                         .block_device = fake_super,
1265                         .metadata_slot = 0,
1266                         .partition_name = name,
1267                         .timeout_ms = 1s,
1268                         .partition_opener = opener_.get(),
1269                 },
1270                 &path));
1271         ASSERT_TRUE(WriteRandomData(path));
1272         auto hash = GetHash(path);
1273         ASSERT_TRUE(hash.has_value());
1274         hashes_[name] = *hash;
1275     }
1276 
1277     // Setup manifest.
1278     group_->set_size(kRetrofitGroupSize);
1279     for (auto* partition : {sys_, vnd_, prd_}) {
1280         SetSize(partition, 2_MiB);
1281     }
1282     AddOperationForPartitions();
1283 
1284     ASSERT_TRUE(sm->BeginUpdate());
1285     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1286 
1287     // Test that COW image should not be created for retrofit devices; super
1288     // should be big enough.
1289     ASSERT_FALSE(image_manager_->BackingImageExists("sys_b-cow-img"));
1290     ASSERT_FALSE(image_manager_->BackingImageExists("vnd_b-cow-img"));
1291     ASSERT_FALSE(image_manager_->BackingImageExists("prd_b-cow-img"));
1292 
1293     // Write some data to target partitions.
1294     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
1295         ASSERT_TRUE(WriteSnapshotAndHash(name));
1296     }
1297 
1298     // Assert that source partitions aren't affected.
1299     for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
1300         ASSERT_TRUE(IsPartitionUnchanged(name));
1301     }
1302 
1303     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1304 }
1305 
TEST_F(SnapshotUpdateTest,MergeCannotRemoveCow)1306 TEST_F(SnapshotUpdateTest, MergeCannotRemoveCow) {
1307     // Make source partitions as big as possible to force COW image to be created.
1308     SetSize(sys_, 5_MiB);
1309     SetSize(vnd_, 5_MiB);
1310     SetSize(prd_, 5_MiB);
1311     src_ = MetadataBuilder::New(*opener_, "super", 0);
1312     ASSERT_NE(src_, nullptr);
1313     src_->RemoveGroupAndPartitions(group_->name() + "_a");
1314     src_->RemoveGroupAndPartitions(group_->name() + "_b");
1315     ASSERT_TRUE(FillFakeMetadata(src_.get(), manifest_, "_a"));
1316     auto metadata = src_->Export();
1317     ASSERT_NE(nullptr, metadata);
1318     ASSERT_TRUE(UpdatePartitionTable(*opener_, "super", *metadata.get(), 0));
1319 
1320     // OTA client blindly unmaps all partitions that are possibly mapped.
1321     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
1322         ASSERT_TRUE(sm->UnmapUpdateSnapshot(name));
1323     }
1324 
1325     // Add operations for sys. The whole device is written.
1326     AddOperation(sys_);
1327 
1328     // Execute the update.
1329     ASSERT_TRUE(sm->BeginUpdate());
1330     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1331     ASSERT_TRUE(MapUpdateSnapshots());
1332     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1333 
1334     // Simulate shutting down the device.
1335     ASSERT_TRUE(UnmapAll());
1336 
1337     // After reboot, init does first stage mount.
1338     // Normally we should use NewForFirstStageMount, but if so, "gsid.mapped_image.sys_b-cow-img"
1339     // won't be set.
1340     auto init = SnapshotManager::New(new TestDeviceInfo(fake_super, "_b"));
1341     ASSERT_NE(init, nullptr);
1342     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1343 
1344     // Keep an open handle to the cow device. This should cause the merge to
1345     // be incomplete.
1346     auto cow_path = android::base::GetProperty("gsid.mapped_image.sys_b-cow-img", "");
1347     unique_fd fd(open(cow_path.c_str(), O_RDONLY | O_CLOEXEC));
1348     ASSERT_GE(fd, 0);
1349 
1350     // COW cannot be removed due to open fd, so expect a soft failure.
1351     ASSERT_TRUE(init->InitiateMerge());
1352     ASSERT_EQ(UpdateState::MergeNeedsReboot, init->ProcessUpdateState());
1353 
1354     // Simulate shutting down the device.
1355     fd.reset();
1356     ASSERT_TRUE(UnmapAll());
1357 
1358     // init does first stage mount again.
1359     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1360 
1361     // sys_b should be mapped as a dm-linear device directly.
1362     ASSERT_FALSE(sm->IsSnapshotDevice("sys_b", nullptr));
1363 
1364     // Merge should be able to complete now.
1365     ASSERT_EQ(UpdateState::MergeCompleted, init->ProcessUpdateState());
1366 }
1367 
1368 class MetadataMountedTest : public SnapshotUpdateTest {
1369   public:
SetUp()1370     void SetUp() override {
1371         metadata_dir_ = test_device->GetMetadataDir();
1372         ASSERT_TRUE(ReadDefaultFstab(&fstab_));
1373     }
TearDown()1374     void TearDown() override {
1375         SetUp();
1376         // Remount /metadata
1377         test_device->set_recovery(false);
1378         EXPECT_TRUE(android::fs_mgr::EnsurePathMounted(&fstab_, metadata_dir_));
1379     }
IsMetadataMounted()1380     AssertionResult IsMetadataMounted() {
1381         Fstab mounted_fstab;
1382         if (!ReadFstabFromFile("/proc/mounts", &mounted_fstab)) {
1383             ADD_FAILURE() << "Failed to scan mounted volumes";
1384             return AssertionFailure() << "Failed to scan mounted volumes";
1385         }
1386 
1387         auto entry = GetEntryForPath(&fstab_, metadata_dir_);
1388         if (entry == nullptr) {
1389             return AssertionFailure() << "No mount point found in fstab for path " << metadata_dir_;
1390         }
1391 
1392         auto mv = GetEntryForMountPoint(&mounted_fstab, entry->mount_point);
1393         if (mv == nullptr) {
1394             return AssertionFailure() << metadata_dir_ << " is not mounted";
1395         }
1396         return AssertionSuccess() << metadata_dir_ << " is mounted";
1397     }
1398     std::string metadata_dir_;
1399     Fstab fstab_;
1400 };
1401 
MountMetadata()1402 void MountMetadata() {
1403     MetadataMountedTest().TearDown();
1404 }
1405 
TEST_F(MetadataMountedTest,Android)1406 TEST_F(MetadataMountedTest, Android) {
1407     auto device = sm->EnsureMetadataMounted();
1408     EXPECT_NE(nullptr, device);
1409     device.reset();
1410 
1411     EXPECT_TRUE(IsMetadataMounted());
1412     EXPECT_TRUE(sm->CancelUpdate()) << "Metadata dir should never be unmounted in Android mode";
1413 }
1414 
TEST_F(MetadataMountedTest,Recovery)1415 TEST_F(MetadataMountedTest, Recovery) {
1416     test_device->set_recovery(true);
1417     metadata_dir_ = test_device->GetMetadataDir();
1418 
1419     EXPECT_TRUE(android::fs_mgr::EnsurePathUnmounted(&fstab_, metadata_dir_));
1420     EXPECT_FALSE(IsMetadataMounted());
1421 
1422     auto device = sm->EnsureMetadataMounted();
1423     EXPECT_NE(nullptr, device);
1424     EXPECT_TRUE(IsMetadataMounted());
1425 
1426     device.reset();
1427     EXPECT_FALSE(IsMetadataMounted());
1428 }
1429 
1430 // Test that during a merge, we can wipe data in recovery.
TEST_F(SnapshotUpdateTest,MergeInRecovery)1431 TEST_F(SnapshotUpdateTest, MergeInRecovery) {
1432     // Execute the first update.
1433     ASSERT_TRUE(sm->BeginUpdate());
1434     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1435     ASSERT_TRUE(MapUpdateSnapshots());
1436     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1437 
1438     // Simulate shutting down the device.
1439     ASSERT_TRUE(UnmapAll());
1440 
1441     // After reboot, init does first stage mount.
1442     auto init = SnapshotManager::NewForFirstStageMount(new TestDeviceInfo(fake_super, "_b"));
1443     ASSERT_NE(init, nullptr);
1444     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
1445     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1446     init = nullptr;
1447 
1448     // Initiate the merge and then immediately stop it to simulate a reboot.
1449     auto new_sm = SnapshotManager::New(new TestDeviceInfo(fake_super, "_b"));
1450     ASSERT_TRUE(new_sm->InitiateMerge());
1451     ASSERT_TRUE(UnmapAll());
1452 
1453     // Simulate a reboot into recovery.
1454     auto test_device = std::make_unique<TestDeviceInfo>(fake_super, "_b");
1455     test_device->set_recovery(true);
1456     new_sm = SnapshotManager::NewForFirstStageMount(test_device.release());
1457 
1458     ASSERT_TRUE(new_sm->HandleImminentDataWipe());
1459     ASSERT_EQ(new_sm->GetUpdateState(), UpdateState::None);
1460 }
1461 
1462 // Test that a merge does not clear the snapshot state in fastboot.
TEST_F(SnapshotUpdateTest,MergeInFastboot)1463 TEST_F(SnapshotUpdateTest, MergeInFastboot) {
1464     // Execute the first update.
1465     ASSERT_TRUE(sm->BeginUpdate());
1466     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1467     ASSERT_TRUE(MapUpdateSnapshots());
1468     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1469 
1470     // Simulate shutting down the device.
1471     ASSERT_TRUE(UnmapAll());
1472 
1473     // After reboot, init does first stage mount.
1474     auto init = SnapshotManager::NewForFirstStageMount(new TestDeviceInfo(fake_super, "_b"));
1475     ASSERT_NE(init, nullptr);
1476     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
1477     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1478     init = nullptr;
1479 
1480     // Initiate the merge and then immediately stop it to simulate a reboot.
1481     auto new_sm = SnapshotManager::New(new TestDeviceInfo(fake_super, "_b"));
1482     ASSERT_TRUE(new_sm->InitiateMerge());
1483     ASSERT_TRUE(UnmapAll());
1484 
1485     // Simulate a reboot into recovery.
1486     auto test_device = std::make_unique<TestDeviceInfo>(fake_super, "_b");
1487     test_device->set_recovery(true);
1488     new_sm = SnapshotManager::NewForFirstStageMount(test_device.release());
1489 
1490     ASSERT_TRUE(new_sm->FinishMergeInRecovery());
1491 
1492     auto mount = new_sm->EnsureMetadataMounted();
1493     ASSERT_TRUE(mount && mount->HasDevice());
1494     ASSERT_EQ(new_sm->ProcessUpdateState(), UpdateState::MergeCompleted);
1495 
1496     // Finish the merge in a normal boot.
1497     test_device = std::make_unique<TestDeviceInfo>(fake_super, "_b");
1498     init = SnapshotManager::NewForFirstStageMount(test_device.release());
1499     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1500     init = nullptr;
1501 
1502     test_device = std::make_unique<TestDeviceInfo>(fake_super, "_b");
1503     new_sm = SnapshotManager::NewForFirstStageMount(test_device.release());
1504     ASSERT_EQ(new_sm->ProcessUpdateState(), UpdateState::MergeCompleted);
1505     ASSERT_EQ(new_sm->ProcessUpdateState(), UpdateState::None);
1506 }
1507 
1508 // Test that after an OTA, before a merge, we can wipe data in recovery.
TEST_F(SnapshotUpdateTest,DataWipeRollbackInRecovery)1509 TEST_F(SnapshotUpdateTest, DataWipeRollbackInRecovery) {
1510     // Execute the first update.
1511     ASSERT_TRUE(sm->BeginUpdate());
1512     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1513     ASSERT_TRUE(MapUpdateSnapshots());
1514     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1515 
1516     // Simulate shutting down the device.
1517     ASSERT_TRUE(UnmapAll());
1518 
1519     // Simulate a reboot into recovery.
1520     auto test_device = new TestDeviceInfo(fake_super, "_b");
1521     test_device->set_recovery(true);
1522     auto new_sm = SnapshotManager::NewForFirstStageMount(test_device);
1523 
1524     ASSERT_TRUE(new_sm->HandleImminentDataWipe());
1525     // Manually mount metadata so that we can call GetUpdateState() below.
1526     MountMetadata();
1527     EXPECT_EQ(new_sm->GetUpdateState(), UpdateState::Unverified);
1528     EXPECT_TRUE(test_device->IsSlotUnbootable(1));
1529     EXPECT_FALSE(test_device->IsSlotUnbootable(0));
1530 }
1531 
1532 // Test that after an OTA and a bootloader rollback with no merge, we can wipe
1533 // data in recovery.
TEST_F(SnapshotUpdateTest,DataWipeAfterRollback)1534 TEST_F(SnapshotUpdateTest, DataWipeAfterRollback) {
1535     // Execute the first update.
1536     ASSERT_TRUE(sm->BeginUpdate());
1537     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1538     ASSERT_TRUE(MapUpdateSnapshots());
1539     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1540 
1541     // Simulate shutting down the device.
1542     ASSERT_TRUE(UnmapAll());
1543 
1544     // Simulate a rollback, with reboot into recovery.
1545     auto test_device = new TestDeviceInfo(fake_super, "_a");
1546     test_device->set_recovery(true);
1547     auto new_sm = SnapshotManager::NewForFirstStageMount(test_device);
1548 
1549     ASSERT_TRUE(new_sm->HandleImminentDataWipe());
1550     EXPECT_EQ(new_sm->GetUpdateState(), UpdateState::None);
1551     EXPECT_FALSE(test_device->IsSlotUnbootable(0));
1552     EXPECT_FALSE(test_device->IsSlotUnbootable(1));
1553 }
1554 
1555 // Test update package that requests data wipe.
TEST_F(SnapshotUpdateTest,DataWipeRequiredInPackage)1556 TEST_F(SnapshotUpdateTest, DataWipeRequiredInPackage) {
1557     AddOperationForPartitions();
1558     // Execute the update.
1559     ASSERT_TRUE(sm->BeginUpdate());
1560     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1561 
1562     // Write some data to target partitions.
1563     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
1564         ASSERT_TRUE(WriteSnapshotAndHash(name)) << name;
1565     }
1566 
1567     ASSERT_TRUE(sm->FinishedSnapshotWrites(true /* wipe */));
1568 
1569     // Simulate shutting down the device.
1570     ASSERT_TRUE(UnmapAll());
1571 
1572     // Simulate a reboot into recovery.
1573     auto test_device = new TestDeviceInfo(fake_super, "_b");
1574     test_device->set_recovery(true);
1575     auto new_sm = SnapshotManager::NewForFirstStageMount(test_device);
1576 
1577     ASSERT_TRUE(new_sm->HandleImminentDataWipe());
1578     // Manually mount metadata so that we can call GetUpdateState() below.
1579     MountMetadata();
1580     EXPECT_EQ(new_sm->GetUpdateState(), UpdateState::None);
1581     ASSERT_FALSE(test_device->IsSlotUnbootable(1));
1582     ASSERT_FALSE(test_device->IsSlotUnbootable(0));
1583 
1584     // Now reboot into new slot.
1585     test_device = new TestDeviceInfo(fake_super, "_b");
1586     auto init = SnapshotManager::NewForFirstStageMount(test_device);
1587     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1588     // Verify that we are on the downgraded build.
1589     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
1590         ASSERT_TRUE(IsPartitionUnchanged(name)) << name;
1591     }
1592 }
1593 
TEST_F(SnapshotUpdateTest,Hashtree)1594 TEST_F(SnapshotUpdateTest, Hashtree) {
1595     constexpr auto partition_size = 4_MiB;
1596     constexpr auto data_size = 3_MiB;
1597     constexpr auto hashtree_size = 512_KiB;
1598     constexpr auto fec_size = partition_size - data_size - hashtree_size;
1599 
1600     const auto block_size = manifest_.block_size();
1601     SetSize(sys_, partition_size);
1602     AddOperation(sys_, data_size);
1603 
1604     // Set hastree extents.
1605     sys_->mutable_hash_tree_data_extent()->set_start_block(0);
1606     sys_->mutable_hash_tree_data_extent()->set_num_blocks(data_size / block_size);
1607 
1608     sys_->mutable_hash_tree_extent()->set_start_block(data_size / block_size);
1609     sys_->mutable_hash_tree_extent()->set_num_blocks(hashtree_size / block_size);
1610 
1611     // Set FEC extents.
1612     sys_->mutable_fec_data_extent()->set_start_block(0);
1613     sys_->mutable_fec_data_extent()->set_num_blocks((data_size + hashtree_size) / block_size);
1614 
1615     sys_->mutable_fec_extent()->set_start_block((data_size + hashtree_size) / block_size);
1616     sys_->mutable_fec_extent()->set_num_blocks(fec_size / block_size);
1617 
1618     ASSERT_TRUE(sm->BeginUpdate());
1619     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1620 
1621     // Map and write some data to target partition.
1622     ASSERT_TRUE(MapUpdateSnapshots({"vnd_b", "prd_b"}));
1623     ASSERT_TRUE(WriteSnapshotAndHash("sys_b", partition_size));
1624 
1625     // Finish update.
1626     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1627 
1628     // Simulate shutting down the device.
1629     ASSERT_TRUE(UnmapAll());
1630 
1631     // After reboot, init does first stage mount.
1632     auto init = SnapshotManager::NewForFirstStageMount(new TestDeviceInfo(fake_super, "_b"));
1633     ASSERT_NE(init, nullptr);
1634     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
1635     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1636 
1637     // Check that the target partition have the same content. Hashtree and FEC extents
1638     // should be accounted for.
1639     ASSERT_TRUE(IsPartitionUnchanged("sys_b"));
1640 }
1641 
1642 // Test for overflow bit after update
TEST_F(SnapshotUpdateTest,Overflow)1643 TEST_F(SnapshotUpdateTest, Overflow) {
1644     const auto actual_write_size = GetSize(sys_);
1645     const auto declared_write_size = actual_write_size - 1_MiB;
1646 
1647     AddOperation(sys_, declared_write_size);
1648 
1649     // Execute the update.
1650     ASSERT_TRUE(sm->BeginUpdate());
1651     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1652 
1653     // Map and write some data to target partitions.
1654     ASSERT_TRUE(MapUpdateSnapshots({"vnd_b", "prd_b"}));
1655     ASSERT_TRUE(WriteSnapshotAndHash("sys_b", actual_write_size));
1656 
1657     std::vector<android::dm::DeviceMapper::TargetInfo> table;
1658     ASSERT_TRUE(DeviceMapper::Instance().GetTableStatus("sys_b", &table));
1659     ASSERT_EQ(1u, table.size());
1660     EXPECT_TRUE(table[0].IsOverflowSnapshot());
1661 
1662     ASSERT_FALSE(sm->FinishedSnapshotWrites(false))
1663             << "FinishedSnapshotWrites should detect overflow of CoW device.";
1664 }
1665 
TEST_F(SnapshotUpdateTest,LowSpace)1666 TEST_F(SnapshotUpdateTest, LowSpace) {
1667     static constexpr auto kMaxFree = 10_MiB;
1668     auto userdata = std::make_unique<LowSpaceUserdata>();
1669     ASSERT_TRUE(userdata->Init(kMaxFree));
1670 
1671     // Grow all partitions to 5_MiB, total 15_MiB. This requires 15 MiB of CoW space. After
1672     // using the empty space in super (< 1 MiB), it uses at least 14 MiB of /userdata space.
1673     constexpr uint64_t partition_size = 5_MiB;
1674     SetSize(sys_, partition_size);
1675     SetSize(vnd_, partition_size);
1676     SetSize(prd_, partition_size);
1677 
1678     AddOperationForPartitions();
1679 
1680     // Execute the update.
1681     ASSERT_TRUE(sm->BeginUpdate());
1682     auto res = sm->CreateUpdateSnapshots(manifest_);
1683     ASSERT_FALSE(res);
1684     ASSERT_EQ(Return::ErrorCode::NO_SPACE, res.error_code());
1685     ASSERT_GE(res.required_size(), 14_MiB);
1686     ASSERT_LT(res.required_size(), 15_MiB);
1687 }
1688 
1689 class FlashAfterUpdateTest : public SnapshotUpdateTest,
1690                              public WithParamInterface<std::tuple<uint32_t, bool>> {
1691   public:
InitiateMerge(const std::string & slot_suffix)1692     AssertionResult InitiateMerge(const std::string& slot_suffix) {
1693         auto sm = SnapshotManager::New(new TestDeviceInfo(fake_super, slot_suffix));
1694         if (!sm->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_)) {
1695             return AssertionFailure() << "Cannot CreateLogicalAndSnapshotPartitions";
1696         }
1697         if (!sm->InitiateMerge()) {
1698             return AssertionFailure() << "Cannot initiate merge";
1699         }
1700         return AssertionSuccess();
1701     }
1702 };
1703 
TEST_P(FlashAfterUpdateTest,FlashSlotAfterUpdate)1704 TEST_P(FlashAfterUpdateTest, FlashSlotAfterUpdate) {
1705     if (!is_virtual_ab_) GTEST_SKIP() << "Test for Virtual A/B devices only";
1706 
1707     // OTA client blindly unmaps all partitions that are possibly mapped.
1708     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
1709         ASSERT_TRUE(sm->UnmapUpdateSnapshot(name));
1710     }
1711 
1712     // Execute the update.
1713     ASSERT_TRUE(sm->BeginUpdate());
1714     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1715     ASSERT_TRUE(MapUpdateSnapshots());
1716     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1717 
1718     // Simulate shutting down the device.
1719     ASSERT_TRUE(UnmapAll());
1720 
1721     bool after_merge = std::get<1>(GetParam());
1722     if (after_merge) {
1723         ASSERT_TRUE(InitiateMerge("_b"));
1724         // Simulate shutting down the device after merge has initiated.
1725         ASSERT_TRUE(UnmapAll());
1726     }
1727 
1728     auto flashed_slot = std::get<0>(GetParam());
1729     auto flashed_slot_suffix = SlotSuffixForSlotNumber(flashed_slot);
1730 
1731     // Simulate flashing |flashed_slot|. This clears the UPDATED flag.
1732     auto flashed_builder = MetadataBuilder::New(*opener_, "super", flashed_slot);
1733     ASSERT_NE(flashed_builder, nullptr);
1734     flashed_builder->RemoveGroupAndPartitions(group_->name() + flashed_slot_suffix);
1735     flashed_builder->RemoveGroupAndPartitions(kCowGroupName);
1736     ASSERT_TRUE(FillFakeMetadata(flashed_builder.get(), manifest_, flashed_slot_suffix));
1737 
1738     // Deliberately remove a partition from this build so that
1739     // InitiateMerge do not switch state to "merging". This is possible in
1740     // practice because the list of dynamic partitions may change.
1741     ASSERT_NE(nullptr, flashed_builder->FindPartition("prd" + flashed_slot_suffix));
1742     flashed_builder->RemovePartition("prd" + flashed_slot_suffix);
1743 
1744     // Note that fastbootd always updates the partition table of both slots.
1745     auto flashed_metadata = flashed_builder->Export();
1746     ASSERT_NE(nullptr, flashed_metadata);
1747     ASSERT_TRUE(UpdatePartitionTable(*opener_, "super", *flashed_metadata, 0));
1748     ASSERT_TRUE(UpdatePartitionTable(*opener_, "super", *flashed_metadata, 1));
1749 
1750     std::string path;
1751     for (const auto& name : {"sys", "vnd"}) {
1752         ASSERT_TRUE(CreateLogicalPartition(
1753                 CreateLogicalPartitionParams{
1754                         .block_device = fake_super,
1755                         .metadata_slot = flashed_slot,
1756                         .partition_name = name + flashed_slot_suffix,
1757                         .timeout_ms = 1s,
1758                         .partition_opener = opener_.get(),
1759                 },
1760                 &path));
1761         ASSERT_TRUE(WriteRandomData(path));
1762         auto hash = GetHash(path);
1763         ASSERT_TRUE(hash.has_value());
1764         hashes_[name + flashed_slot_suffix] = *hash;
1765     }
1766 
1767     // Simulate shutting down the device after flash.
1768     ASSERT_TRUE(UnmapAll());
1769 
1770     // Simulate reboot. After reboot, init does first stage mount.
1771     auto init = SnapshotManager::NewForFirstStageMount(
1772             new TestDeviceInfo(fake_super, flashed_slot_suffix));
1773     ASSERT_NE(init, nullptr);
1774 
1775     if (flashed_slot && after_merge) {
1776         ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
1777     }
1778     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1779 
1780     // Check that the target partitions have the same content.
1781     for (const auto& name : {"sys", "vnd"}) {
1782         ASSERT_TRUE(IsPartitionUnchanged(name + flashed_slot_suffix));
1783     }
1784 
1785     // There should be no snapshot to merge.
1786     auto new_sm = SnapshotManager::New(new TestDeviceInfo(fake_super, flashed_slot_suffix));
1787     // update_enigne calls ProcessUpdateState first -- should see Cancelled.
1788     ASSERT_EQ(UpdateState::Cancelled, new_sm->ProcessUpdateState());
1789 
1790     // Next OTA calls CancelUpdate no matter what.
1791     ASSERT_TRUE(new_sm->CancelUpdate());
1792 }
1793 
1794 INSTANTIATE_TEST_SUITE_P(Snapshot, FlashAfterUpdateTest, Combine(Values(0, 1), Bool()),
__anon4de4482e0502(const TestParamInfo<FlashAfterUpdateTest::ParamType>& info) 1795                          [](const TestParamInfo<FlashAfterUpdateTest::ParamType>& info) {
1796                              return "Flash"s + (std::get<0>(info.param) ? "New"s : "Old"s) +
1797                                     "Slot"s + (std::get<1>(info.param) ? "After"s : "Before"s) +
1798                                     "Merge"s;
1799                          });
1800 
1801 // Test behavior of ImageManager::Create on low space scenario. These tests assumes image manager
1802 // uses /data as backup device.
1803 class ImageManagerTest : public SnapshotTest, public WithParamInterface<uint64_t> {
1804   protected:
SetUp()1805     void SetUp() override {
1806         if (!is_virtual_ab_) GTEST_SKIP() << "Test for Virtual A/B devices only";
1807 
1808         SnapshotTest::SetUp();
1809         userdata_ = std::make_unique<LowSpaceUserdata>();
1810         ASSERT_TRUE(userdata_->Init(GetParam()));
1811     }
TearDown()1812     void TearDown() override {
1813         if (!is_virtual_ab_) return;
1814         return;  // BUG(149738928)
1815 
1816         EXPECT_TRUE(!image_manager_->BackingImageExists(kImageName) ||
1817                     image_manager_->DeleteBackingImage(kImageName));
1818     }
1819     static constexpr const char* kImageName = "my_image";
1820     std::unique_ptr<LowSpaceUserdata> userdata_;
1821 };
1822 
TEST_P(ImageManagerTest,CreateImageEnoughAvailSpace)1823 TEST_P(ImageManagerTest, CreateImageEnoughAvailSpace) {
1824     if (userdata_->available_space() == 0) {
1825         GTEST_SKIP() << "/data is full (" << userdata_->available_space()
1826                      << " bytes available), skipping";
1827     }
1828     ASSERT_TRUE(image_manager_->CreateBackingImage(kImageName, userdata_->available_space(),
1829                                                    IImageManager::CREATE_IMAGE_DEFAULT))
1830             << "Should be able to create image with size = " << userdata_->available_space()
1831             << " bytes";
1832     ASSERT_TRUE(image_manager_->DeleteBackingImage(kImageName))
1833             << "Should be able to delete created image";
1834 }
1835 
TEST_P(ImageManagerTest,CreateImageNoSpace)1836 TEST_P(ImageManagerTest, CreateImageNoSpace) {
1837     uint64_t to_allocate = userdata_->free_space() + userdata_->bsize();
1838     auto res = image_manager_->CreateBackingImage(kImageName, to_allocate,
1839                                                   IImageManager::CREATE_IMAGE_DEFAULT);
1840     ASSERT_FALSE(res) << "Should not be able to create image with size = " << to_allocate
1841                       << " bytes because only " << userdata_->free_space() << " bytes are free";
1842     ASSERT_EQ(FiemapStatus::ErrorCode::NO_SPACE, res.error_code()) << res.string();
1843 }
1844 
ImageManagerTestParams()1845 std::vector<uint64_t> ImageManagerTestParams() {
1846     std::vector<uint64_t> ret;
1847     for (uint64_t size = 1_MiB; size <= 512_MiB; size *= 2) {
1848         ret.push_back(size);
1849     }
1850     return ret;
1851 }
1852 
1853 INSTANTIATE_TEST_SUITE_P(ImageManagerTest, ImageManagerTest, ValuesIn(ImageManagerTestParams()));
1854 
1855 }  // namespace snapshot
1856 }  // namespace android
1857 
1858 using namespace android::snapshot;
1859 
Mkdir(const std::string & path)1860 bool Mkdir(const std::string& path) {
1861     if (mkdir(path.c_str(), 0700) && errno != EEXIST) {
1862         std::cerr << "Could not mkdir " << path << ": " << strerror(errno) << std::endl;
1863         return false;
1864     }
1865     return true;
1866 }
1867 
main(int argc,char ** argv)1868 int main(int argc, char** argv) {
1869     ::testing::InitGoogleTest(&argc, argv);
1870 
1871     std::vector<std::string> paths = {
1872             // clang-format off
1873             "/data/gsi/ota/test",
1874             "/data/gsi/ota/test/super",
1875             "/metadata/gsi/ota/test",
1876             "/metadata/gsi/ota/test/super",
1877             "/metadata/ota/test",
1878             "/metadata/ota/test/snapshots",
1879             // clang-format on
1880     };
1881     for (const auto& path : paths) {
1882         if (!Mkdir(path)) {
1883             return 1;
1884         }
1885     }
1886 
1887     // Create this once, otherwise, gsid will start/stop between each test.
1888     test_device = new TestDeviceInfo();
1889     sm = SnapshotManager::New(test_device);
1890     if (!sm) {
1891         std::cerr << "Could not create snapshot manager\n";
1892         return 1;
1893     }
1894 
1895     // Clean up previous run.
1896     MetadataMountedTest().TearDown();
1897     SnapshotUpdateTest().Cleanup();
1898     SnapshotTest().Cleanup();
1899 
1900     // Use a separate image manager for our fake super partition.
1901     auto super_images = IImageManager::Open("ota/test/super", 10s);
1902     if (!super_images) {
1903         std::cerr << "Could not create image manager\n";
1904         return 1;
1905     }
1906 
1907     // Clean up any old copy.
1908     DeleteBackingImage(super_images.get(), "fake-super");
1909 
1910     // Create and map the fake super partition.
1911     static constexpr int kImageFlags =
1912             IImageManager::CREATE_IMAGE_DEFAULT | IImageManager::CREATE_IMAGE_ZERO_FILL;
1913     if (!super_images->CreateBackingImage("fake-super", kSuperSize, kImageFlags)) {
1914         std::cerr << "Could not create fake super partition\n";
1915         return 1;
1916     }
1917     if (!super_images->MapImageDevice("fake-super", 10s, &fake_super)) {
1918         std::cerr << "Could not map fake super partition\n";
1919         return 1;
1920     }
1921     test_device->set_fake_super(fake_super);
1922 
1923     auto result = RUN_ALL_TESTS();
1924 
1925     DeleteBackingImage(super_images.get(), "fake-super");
1926 
1927     return result;
1928 }
1929