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