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/cow_format.h>
16 #include <libsnapshot/snapshot.h>
17 
18 #include <fcntl.h>
19 #include <signal.h>
20 #include <sys/file.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 
24 #include <chrono>
25 #include <deque>
26 #include <future>
27 #include <iostream>
28 
29 #include <aidl/android/hardware/boot/MergeStatus.h>
30 #include <android-base/file.h>
31 #include <android-base/logging.h>
32 #include <android-base/properties.h>
33 #include <android-base/strings.h>
34 #include <android-base/unique_fd.h>
35 #include <fs_mgr/file_wait.h>
36 #include <fs_mgr/roots.h>
37 #include <fs_mgr_dm_linear.h>
38 #include <gflags/gflags.h>
39 #include <gtest/gtest.h>
40 #include <libdm/dm.h>
41 #include <libfiemap/image_manager.h>
42 #include <liblp/builder.h>
43 #include <openssl/sha.h>
44 #include <storage_literals/storage_literals.h>
45 
46 #include <android/snapshot/snapshot.pb.h>
47 #include <libsnapshot/test_helpers.h>
48 #include "partition_cow_creator.h"
49 #include "utility.h"
50 
51 // Mock classes are not used. Header included to ensure mocked class definition aligns with the
52 // class itself.
53 #include <libsnapshot/mock_device_info.h>
54 #include <libsnapshot/mock_snapshot.h>
55 
56 #if defined(LIBSNAPSHOT_TEST_VAB_LEGACY)
57 #define DEFAULT_MODE "vab-legacy"
58 #elif defined(LIBSNAPSHOT_TEST_VABC_LEGACY)
59 #define DEFAULT_MODE "vabc-legacy"
60 #else
61 #define DEFAULT_MODE ""
62 #endif
63 
64 DEFINE_string(force_mode, DEFAULT_MODE,
65               "Force testing older modes (vab-legacy, vabc-legacy) ignoring device config.");
66 DEFINE_string(force_iouring_disable, "",
67               "Force testing mode (iouring_disabled) - disable io_uring");
68 DEFINE_string(compression_method, "gz", "Default compression algorithm.");
69 
70 namespace android {
71 namespace snapshot {
72 
73 using android::base::unique_fd;
74 using android::dm::DeviceMapper;
75 using android::dm::DmDeviceState;
76 using android::dm::IDeviceMapper;
77 using android::fiemap::FiemapStatus;
78 using android::fiemap::IImageManager;
79 using android::fs_mgr::BlockDeviceInfo;
80 using android::fs_mgr::CreateLogicalPartitionParams;
81 using android::fs_mgr::DestroyLogicalPartition;
82 using android::fs_mgr::EnsurePathMounted;
83 using android::fs_mgr::EnsurePathUnmounted;
84 using android::fs_mgr::Extent;
85 using android::fs_mgr::Fstab;
86 using android::fs_mgr::GetPartitionGroupName;
87 using android::fs_mgr::GetPartitionName;
88 using android::fs_mgr::Interval;
89 using android::fs_mgr::MetadataBuilder;
90 using android::fs_mgr::SlotSuffixForSlotNumber;
91 using chromeos_update_engine::DeltaArchiveManifest;
92 using chromeos_update_engine::DynamicPartitionGroup;
93 using chromeos_update_engine::PartitionUpdate;
94 using namespace ::testing;
95 using namespace android::storage_literals;
96 using namespace std::chrono_literals;
97 using namespace std::string_literals;
98 
99 // Global states. See test_helpers.h.
100 std::unique_ptr<SnapshotManager> sm;
101 TestDeviceInfo* test_device = nullptr;
102 std::string fake_super;
103 
104 void MountMetadata();
105 
106 class SnapshotTest : public ::testing::Test {
107   public:
SnapshotTest()108     SnapshotTest() : dm_(DeviceMapper::Instance()) {}
109 
110     // This is exposed for main.
Cleanup()111     void Cleanup() {
112         InitializeState();
113         CleanupTestArtifacts();
114     }
115 
116   protected:
SetUp()117     void SetUp() override {
118         const testing::TestInfo* const test_info =
119                 testing::UnitTest::GetInstance()->current_test_info();
120         test_name_ = test_info->test_suite_name() + "/"s + test_info->name();
121 
122         LOG(INFO) << "Starting test: " << test_name_;
123 
124         SKIP_IF_NON_VIRTUAL_AB();
125 
126         SetupProperties();
127         if (!DeviceSupportsMode()) {
128             GTEST_SKIP() << "Mode not supported on this device";
129         }
130 
131         InitializeState();
132         CleanupTestArtifacts();
133         FormatFakeSuper();
134         MountMetadata();
135         ASSERT_TRUE(sm->BeginUpdate());
136     }
137 
SetupProperties()138     void SetupProperties() {
139         std::unordered_map<std::string, std::string> properties;
140 
141         ASSERT_TRUE(android::base::SetProperty("snapuserd.test.dm.snapshots", "0"))
142                 << "Failed to disable property: virtual_ab.userspace.snapshots.enabled";
143         ASSERT_TRUE(android::base::SetProperty("snapuserd.test.io_uring.force_disable", "0"))
144                 << "Failed to set property: snapuserd.test.io_uring.disabled";
145 
146         if (FLAGS_force_mode == "vabc-legacy") {
147             ASSERT_TRUE(android::base::SetProperty("snapuserd.test.dm.snapshots", "1"))
148                     << "Failed to disable property: virtual_ab.userspace.snapshots.enabled";
149             properties["ro.virtual_ab.compression.enabled"] = "true";
150             properties["ro.virtual_ab.userspace.snapshots.enabled"] = "false";
151         } else if (FLAGS_force_mode == "vab-legacy") {
152             properties["ro.virtual_ab.compression.enabled"] = "false";
153             properties["ro.virtual_ab.userspace.snapshots.enabled"] = "false";
154         }
155 
156         if (FLAGS_force_iouring_disable == "iouring_disabled") {
157             ASSERT_TRUE(android::base::SetProperty("snapuserd.test.io_uring.force_disable", "1"))
158                     << "Failed to set property: snapuserd.test.io_uring.disabled";
159             properties["ro.virtual_ab.io_uring.enabled"] = "false";
160         }
161 
162         auto fetcher = std::make_unique<SnapshotTestPropertyFetcher>("_a", std::move(properties));
163         IPropertyFetcher::OverrideForTesting(std::move(fetcher));
164 
165         if (GetLegacyCompressionEnabledProperty() || CanUseUserspaceSnapshots()) {
166             // If we're asked to test the device's actual configuration, then it
167             // may be misconfigured, so check for kernel support as libsnapshot does.
168             if (FLAGS_force_mode.empty()) {
169                 snapuserd_required_ = KernelSupportsCompressedSnapshots();
170             } else {
171                 snapuserd_required_ = true;
172             }
173         }
174     }
175 
TearDown()176     void TearDown() override {
177         RETURN_IF_NON_VIRTUAL_AB();
178 
179         LOG(INFO) << "Tearing down SnapshotTest test: " << test_name_;
180 
181         lock_ = nullptr;
182 
183         CleanupTestArtifacts();
184         SnapshotTestPropertyFetcher::TearDown();
185 
186         LOG(INFO) << "Teardown complete for test: " << test_name_;
187     }
188 
DeviceSupportsMode()189     bool DeviceSupportsMode() {
190         if (FLAGS_force_mode.empty()) {
191             return true;
192         }
193         if (snapuserd_required_ && !KernelSupportsCompressedSnapshots()) {
194             return false;
195         }
196         return true;
197     }
198 
InitializeState()199     void InitializeState() {
200         ASSERT_TRUE(sm->EnsureImageManager());
201         image_manager_ = sm->image_manager();
202 
203         test_device->set_slot_suffix("_a");
204 
205         sm->set_use_first_stage_snapuserd(false);
206     }
207 
CleanupTestArtifacts()208     void CleanupTestArtifacts() {
209         // Normally cancelling inside a merge is not allowed. Since these
210         // are tests, we don't care, destroy everything that might exist.
211         // Note we hardcode this list because of an annoying quirk: when
212         // completing a merge, the snapshot stops existing, so we can't
213         // get an accurate list to remove.
214         lock_ = nullptr;
215 
216         // If there is no image manager, the test was skipped.
217         if (!image_manager_) {
218             return;
219         }
220 
221         std::vector<std::string> snapshots = {"test-snapshot", "test_partition_a",
222                                               "test_partition_b"};
223         for (const auto& snapshot : snapshots) {
224             CleanupSnapshotArtifacts(snapshot);
225         }
226 
227         // Remove stale partitions in fake super.
228         std::vector<std::string> partitions = {
229                 "base-device",
230                 "test_partition_b",
231                 "test_partition_b-base",
232                 "test_partition_b-cow",
233         };
234         for (const auto& partition : partitions) {
235             DeleteDevice(partition);
236         }
237 
238         if (sm->GetUpdateState() != UpdateState::None) {
239             auto state_file = sm->GetStateFilePath();
240             unlink(state_file.c_str());
241         }
242     }
243 
CleanupSnapshotArtifacts(const std::string & snapshot)244     void CleanupSnapshotArtifacts(const std::string& snapshot) {
245         // The device-mapper stack may have been collapsed to dm-linear, so it's
246         // necessary to check what state it's in before attempting a cleanup.
247         // SnapshotManager has no path like this because we'd never remove a
248         // merged snapshot (a live partition).
249         bool is_dm_user = false;
250         DeviceMapper::TargetInfo target;
251         if (sm->IsSnapshotDevice(snapshot, &target)) {
252             is_dm_user = (DeviceMapper::GetTargetType(target.spec) == "user");
253         }
254 
255         if (is_dm_user) {
256             ASSERT_TRUE(sm->EnsureSnapuserdConnected());
257             ASSERT_TRUE(AcquireLock());
258 
259             auto local_lock = std::move(lock_);
260             ASSERT_TRUE(sm->UnmapUserspaceSnapshotDevice(local_lock.get(), snapshot));
261         }
262 
263         ASSERT_TRUE(DeleteSnapshotDevice(snapshot));
264         DeleteBackingImage(image_manager_, snapshot + "-cow-img");
265 
266         auto status_file = sm->GetSnapshotStatusFilePath(snapshot);
267         android::base::RemoveFileIfExists(status_file);
268     }
269 
AcquireLock()270     bool AcquireLock() {
271         lock_ = sm->LockExclusive();
272         return !!lock_;
273     }
274 
275     // This is so main() can instantiate this to invoke Cleanup.
TestBody()276     virtual void TestBody() override {}
277 
FormatFakeSuper()278     void FormatFakeSuper() {
279         BlockDeviceInfo super_device("super", kSuperSize, 0, 0, 4096);
280         std::vector<BlockDeviceInfo> devices = {super_device};
281 
282         auto builder = MetadataBuilder::New(devices, "super", 65536, 2);
283         ASSERT_NE(builder, nullptr);
284 
285         auto metadata = builder->Export();
286         ASSERT_NE(metadata, nullptr);
287 
288         TestPartitionOpener opener(fake_super);
289         ASSERT_TRUE(FlashPartitionTable(opener, fake_super, *metadata.get()));
290     }
291 
292     // If |path| is non-null, the partition will be mapped after creation.
CreatePartition(const std::string & name,uint64_t size,std::string * path=nullptr,const std::optional<std::string> group={})293     bool CreatePartition(const std::string& name, uint64_t size, std::string* path = nullptr,
294                          const std::optional<std::string> group = {}) {
295         TestPartitionOpener opener(fake_super);
296         auto builder = MetadataBuilder::New(opener, "super", 0);
297         if (!builder) return false;
298 
299         std::string partition_group = std::string(android::fs_mgr::kDefaultGroup);
300         if (group) {
301             partition_group = *group;
302         }
303         return CreatePartition(builder.get(), name, size, path, partition_group);
304     }
305 
CreatePartition(MetadataBuilder * builder,const std::string & name,uint64_t size,std::string * path,const std::string & group)306     bool CreatePartition(MetadataBuilder* builder, const std::string& name, uint64_t size,
307                          std::string* path, const std::string& group) {
308         auto partition = builder->AddPartition(name, group, 0);
309         if (!partition) return false;
310         if (!builder->ResizePartition(partition, size)) {
311             return false;
312         }
313 
314         // Update the source slot.
315         auto metadata = builder->Export();
316         if (!metadata) return false;
317 
318         TestPartitionOpener opener(fake_super);
319         if (!UpdatePartitionTable(opener, "super", *metadata.get(), 0)) {
320             return false;
321         }
322 
323         if (!path) return true;
324 
325         CreateLogicalPartitionParams params = {
326                 .block_device = fake_super,
327                 .metadata = metadata.get(),
328                 .partition_name = name,
329                 .force_writable = true,
330                 .timeout_ms = 10s,
331         };
332         return CreateLogicalPartition(params, path);
333     }
334 
MapUpdateSnapshot(const std::string & name,std::unique_ptr<ISnapshotWriter> * writer)335     AssertionResult MapUpdateSnapshot(const std::string& name,
336                                       std::unique_ptr<ISnapshotWriter>* writer) {
337         TestPartitionOpener opener(fake_super);
338         CreateLogicalPartitionParams params{
339                 .block_device = fake_super,
340                 .metadata_slot = 1,
341                 .partition_name = name,
342                 .timeout_ms = 10s,
343                 .partition_opener = &opener,
344         };
345 
346         auto old_partition = "/dev/block/mapper/" + GetOtherPartitionName(name);
347         auto result = sm->OpenSnapshotWriter(params, {old_partition});
348         if (!result) {
349             return AssertionFailure() << "Cannot open snapshot for writing: " << name;
350         }
351         if (!result->Initialize()) {
352             return AssertionFailure() << "Cannot initialize snapshot for writing: " << name;
353         }
354 
355         if (writer) {
356             *writer = std::move(result);
357         }
358         return AssertionSuccess();
359     }
360 
MapUpdateSnapshot(const std::string & name,std::string * path)361     AssertionResult MapUpdateSnapshot(const std::string& name, std::string* path) {
362         TestPartitionOpener opener(fake_super);
363         CreateLogicalPartitionParams params{
364                 .block_device = fake_super,
365                 .metadata_slot = 1,
366                 .partition_name = name,
367                 .timeout_ms = 10s,
368                 .partition_opener = &opener,
369         };
370 
371         auto result = sm->MapUpdateSnapshot(params, path);
372         if (!result) {
373             return AssertionFailure() << "Cannot open snapshot for writing: " << name;
374         }
375         return AssertionSuccess();
376     }
377 
DeleteSnapshotDevice(const std::string & snapshot)378     AssertionResult DeleteSnapshotDevice(const std::string& snapshot) {
379         AssertionResult res = AssertionSuccess();
380         if (!(res = DeleteDevice(snapshot))) return res;
381         if (!sm->UnmapDmUserDevice(snapshot + "-user-cow")) {
382             return AssertionFailure() << "Cannot delete dm-user device for " << snapshot;
383         }
384         if (!(res = DeleteDevice(snapshot + "-inner"))) return res;
385         if (!(res = DeleteDevice(snapshot + "-cow"))) return res;
386         if (!image_manager_->UnmapImageIfExists(snapshot + "-cow-img")) {
387             return AssertionFailure() << "Cannot unmap image " << snapshot << "-cow-img";
388         }
389         if (!(res = DeleteDevice(snapshot + "-base"))) return res;
390         if (!(res = DeleteDevice(snapshot + "-src"))) return res;
391         return AssertionSuccess();
392     }
393 
DeleteDevice(const std::string & device)394     AssertionResult DeleteDevice(const std::string& device) {
395         if (!sm->DeleteDeviceIfExists(device, 1s)) {
396             return AssertionFailure() << "Can't delete " << device;
397         }
398         return AssertionSuccess();
399     }
400 
CreateCowImage(const std::string & name)401     AssertionResult CreateCowImage(const std::string& name) {
402         if (!sm->CreateCowImage(lock_.get(), name)) {
403             return AssertionFailure() << "Cannot create COW image " << name;
404         }
405         std::string cow_device;
406         auto map_res = MapCowImage(name, 10s, &cow_device);
407         if (!map_res) {
408             return map_res;
409         }
410         if (!InitializeKernelCow(cow_device)) {
411             return AssertionFailure() << "Cannot zero fill " << cow_device;
412         }
413         if (!sm->UnmapCowImage(name)) {
414             return AssertionFailure() << "Cannot unmap " << name << " after zero filling it";
415         }
416         return AssertionSuccess();
417     }
418 
MapCowImage(const std::string & name,const std::chrono::milliseconds & timeout_ms,std::string * path)419     AssertionResult MapCowImage(const std::string& name,
420                                 const std::chrono::milliseconds& timeout_ms, std::string* path) {
421         auto cow_image_path = sm->MapCowImage(name, timeout_ms);
422         if (!cow_image_path.has_value()) {
423             return AssertionFailure() << "Cannot map cow image " << name;
424         }
425         *path = *cow_image_path;
426         return AssertionSuccess();
427     }
428 
429     // Prepare A/B slot for a partition named "test_partition".
PrepareOneSnapshot(uint64_t device_size,std::unique_ptr<ISnapshotWriter> * writer=nullptr)430     AssertionResult PrepareOneSnapshot(uint64_t device_size,
431                                        std::unique_ptr<ISnapshotWriter>* writer = nullptr) {
432         lock_ = nullptr;
433 
434         DeltaArchiveManifest manifest;
435 
436         auto dynamic_partition_metadata = manifest.mutable_dynamic_partition_metadata();
437         dynamic_partition_metadata->set_vabc_enabled(snapuserd_required_);
438         dynamic_partition_metadata->set_cow_version(android::snapshot::kCowVersionMajor);
439         if (snapuserd_required_) {
440             dynamic_partition_metadata->set_vabc_compression_param(FLAGS_compression_method);
441         }
442 
443         auto group = dynamic_partition_metadata->add_groups();
444         group->set_name("group");
445         group->set_size(device_size * 2);
446         group->add_partition_names("test_partition");
447 
448         auto pu = manifest.add_partitions();
449         pu->set_partition_name("test_partition");
450         pu->set_estimate_cow_size(device_size);
451         SetSize(pu, device_size);
452 
453         auto extent = pu->add_operations()->add_dst_extents();
454         extent->set_start_block(0);
455         if (device_size) {
456             extent->set_num_blocks(device_size / manifest.block_size());
457         }
458 
459         TestPartitionOpener opener(fake_super);
460         auto builder = MetadataBuilder::New(opener, "super", 0);
461         if (!builder) {
462             return AssertionFailure() << "Failed to open MetadataBuilder";
463         }
464         builder->AddGroup("group_a", 16_GiB);
465         builder->AddGroup("group_b", 16_GiB);
466         if (!CreatePartition(builder.get(), "test_partition_a", device_size, nullptr, "group_a")) {
467             return AssertionFailure() << "Failed create test_partition_a";
468         }
469 
470         if (!sm->CreateUpdateSnapshots(manifest)) {
471             return AssertionFailure() << "Failed to create update snapshots";
472         }
473 
474         if (writer) {
475             auto res = MapUpdateSnapshot("test_partition_b", writer);
476             if (!res) {
477                 return res;
478             }
479         } else if (!snapuserd_required_) {
480             std::string ignore;
481             if (!MapUpdateSnapshot("test_partition_b", &ignore)) {
482                 return AssertionFailure() << "Failed to map test_partition_b";
483             }
484         }
485         if (!AcquireLock()) {
486             return AssertionFailure() << "Failed to acquire lock";
487         }
488         return AssertionSuccess();
489     }
490 
491     // Simulate a reboot into the new slot.
SimulateReboot()492     AssertionResult SimulateReboot() {
493         lock_ = nullptr;
494         if (!sm->FinishedSnapshotWrites(false)) {
495             return AssertionFailure() << "Failed to finish snapshot writes";
496         }
497         if (!sm->UnmapUpdateSnapshot("test_partition_b")) {
498             return AssertionFailure() << "Failed to unmap COW for test_partition_b";
499         }
500         if (!dm_.DeleteDeviceIfExists("test_partition_b")) {
501             return AssertionFailure() << "Failed to delete test_partition_b";
502         }
503         if (!dm_.DeleteDeviceIfExists("test_partition_b-base")) {
504             return AssertionFailure() << "Failed to destroy test_partition_b-base";
505         }
506         return AssertionSuccess();
507     }
508 
NewManagerForFirstStageMount(const std::string & slot_suffix="")509     std::unique_ptr<SnapshotManager> NewManagerForFirstStageMount(
510             const std::string& slot_suffix = "_a") {
511         auto info = new TestDeviceInfo(fake_super, slot_suffix);
512         return NewManagerForFirstStageMount(info);
513     }
514 
NewManagerForFirstStageMount(TestDeviceInfo * info)515     std::unique_ptr<SnapshotManager> NewManagerForFirstStageMount(TestDeviceInfo* info) {
516         info->set_first_stage_init(true);
517         auto init = SnapshotManager::NewForFirstStageMount(info);
518         if (!init) {
519             return nullptr;
520         }
521         init->SetUeventRegenCallback([](const std::string& device) -> bool {
522             return android::fs_mgr::WaitForFile(device, snapshot_timeout_);
523         });
524         return init;
525     }
526 
527     static constexpr std::chrono::milliseconds snapshot_timeout_ = 5s;
528     DeviceMapper& dm_;
529     std::unique_ptr<SnapshotManager::LockedFile> lock_;
530     android::fiemap::IImageManager* image_manager_ = nullptr;
531     std::string fake_super_;
532     bool snapuserd_required_ = false;
533     std::string test_name_;
534 };
535 
TEST_F(SnapshotTest,CreateSnapshot)536 TEST_F(SnapshotTest, CreateSnapshot) {
537     ASSERT_TRUE(AcquireLock());
538 
539     PartitionCowCreator cow_creator;
540     cow_creator.using_snapuserd = snapuserd_required_;
541     if (cow_creator.using_snapuserd) {
542         cow_creator.compression_algorithm = FLAGS_compression_method;
543     } else {
544         cow_creator.compression_algorithm = "none";
545     }
546 
547     static const uint64_t kDeviceSize = 1024 * 1024;
548     SnapshotStatus status;
549     status.set_name("test-snapshot");
550     status.set_device_size(kDeviceSize);
551     status.set_snapshot_size(kDeviceSize);
552     status.set_cow_file_size(kDeviceSize);
553     ASSERT_TRUE(sm->CreateSnapshot(lock_.get(), &cow_creator, &status));
554     ASSERT_TRUE(CreateCowImage("test-snapshot"));
555 
556     std::vector<std::string> snapshots;
557     ASSERT_TRUE(sm->ListSnapshots(lock_.get(), &snapshots));
558     ASSERT_EQ(snapshots.size(), 1);
559     ASSERT_EQ(snapshots[0], "test-snapshot");
560 
561     // Scope so delete can re-acquire the snapshot file lock.
562     {
563         SnapshotStatus status;
564         ASSERT_TRUE(sm->ReadSnapshotStatus(lock_.get(), "test-snapshot", &status));
565         ASSERT_EQ(status.state(), SnapshotState::CREATED);
566         ASSERT_EQ(status.device_size(), kDeviceSize);
567         ASSERT_EQ(status.snapshot_size(), kDeviceSize);
568         ASSERT_EQ(status.using_snapuserd(), cow_creator.using_snapuserd);
569         ASSERT_EQ(status.compression_algorithm(), cow_creator.compression_algorithm);
570     }
571 
572     ASSERT_TRUE(sm->UnmapSnapshot(lock_.get(), "test-snapshot"));
573     ASSERT_TRUE(sm->UnmapCowImage("test-snapshot"));
574     ASSERT_TRUE(sm->DeleteSnapshot(lock_.get(), "test-snapshot"));
575 }
576 
TEST_F(SnapshotTest,MapSnapshot)577 TEST_F(SnapshotTest, MapSnapshot) {
578     ASSERT_TRUE(AcquireLock());
579 
580     PartitionCowCreator cow_creator;
581     cow_creator.using_snapuserd = snapuserd_required_;
582 
583     static const uint64_t kDeviceSize = 1024 * 1024;
584     SnapshotStatus status;
585     status.set_name("test-snapshot");
586     status.set_device_size(kDeviceSize);
587     status.set_snapshot_size(kDeviceSize);
588     status.set_cow_file_size(kDeviceSize);
589     ASSERT_TRUE(sm->CreateSnapshot(lock_.get(), &cow_creator, &status));
590     ASSERT_TRUE(CreateCowImage("test-snapshot"));
591 
592     std::string base_device;
593     ASSERT_TRUE(CreatePartition("base-device", kDeviceSize, &base_device));
594 
595     std::string cow_device;
596     ASSERT_TRUE(MapCowImage("test-snapshot", 10s, &cow_device));
597 
598     std::string snap_device;
599     ASSERT_TRUE(sm->MapSnapshot(lock_.get(), "test-snapshot", base_device, cow_device, 10s,
600                                 &snap_device));
601     ASSERT_TRUE(android::base::StartsWith(snap_device, "/dev/block/dm-"));
602 }
603 
TEST_F(SnapshotTest,NoMergeBeforeReboot)604 TEST_F(SnapshotTest, NoMergeBeforeReboot) {
605     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
606 
607     // Merge should fail, since the slot hasn't changed.
608     ASSERT_FALSE(sm->InitiateMerge());
609 }
610 
TEST_F(SnapshotTest,CleanFirstStageMount)611 TEST_F(SnapshotTest, CleanFirstStageMount) {
612     // If there's no update in progress, there should be no first-stage mount
613     // needed.
614     auto sm = NewManagerForFirstStageMount();
615     ASSERT_NE(sm, nullptr);
616     ASSERT_FALSE(sm->NeedSnapshotsInFirstStageMount());
617 }
618 
TEST_F(SnapshotTest,FirstStageMountAfterRollback)619 TEST_F(SnapshotTest, FirstStageMountAfterRollback) {
620     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
621 
622     // We didn't change the slot, so we shouldn't need snapshots.
623     auto sm = NewManagerForFirstStageMount();
624     ASSERT_NE(sm, nullptr);
625     ASSERT_FALSE(sm->NeedSnapshotsInFirstStageMount());
626 
627     auto indicator = sm->GetRollbackIndicatorPath();
628     ASSERT_EQ(access(indicator.c_str(), R_OK), 0);
629 }
630 
TEST_F(SnapshotTest,Merge)631 TEST_F(SnapshotTest, Merge) {
632     ASSERT_TRUE(AcquireLock());
633 
634     static const uint64_t kDeviceSize = 1024 * 1024;
635 
636     std::unique_ptr<ISnapshotWriter> writer;
637     ASSERT_TRUE(PrepareOneSnapshot(kDeviceSize, &writer));
638 
639     bool userspace_snapshots = sm->UpdateUsesUserSnapshots(lock_.get());
640 
641     // Release the lock.
642     lock_ = nullptr;
643 
644     std::string test_string = "This is a test string.";
645     test_string.resize(writer->options().block_size);
646     ASSERT_TRUE(writer->AddRawBlocks(0, test_string.data(), test_string.size()));
647     ASSERT_TRUE(writer->Finalize());
648     writer = nullptr;
649 
650     // Done updating.
651     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
652 
653     ASSERT_TRUE(sm->UnmapUpdateSnapshot("test_partition_b"));
654 
655     test_device->set_slot_suffix("_b");
656     ASSERT_TRUE(sm->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
657     ASSERT_TRUE(sm->InitiateMerge());
658 
659     // The device should have been switched to a snapshot-merge target.
660     DeviceMapper::TargetInfo target;
661     ASSERT_TRUE(sm->IsSnapshotDevice("test_partition_b", &target));
662     if (userspace_snapshots) {
663         ASSERT_EQ(DeviceMapper::GetTargetType(target.spec), "user");
664     } else {
665         ASSERT_EQ(DeviceMapper::GetTargetType(target.spec), "snapshot-merge");
666     }
667 
668     // We should not be able to cancel an update now.
669     ASSERT_FALSE(sm->CancelUpdate());
670 
671     ASSERT_EQ(sm->ProcessUpdateState(), UpdateState::MergeCompleted);
672     ASSERT_EQ(sm->GetUpdateState(), UpdateState::None);
673 
674     // The device should no longer be a snapshot or snapshot-merge.
675     ASSERT_FALSE(sm->IsSnapshotDevice("test_partition_b"));
676 
677     // Test that we can read back the string we wrote to the snapshot. Note
678     // that the base device is gone now. |snap_device| contains the correct
679     // partition.
680     unique_fd fd(open("/dev/block/mapper/test_partition_b", O_RDONLY | O_CLOEXEC));
681     ASSERT_GE(fd, 0);
682 
683     std::string buffer(test_string.size(), '\0');
684     ASSERT_TRUE(android::base::ReadFully(fd, buffer.data(), buffer.size()));
685     ASSERT_EQ(test_string, buffer);
686 }
687 
TEST_F(SnapshotTest,FirstStageMountAndMerge)688 TEST_F(SnapshotTest, FirstStageMountAndMerge) {
689     ASSERT_TRUE(AcquireLock());
690 
691     static const uint64_t kDeviceSize = 1024 * 1024;
692     ASSERT_TRUE(PrepareOneSnapshot(kDeviceSize));
693     ASSERT_TRUE(SimulateReboot());
694 
695     auto init = NewManagerForFirstStageMount("_b");
696     ASSERT_NE(init, nullptr);
697     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
698     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
699 
700     ASSERT_TRUE(AcquireLock());
701 
702     bool userspace_snapshots = init->UpdateUsesUserSnapshots(lock_.get());
703 
704     // Validate that we have a snapshot device.
705     SnapshotStatus status;
706     ASSERT_TRUE(init->ReadSnapshotStatus(lock_.get(), "test_partition_b", &status));
707     ASSERT_EQ(status.state(), SnapshotState::CREATED);
708     if (snapuserd_required_) {
709         ASSERT_EQ(status.compression_algorithm(), FLAGS_compression_method);
710     } else {
711         ASSERT_EQ(status.compression_algorithm(), "");
712     }
713 
714     DeviceMapper::TargetInfo target;
715     ASSERT_TRUE(init->IsSnapshotDevice("test_partition_b", &target));
716     if (userspace_snapshots) {
717         ASSERT_EQ(DeviceMapper::GetTargetType(target.spec), "user");
718     } else {
719         ASSERT_EQ(DeviceMapper::GetTargetType(target.spec), "snapshot");
720     }
721 }
722 
TEST_F(SnapshotTest,FlashSuperDuringUpdate)723 TEST_F(SnapshotTest, FlashSuperDuringUpdate) {
724     ASSERT_TRUE(AcquireLock());
725 
726     static const uint64_t kDeviceSize = 1024 * 1024;
727     ASSERT_TRUE(PrepareOneSnapshot(kDeviceSize));
728     ASSERT_TRUE(SimulateReboot());
729 
730     // Reflash the super partition.
731     FormatFakeSuper();
732     ASSERT_TRUE(CreatePartition("test_partition_b", kDeviceSize));
733 
734     auto init = NewManagerForFirstStageMount("_b");
735     ASSERT_NE(init, nullptr);
736     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
737     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
738 
739     ASSERT_TRUE(AcquireLock());
740 
741     SnapshotStatus status;
742     ASSERT_TRUE(init->ReadSnapshotStatus(lock_.get(), "test_partition_b", &status));
743 
744     // We should not get a snapshot device now.
745     DeviceMapper::TargetInfo target;
746     ASSERT_FALSE(init->IsSnapshotDevice("test_partition_b", &target));
747 
748     // We should see a cancelled update as well.
749     lock_ = nullptr;
750     ASSERT_EQ(sm->ProcessUpdateState(), UpdateState::Cancelled);
751 }
752 
TEST_F(SnapshotTest,FlashSuperDuringMerge)753 TEST_F(SnapshotTest, FlashSuperDuringMerge) {
754     ASSERT_TRUE(AcquireLock());
755 
756     static const uint64_t kDeviceSize = 1024 * 1024;
757     ASSERT_TRUE(PrepareOneSnapshot(kDeviceSize));
758     ASSERT_TRUE(SimulateReboot());
759 
760     auto init = NewManagerForFirstStageMount("_b");
761     ASSERT_NE(init, nullptr);
762     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
763     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
764     ASSERT_TRUE(init->InitiateMerge());
765 
766     // Now, reflash super. Note that we haven't called ProcessUpdateState, so the
767     // status is still Merging.
768     ASSERT_TRUE(DeleteSnapshotDevice("test_partition_b"));
769     ASSERT_TRUE(init->image_manager()->UnmapImageIfExists("test_partition_b-cow-img"));
770     FormatFakeSuper();
771     ASSERT_TRUE(CreatePartition("test_partition_b", kDeviceSize));
772     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
773     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
774 
775     // Because the status is Merging, we must call ProcessUpdateState, which should
776     // detect a cancelled update.
777     ASSERT_EQ(init->ProcessUpdateState(), UpdateState::Cancelled);
778     ASSERT_EQ(init->GetUpdateState(), UpdateState::None);
779 }
780 
TEST_F(SnapshotTest,UpdateBootControlHal)781 TEST_F(SnapshotTest, UpdateBootControlHal) {
782     ASSERT_TRUE(AcquireLock());
783 
784     ASSERT_TRUE(sm->WriteUpdateState(lock_.get(), UpdateState::None));
785     ASSERT_EQ(test_device->merge_status(), MergeStatus::NONE);
786 
787     ASSERT_TRUE(sm->WriteUpdateState(lock_.get(), UpdateState::Initiated));
788     ASSERT_EQ(test_device->merge_status(), MergeStatus::NONE);
789 
790     ASSERT_TRUE(sm->WriteUpdateState(lock_.get(), UpdateState::Unverified));
791     ASSERT_EQ(test_device->merge_status(), MergeStatus::SNAPSHOTTED);
792 
793     ASSERT_TRUE(sm->WriteUpdateState(lock_.get(), UpdateState::Merging));
794     ASSERT_EQ(test_device->merge_status(), MergeStatus::MERGING);
795 
796     ASSERT_TRUE(sm->WriteUpdateState(lock_.get(), UpdateState::MergeNeedsReboot));
797     ASSERT_EQ(test_device->merge_status(), MergeStatus::NONE);
798 
799     ASSERT_TRUE(sm->WriteUpdateState(lock_.get(), UpdateState::MergeCompleted));
800     ASSERT_EQ(test_device->merge_status(), MergeStatus::NONE);
801 
802     ASSERT_TRUE(sm->WriteUpdateState(lock_.get(), UpdateState::MergeFailed));
803     ASSERT_EQ(test_device->merge_status(), MergeStatus::MERGING);
804 }
805 
TEST_F(SnapshotTest,MergeFailureCode)806 TEST_F(SnapshotTest, MergeFailureCode) {
807     ASSERT_TRUE(AcquireLock());
808 
809     ASSERT_TRUE(sm->WriteUpdateState(lock_.get(), UpdateState::MergeFailed,
810                                      MergeFailureCode::ListSnapshots));
811     ASSERT_EQ(test_device->merge_status(), MergeStatus::MERGING);
812 
813     SnapshotUpdateStatus status = sm->ReadSnapshotUpdateStatus(lock_.get());
814     ASSERT_EQ(status.state(), UpdateState::MergeFailed);
815     ASSERT_EQ(status.merge_failure_code(), MergeFailureCode::ListSnapshots);
816 }
817 
818 enum class Request { UNKNOWN, LOCK_SHARED, LOCK_EXCLUSIVE, UNLOCK, EXIT };
operator <<(std::ostream & os,Request request)819 std::ostream& operator<<(std::ostream& os, Request request) {
820     switch (request) {
821         case Request::LOCK_SHARED:
822             return os << "Shared";
823         case Request::LOCK_EXCLUSIVE:
824             return os << "Exclusive";
825         case Request::UNLOCK:
826             return os << "Unlock";
827         case Request::EXIT:
828             return os << "Exit";
829         case Request::UNKNOWN:
830             [[fallthrough]];
831         default:
832             return os << "Unknown";
833     }
834 }
835 
836 class LockTestConsumer {
837   public:
MakeRequest(Request new_request)838     AssertionResult MakeRequest(Request new_request) {
839         {
840             std::unique_lock<std::mutex> ulock(mutex_);
841             requests_.push_back(new_request);
842         }
843         cv_.notify_all();
844         return AssertionSuccess() << "Request " << new_request << " successful";
845     }
846 
847     template <typename R, typename P>
WaitFulfill(std::chrono::duration<R,P> timeout)848     AssertionResult WaitFulfill(std::chrono::duration<R, P> timeout) {
849         std::unique_lock<std::mutex> ulock(mutex_);
850         if (cv_.wait_for(ulock, timeout, [this] { return requests_.empty(); })) {
851             return AssertionSuccess() << "All requests_ fulfilled.";
852         }
853         return AssertionFailure() << "Timeout waiting for fulfilling " << requests_.size()
854                                   << " request(s), first one is "
855                                   << (requests_.empty() ? Request::UNKNOWN : requests_.front());
856     }
857 
StartHandleRequestsInBackground()858     void StartHandleRequestsInBackground() {
859         future_ = std::async(std::launch::async, &LockTestConsumer::HandleRequests, this);
860     }
861 
862   private:
HandleRequests()863     void HandleRequests() {
864         static constexpr auto consumer_timeout = 3s;
865 
866         auto next_request = Request::UNKNOWN;
867         do {
868             // Peek next request.
869             {
870                 std::unique_lock<std::mutex> ulock(mutex_);
871                 if (cv_.wait_for(ulock, consumer_timeout, [this] { return !requests_.empty(); })) {
872                     next_request = requests_.front();
873                 } else {
874                     next_request = Request::EXIT;
875                 }
876             }
877 
878             // Handle next request.
879             switch (next_request) {
880                 case Request::LOCK_SHARED: {
881                     lock_ = sm->LockShared();
882                 } break;
883                 case Request::LOCK_EXCLUSIVE: {
884                     lock_ = sm->LockExclusive();
885                 } break;
886                 case Request::EXIT:
887                     [[fallthrough]];
888                 case Request::UNLOCK: {
889                     lock_.reset();
890                 } break;
891                 case Request::UNKNOWN:
892                     [[fallthrough]];
893                 default:
894                     break;
895             }
896 
897             // Pop next request. This thread is the only thread that
898             // pops from the front of the requests_ deque.
899             {
900                 std::unique_lock<std::mutex> ulock(mutex_);
901                 if (next_request == Request::EXIT) {
902                     requests_.clear();
903                 } else {
904                     requests_.pop_front();
905                 }
906             }
907             cv_.notify_all();
908         } while (next_request != Request::EXIT);
909     }
910 
911     std::mutex mutex_;
912     std::condition_variable cv_;
913     std::deque<Request> requests_;
914     std::unique_ptr<SnapshotManager::LockedFile> lock_;
915     std::future<void> future_;
916 };
917 
918 class LockTest : public ::testing::Test {
919   public:
SetUp()920     void SetUp() {
921         SKIP_IF_NON_VIRTUAL_AB();
922         first_consumer.StartHandleRequestsInBackground();
923         second_consumer.StartHandleRequestsInBackground();
924     }
925 
TearDown()926     void TearDown() {
927         RETURN_IF_NON_VIRTUAL_AB();
928         EXPECT_TRUE(first_consumer.MakeRequest(Request::EXIT));
929         EXPECT_TRUE(second_consumer.MakeRequest(Request::EXIT));
930     }
931 
932     static constexpr auto request_timeout = 500ms;
933     LockTestConsumer first_consumer;
934     LockTestConsumer second_consumer;
935 };
936 
TEST_F(LockTest,SharedShared)937 TEST_F(LockTest, SharedShared) {
938     ASSERT_TRUE(first_consumer.MakeRequest(Request::LOCK_SHARED));
939     ASSERT_TRUE(first_consumer.WaitFulfill(request_timeout));
940     ASSERT_TRUE(second_consumer.MakeRequest(Request::LOCK_SHARED));
941     ASSERT_TRUE(second_consumer.WaitFulfill(request_timeout));
942 }
943 
944 using LockTestParam = std::pair<Request, Request>;
945 class LockTestP : public LockTest, public ::testing::WithParamInterface<LockTestParam> {};
TEST_P(LockTestP,Test)946 TEST_P(LockTestP, Test) {
947     ASSERT_TRUE(first_consumer.MakeRequest(GetParam().first));
948     ASSERT_TRUE(first_consumer.WaitFulfill(request_timeout));
949     ASSERT_TRUE(second_consumer.MakeRequest(GetParam().second));
950     ASSERT_FALSE(second_consumer.WaitFulfill(request_timeout))
951             << "Should not be able to " << GetParam().second << " while separate thread "
952             << GetParam().first;
953     ASSERT_TRUE(first_consumer.MakeRequest(Request::UNLOCK));
954     ASSERT_TRUE(second_consumer.WaitFulfill(request_timeout))
955             << "Should be able to hold lock that is released by separate thread";
956 }
957 INSTANTIATE_TEST_SUITE_P(
958         LockTest, LockTestP,
959         testing::Values(LockTestParam{Request::LOCK_EXCLUSIVE, Request::LOCK_EXCLUSIVE},
960                         LockTestParam{Request::LOCK_EXCLUSIVE, Request::LOCK_SHARED},
961                         LockTestParam{Request::LOCK_SHARED, Request::LOCK_EXCLUSIVE}),
__anon2cbfbe5c0402(const testing::TestParamInfo<LockTestP::ParamType>& info) 962         [](const testing::TestParamInfo<LockTestP::ParamType>& info) {
963             std::stringstream ss;
964             ss << info.param.first << info.param.second;
965             return ss.str();
966         });
967 
968 class SnapshotUpdateTest : public SnapshotTest {
969   public:
SetUp()970     void SetUp() override {
971         SKIP_IF_NON_VIRTUAL_AB();
972 
973         SnapshotTest::SetUp();
974         if (!image_manager_) {
975             // Test was skipped.
976             return;
977         }
978 
979         Cleanup();
980 
981         // Cleanup() changes slot suffix, so initialize it again.
982         test_device->set_slot_suffix("_a");
983 
984         opener_ = std::make_unique<TestPartitionOpener>(fake_super);
985 
986         auto dynamic_partition_metadata = manifest_.mutable_dynamic_partition_metadata();
987         dynamic_partition_metadata->set_vabc_enabled(snapuserd_required_);
988         dynamic_partition_metadata->set_cow_version(android::snapshot::kCowVersionMajor);
989         if (snapuserd_required_) {
990             dynamic_partition_metadata->set_vabc_compression_param(FLAGS_compression_method);
991         }
992 
993         // Create a fake update package metadata.
994         // Not using full name "system", "vendor", "product" because these names collide with the
995         // mapped partitions on the running device.
996         // Each test modifies manifest_ slightly to indicate changes to the partition layout.
997         group_ = dynamic_partition_metadata->add_groups();
998         group_->set_name("group");
999         group_->set_size(kGroupSize);
1000         group_->add_partition_names("sys");
1001         group_->add_partition_names("vnd");
1002         group_->add_partition_names("prd");
1003         sys_ = manifest_.add_partitions();
1004         sys_->set_partition_name("sys");
1005         sys_->set_estimate_cow_size(2_MiB);
1006         SetSize(sys_, 3_MiB);
1007         vnd_ = manifest_.add_partitions();
1008         vnd_->set_partition_name("vnd");
1009         vnd_->set_estimate_cow_size(2_MiB);
1010         SetSize(vnd_, 3_MiB);
1011         prd_ = manifest_.add_partitions();
1012         prd_->set_partition_name("prd");
1013         prd_->set_estimate_cow_size(2_MiB);
1014         SetSize(prd_, 3_MiB);
1015 
1016         // Initialize source partition metadata using |manifest_|.
1017         src_ = MetadataBuilder::New(*opener_, "super", 0);
1018         ASSERT_NE(src_, nullptr);
1019         ASSERT_TRUE(FillFakeMetadata(src_.get(), manifest_, "_a"));
1020         // Add sys_b which is like system_other.
1021         ASSERT_TRUE(src_->AddGroup("group_b", kGroupSize));
1022         auto partition = src_->AddPartition("sys_b", "group_b", 0);
1023         ASSERT_NE(nullptr, partition);
1024         ASSERT_TRUE(src_->ResizePartition(partition, 1_MiB));
1025         auto metadata = src_->Export();
1026         ASSERT_NE(nullptr, metadata);
1027         ASSERT_TRUE(UpdatePartitionTable(*opener_, "super", *metadata.get(), 0));
1028 
1029         // Map source partitions.
1030         std::string path;
1031         for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
1032             ASSERT_TRUE(CreateLogicalPartition(
1033                     CreateLogicalPartitionParams{
1034                             .block_device = fake_super,
1035                             .metadata_slot = 0,
1036                             .partition_name = name,
1037                             .timeout_ms = 1s,
1038                             .partition_opener = opener_.get(),
1039                     },
1040                     &path));
1041             ASSERT_TRUE(WriteRandomData(path));
1042             auto hash = GetHash(path);
1043             ASSERT_TRUE(hash.has_value());
1044             hashes_[name] = *hash;
1045         }
1046 
1047         // OTA client blindly unmaps all partitions that are possibly mapped.
1048         for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
1049             ASSERT_TRUE(sm->UnmapUpdateSnapshot(name));
1050         }
1051     }
TearDown()1052     void TearDown() override {
1053         RETURN_IF_NON_VIRTUAL_AB();
1054 
1055         LOG(INFO) << "Tearing down SnapshotUpdateTest test: " << test_name_;
1056 
1057         Cleanup();
1058         SnapshotTest::TearDown();
1059     }
Cleanup()1060     void Cleanup() {
1061         if (!image_manager_) {
1062             InitializeState();
1063         }
1064         MountMetadata();
1065         for (const auto& suffix : {"_a", "_b"}) {
1066             test_device->set_slot_suffix(suffix);
1067 
1068             // Cheat our way out of merge failed states.
1069             if (sm->ProcessUpdateState() == UpdateState::MergeFailed) {
1070                 ASSERT_TRUE(AcquireLock());
1071                 ASSERT_TRUE(sm->WriteUpdateState(lock_.get(), UpdateState::None));
1072                 lock_ = {};
1073             }
1074 
1075             EXPECT_TRUE(sm->CancelUpdate()) << suffix;
1076         }
1077         EXPECT_TRUE(UnmapAll());
1078     }
1079 
IsPartitionUnchanged(const std::string & name)1080     AssertionResult IsPartitionUnchanged(const std::string& name) {
1081         std::string path;
1082         if (!dm_.GetDmDevicePathByName(name, &path)) {
1083             return AssertionFailure() << "Path of " << name << " cannot be determined";
1084         }
1085         auto hash = GetHash(path);
1086         if (!hash.has_value()) {
1087             return AssertionFailure() << "Cannot read partition " << name << ": " << path;
1088         }
1089         auto it = hashes_.find(name);
1090         if (it == hashes_.end()) {
1091             return AssertionFailure() << "No existing hash for " << name << ". Bad test code?";
1092         }
1093         if (it->second != *hash) {
1094             return AssertionFailure() << "Content of " << name << " has changed";
1095         }
1096         return AssertionSuccess();
1097     }
1098 
GetSnapshotSize(const std::string & name)1099     std::optional<uint64_t> GetSnapshotSize(const std::string& name) {
1100         if (!AcquireLock()) {
1101             return std::nullopt;
1102         }
1103         auto local_lock = std::move(lock_);
1104 
1105         SnapshotStatus status;
1106         if (!sm->ReadSnapshotStatus(local_lock.get(), name, &status)) {
1107             return std::nullopt;
1108         }
1109         return status.snapshot_size();
1110     }
1111 
UnmapAll()1112     AssertionResult UnmapAll() {
1113         for (const auto& name : {"sys", "vnd", "prd", "dlkm"}) {
1114             if (!dm_.DeleteDeviceIfExists(name + "_a"s)) {
1115                 return AssertionFailure() << "Cannot unmap " << name << "_a";
1116             }
1117             if (!DeleteSnapshotDevice(name + "_b"s)) {
1118                 return AssertionFailure() << "Cannot delete snapshot " << name << "_b";
1119             }
1120         }
1121         return AssertionSuccess();
1122     }
1123 
MapOneUpdateSnapshot(const std::string & name)1124     AssertionResult MapOneUpdateSnapshot(const std::string& name) {
1125         if (snapuserd_required_) {
1126             std::unique_ptr<ISnapshotWriter> writer;
1127             return MapUpdateSnapshot(name, &writer);
1128         } else {
1129             std::string path;
1130             return MapUpdateSnapshot(name, &path);
1131         }
1132     }
1133 
WriteSnapshots()1134     AssertionResult WriteSnapshots() {
1135         for (const auto& partition : {sys_, vnd_, prd_}) {
1136             auto res = WriteSnapshotAndHash(partition);
1137             if (!res) {
1138                 return res;
1139             }
1140         }
1141         return AssertionSuccess();
1142     }
1143 
WriteSnapshotAndHash(PartitionUpdate * partition)1144     AssertionResult WriteSnapshotAndHash(PartitionUpdate* partition) {
1145         std::string name = partition->partition_name() + "_b";
1146         if (snapuserd_required_) {
1147             std::unique_ptr<ISnapshotWriter> writer;
1148             auto res = MapUpdateSnapshot(name, &writer);
1149             if (!res) {
1150                 return res;
1151             }
1152             if (!WriteRandomSnapshotData(writer.get(), &hashes_[name])) {
1153                 return AssertionFailure() << "Unable to write random data to snapshot " << name;
1154             }
1155             if (!writer->Finalize()) {
1156                 return AssertionFailure() << "Unable to finalize COW for " << name;
1157             }
1158         } else {
1159             std::string path;
1160             auto res = MapUpdateSnapshot(name, &path);
1161             if (!res) {
1162                 return res;
1163             }
1164             if (!WriteRandomData(path, std::nullopt, &hashes_[name])) {
1165                 return AssertionFailure() << "Unable to write random data to snapshot " << name;
1166             }
1167         }
1168 
1169         // Make sure updates to one device are seen by all devices.
1170         sync();
1171 
1172         return AssertionSuccess() << "Written random data to snapshot " << name
1173                                   << ", hash: " << hashes_[name];
1174     }
1175 
WriteRandomSnapshotData(ICowWriter * writer,std::string * hash)1176     bool WriteRandomSnapshotData(ICowWriter* writer, std::string* hash) {
1177         unique_fd rand(open("/dev/urandom", O_RDONLY));
1178         if (rand < 0) {
1179             PLOG(ERROR) << "open /dev/urandom";
1180             return false;
1181         }
1182 
1183         SHA256_CTX ctx;
1184         SHA256_Init(&ctx);
1185 
1186         if (!writer->options().max_blocks) {
1187             LOG(ERROR) << "CowWriter must specify maximum number of blocks";
1188             return false;
1189         }
1190         const auto num_blocks = writer->options().max_blocks.value();
1191 
1192         const auto block_size = writer->options().block_size;
1193         std::string block(block_size, '\0');
1194         for (uint64_t i = 0; i < num_blocks; i++) {
1195             if (!ReadFully(rand, block.data(), block.size())) {
1196                 PLOG(ERROR) << "read /dev/urandom";
1197                 return false;
1198             }
1199             if (!writer->AddRawBlocks(i, block.data(), block.size())) {
1200                 LOG(ERROR) << "Failed to add raw block " << i;
1201                 return false;
1202             }
1203             SHA256_Update(&ctx, block.data(), block.size());
1204         }
1205 
1206         uint8_t out[32];
1207         SHA256_Final(out, &ctx);
1208         *hash = ToHexString(out, sizeof(out));
1209         return true;
1210     }
1211 
1212     // Generate a snapshot that moves all the upper blocks down to the start.
1213     // It doesn't really matter the order, we just want copies that reference
1214     // blocks that won't exist if the partition shrinks.
ShiftAllSnapshotBlocks(const std::string & name,uint64_t old_size)1215     AssertionResult ShiftAllSnapshotBlocks(const std::string& name, uint64_t old_size) {
1216         std::unique_ptr<ISnapshotWriter> writer;
1217         if (auto res = MapUpdateSnapshot(name, &writer); !res) {
1218             return res;
1219         }
1220         if (!writer->options().max_blocks || !*writer->options().max_blocks) {
1221             return AssertionFailure() << "No max blocks set for " << name << " writer";
1222         }
1223 
1224         uint64_t src_block = (old_size / writer->options().block_size) - 1;
1225         uint64_t dst_block = 0;
1226         uint64_t max_blocks = *writer->options().max_blocks;
1227         while (dst_block < max_blocks && dst_block < src_block) {
1228             if (!writer->AddCopy(dst_block, src_block)) {
1229                 return AssertionFailure() << "Unable to add copy for " << name << " for blocks "
1230                                           << src_block << ", " << dst_block;
1231             }
1232             dst_block++;
1233             src_block--;
1234         }
1235         if (!writer->Finalize()) {
1236             return AssertionFailure() << "Unable to finalize writer for " << name;
1237         }
1238 
1239         auto hash = HashSnapshot(writer.get());
1240         if (hash.empty()) {
1241             return AssertionFailure() << "Unable to hash snapshot writer for " << name;
1242         }
1243         hashes_[name] = hash;
1244 
1245         return AssertionSuccess();
1246     }
1247 
MapUpdateSnapshots(const std::vector<std::string> & names={"", "", ""})1248     AssertionResult MapUpdateSnapshots(const std::vector<std::string>& names = {"sys_b", "vnd_b",
1249                                                                                 "prd_b"}) {
1250         for (const auto& name : names) {
1251             auto res = MapOneUpdateSnapshot(name);
1252             if (!res) {
1253                 return res;
1254             }
1255         }
1256         return AssertionSuccess();
1257     }
1258 
1259     // Create fake install operations to grow the COW device size.
AddOperation(PartitionUpdate * partition_update,uint64_t size_bytes=0)1260     void AddOperation(PartitionUpdate* partition_update, uint64_t size_bytes = 0) {
1261         auto e = partition_update->add_operations()->add_dst_extents();
1262         e->set_start_block(0);
1263         if (size_bytes == 0) {
1264             size_bytes = GetSize(partition_update);
1265         }
1266         e->set_num_blocks(size_bytes / manifest_.block_size());
1267     }
1268 
AddOperationForPartitions(std::vector<PartitionUpdate * > partitions={})1269     void AddOperationForPartitions(std::vector<PartitionUpdate*> partitions = {}) {
1270         if (partitions.empty()) {
1271             partitions = {sys_, vnd_, prd_};
1272         }
1273         for (auto* partition : partitions) {
1274             AddOperation(partition);
1275         }
1276     }
1277 
1278     std::unique_ptr<TestPartitionOpener> opener_;
1279     DeltaArchiveManifest manifest_;
1280     std::unique_ptr<MetadataBuilder> src_;
1281     std::map<std::string, std::string> hashes_;
1282 
1283     PartitionUpdate* sys_ = nullptr;
1284     PartitionUpdate* vnd_ = nullptr;
1285     PartitionUpdate* prd_ = nullptr;
1286     DynamicPartitionGroup* group_ = nullptr;
1287 };
1288 
1289 // Test full update flow executed by update_engine. Some partitions uses super empty space,
1290 // some uses images, and some uses both.
1291 // Also test UnmapUpdateSnapshot unmaps everything.
1292 // Also test first stage mount and merge after this.
TEST_F(SnapshotUpdateTest,FullUpdateFlow)1293 TEST_F(SnapshotUpdateTest, FullUpdateFlow) {
1294     // Grow all partitions. Set |prd| large enough that |sys| and |vnd|'s COWs
1295     // fit in super, but not |prd|.
1296     constexpr uint64_t partition_size = 3788_KiB;
1297     SetSize(sys_, partition_size);
1298     SetSize(vnd_, partition_size);
1299     SetSize(prd_, 18_MiB);
1300 
1301     // Make sure |prd| does not fit in super at all. On VABC, this means we
1302     // fake an extra large COW for |vnd| to fill up super.
1303     vnd_->set_estimate_cow_size(30_MiB);
1304     prd_->set_estimate_cow_size(30_MiB);
1305 
1306     AddOperationForPartitions();
1307 
1308     // Execute the update.
1309     ASSERT_TRUE(sm->BeginUpdate());
1310     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1311 
1312     // Test that partitions prioritize using space in super.
1313     auto tgt = MetadataBuilder::New(*opener_, "super", 1);
1314     ASSERT_NE(tgt, nullptr);
1315     ASSERT_NE(nullptr, tgt->FindPartition("sys_b-cow"));
1316     ASSERT_NE(nullptr, tgt->FindPartition("vnd_b-cow"));
1317     ASSERT_EQ(nullptr, tgt->FindPartition("prd_b-cow"));
1318 
1319     // Write some data to target partitions.
1320     ASSERT_TRUE(WriteSnapshots());
1321 
1322     // Assert that source partitions aren't affected.
1323     for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
1324         ASSERT_TRUE(IsPartitionUnchanged(name));
1325     }
1326 
1327     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1328 
1329     // Simulate shutting down the device.
1330     ASSERT_TRUE(UnmapAll());
1331 
1332     // After reboot, init does first stage mount.
1333     auto init = NewManagerForFirstStageMount("_b");
1334     ASSERT_NE(init, nullptr);
1335     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
1336     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1337 
1338     auto indicator = sm->GetRollbackIndicatorPath();
1339     ASSERT_NE(access(indicator.c_str(), R_OK), 0);
1340 
1341     // Check that the target partitions have the same content.
1342     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
1343         ASSERT_TRUE(IsPartitionUnchanged(name));
1344     }
1345 
1346     // Initiate the merge and wait for it to be completed.
1347     ASSERT_TRUE(init->InitiateMerge());
1348     ASSERT_EQ(init->IsSnapuserdRequired(), snapuserd_required_);
1349     {
1350         // We should have started in SECOND_PHASE since nothing shrinks.
1351         ASSERT_TRUE(AcquireLock());
1352         auto local_lock = std::move(lock_);
1353         auto status = init->ReadSnapshotUpdateStatus(local_lock.get());
1354         ASSERT_EQ(status.merge_phase(), MergePhase::SECOND_PHASE);
1355     }
1356     ASSERT_EQ(UpdateState::MergeCompleted, init->ProcessUpdateState());
1357 
1358     // Make sure the second phase ran and deleted snapshots.
1359     {
1360         ASSERT_TRUE(AcquireLock());
1361         auto local_lock = std::move(lock_);
1362         std::vector<std::string> snapshots;
1363         ASSERT_TRUE(init->ListSnapshots(local_lock.get(), &snapshots));
1364         ASSERT_TRUE(snapshots.empty());
1365     }
1366 
1367     // Check that the target partitions have the same content after the merge.
1368     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
1369         ASSERT_TRUE(IsPartitionUnchanged(name))
1370                 << "Content of " << name << " changes after the merge";
1371     }
1372 }
1373 
TEST_F(SnapshotUpdateTest,DuplicateOps)1374 TEST_F(SnapshotUpdateTest, DuplicateOps) {
1375     if (!snapuserd_required_) {
1376         GTEST_SKIP() << "snapuserd-only test";
1377     }
1378 
1379     // Execute the update.
1380     ASSERT_TRUE(sm->BeginUpdate());
1381     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1382 
1383     // Write some data to target partitions.
1384     ASSERT_TRUE(WriteSnapshots());
1385 
1386     std::vector<PartitionUpdate*> partitions = {sys_, vnd_, prd_};
1387     for (auto* partition : partitions) {
1388         AddOperation(partition);
1389 
1390         std::unique_ptr<ISnapshotWriter> writer;
1391         auto res = MapUpdateSnapshot(partition->partition_name() + "_b", &writer);
1392         ASSERT_TRUE(res);
1393         ASSERT_TRUE(writer->AddZeroBlocks(0, 1));
1394         ASSERT_TRUE(writer->AddZeroBlocks(0, 1));
1395         ASSERT_TRUE(writer->Finalize());
1396     }
1397 
1398     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1399 
1400     // Simulate shutting down the device.
1401     ASSERT_TRUE(UnmapAll());
1402 
1403     // After reboot, init does first stage mount.
1404     auto init = NewManagerForFirstStageMount("_b");
1405     ASSERT_NE(init, nullptr);
1406     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
1407     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1408 
1409     // Initiate the merge and wait for it to be completed.
1410     ASSERT_TRUE(init->InitiateMerge());
1411     ASSERT_EQ(UpdateState::MergeCompleted, init->ProcessUpdateState());
1412 }
1413 
1414 // Test that shrinking and growing partitions at the same time is handled
1415 // correctly in VABC.
TEST_F(SnapshotUpdateTest,SpaceSwapUpdate)1416 TEST_F(SnapshotUpdateTest, SpaceSwapUpdate) {
1417     if (!snapuserd_required_) {
1418         // b/179111359
1419         GTEST_SKIP() << "Skipping snapuserd test";
1420     }
1421 
1422     auto old_sys_size = GetSize(sys_);
1423     auto old_prd_size = GetSize(prd_);
1424 
1425     // Grow |sys| but shrink |prd|.
1426     SetSize(sys_, old_sys_size * 2);
1427     sys_->set_estimate_cow_size(8_MiB);
1428     SetSize(prd_, old_prd_size / 2);
1429     prd_->set_estimate_cow_size(1_MiB);
1430 
1431     AddOperationForPartitions();
1432 
1433     ASSERT_TRUE(sm->BeginUpdate());
1434     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1435 
1436     // Check that the old partition sizes were saved correctly.
1437     {
1438         ASSERT_TRUE(AcquireLock());
1439         auto local_lock = std::move(lock_);
1440 
1441         SnapshotStatus status;
1442         ASSERT_TRUE(sm->ReadSnapshotStatus(local_lock.get(), "prd_b", &status));
1443         ASSERT_EQ(status.old_partition_size(), 3145728);
1444         ASSERT_TRUE(sm->ReadSnapshotStatus(local_lock.get(), "sys_b", &status));
1445         ASSERT_EQ(status.old_partition_size(), 3145728);
1446     }
1447 
1448     ASSERT_TRUE(WriteSnapshotAndHash(sys_));
1449     ASSERT_TRUE(WriteSnapshotAndHash(vnd_));
1450     ASSERT_TRUE(ShiftAllSnapshotBlocks("prd_b", old_prd_size));
1451 
1452     sync();
1453 
1454     // Assert that source partitions aren't affected.
1455     for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
1456         ASSERT_TRUE(IsPartitionUnchanged(name));
1457     }
1458 
1459     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1460 
1461     // Simulate shutting down the device.
1462     ASSERT_TRUE(UnmapAll());
1463 
1464     // After reboot, init does first stage mount.
1465     auto init = NewManagerForFirstStageMount("_b");
1466     ASSERT_NE(init, nullptr);
1467     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
1468     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1469 
1470     auto indicator = sm->GetRollbackIndicatorPath();
1471     ASSERT_NE(access(indicator.c_str(), R_OK), 0);
1472 
1473     // Check that the target partitions have the same content.
1474     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
1475         ASSERT_TRUE(IsPartitionUnchanged(name));
1476     }
1477 
1478     // Initiate the merge and wait for it to be completed.
1479     ASSERT_TRUE(init->InitiateMerge());
1480     ASSERT_EQ(init->IsSnapuserdRequired(), snapuserd_required_);
1481     {
1482         // Check that the merge phase is FIRST_PHASE until at least one call
1483         // to ProcessUpdateState() occurs.
1484         ASSERT_TRUE(AcquireLock());
1485         auto local_lock = std::move(lock_);
1486         auto status = init->ReadSnapshotUpdateStatus(local_lock.get());
1487         ASSERT_EQ(status.merge_phase(), MergePhase::FIRST_PHASE);
1488     }
1489 
1490     // Simulate shutting down the device and creating partitions again.
1491     ASSERT_TRUE(UnmapAll());
1492     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1493 
1494     // Check that we used the correct types after rebooting mid-merge.
1495     DeviceMapper::TargetInfo target;
1496     ASSERT_TRUE(init->IsSnapshotDevice("prd_b", &target));
1497 
1498     bool userspace_snapshots = init->UpdateUsesUserSnapshots();
1499     if (userspace_snapshots) {
1500         ASSERT_EQ(DeviceMapper::GetTargetType(target.spec), "user");
1501         ASSERT_TRUE(init->IsSnapshotDevice("sys_b", &target));
1502         ASSERT_EQ(DeviceMapper::GetTargetType(target.spec), "user");
1503         ASSERT_TRUE(init->IsSnapshotDevice("vnd_b", &target));
1504         ASSERT_EQ(DeviceMapper::GetTargetType(target.spec), "user");
1505     } else {
1506         ASSERT_EQ(DeviceMapper::GetTargetType(target.spec), "snapshot-merge");
1507         ASSERT_TRUE(init->IsSnapshotDevice("sys_b", &target));
1508         ASSERT_EQ(DeviceMapper::GetTargetType(target.spec), "snapshot");
1509         ASSERT_TRUE(init->IsSnapshotDevice("vnd_b", &target));
1510         ASSERT_EQ(DeviceMapper::GetTargetType(target.spec), "snapshot");
1511     }
1512 
1513     // Complete the merge.
1514     ASSERT_EQ(UpdateState::MergeCompleted, init->ProcessUpdateState());
1515 
1516     // Make sure the second phase ran and deleted snapshots.
1517     {
1518         ASSERT_TRUE(AcquireLock());
1519         auto local_lock = std::move(lock_);
1520         std::vector<std::string> snapshots;
1521         ASSERT_TRUE(init->ListSnapshots(local_lock.get(), &snapshots));
1522         ASSERT_TRUE(snapshots.empty());
1523     }
1524 
1525     // Check that the target partitions have the same content after the merge.
1526     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
1527         ASSERT_TRUE(IsPartitionUnchanged(name))
1528                 << "Content of " << name << " changes after the merge";
1529     }
1530 }
1531 
1532 // Test that a transient merge consistency check failure can resume properly.
TEST_F(SnapshotUpdateTest,ConsistencyCheckResume)1533 TEST_F(SnapshotUpdateTest, ConsistencyCheckResume) {
1534     if (!snapuserd_required_) {
1535         // b/179111359
1536         GTEST_SKIP() << "Skipping snapuserd test";
1537     }
1538 
1539     auto old_sys_size = GetSize(sys_);
1540     auto old_prd_size = GetSize(prd_);
1541 
1542     // Grow |sys| but shrink |prd|.
1543     SetSize(sys_, old_sys_size * 2);
1544     sys_->set_estimate_cow_size(8_MiB);
1545     SetSize(prd_, old_prd_size / 2);
1546     prd_->set_estimate_cow_size(1_MiB);
1547 
1548     AddOperationForPartitions();
1549 
1550     ASSERT_TRUE(sm->BeginUpdate());
1551     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1552     ASSERT_TRUE(WriteSnapshotAndHash(sys_));
1553     ASSERT_TRUE(WriteSnapshotAndHash(vnd_));
1554     ASSERT_TRUE(ShiftAllSnapshotBlocks("prd_b", old_prd_size));
1555 
1556     sync();
1557 
1558     // Assert that source partitions aren't affected.
1559     for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
1560         ASSERT_TRUE(IsPartitionUnchanged(name));
1561     }
1562 
1563     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1564 
1565     // Simulate shutting down the device.
1566     ASSERT_TRUE(UnmapAll());
1567 
1568     // After reboot, init does first stage mount.
1569     auto init = NewManagerForFirstStageMount("_b");
1570     ASSERT_NE(init, nullptr);
1571     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
1572     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1573 
1574     // Check that the target partitions have the same content.
1575     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
1576         ASSERT_TRUE(IsPartitionUnchanged(name));
1577     }
1578 
1579     auto old_checker = init->merge_consistency_checker();
1580 
1581     init->set_merge_consistency_checker(
1582             [](const std::string&, const SnapshotStatus&) -> MergeFailureCode {
1583                 return MergeFailureCode::WrongMergeCountConsistencyCheck;
1584             });
1585 
1586     // Initiate the merge and wait for it to be completed.
1587     ASSERT_TRUE(init->InitiateMerge());
1588     ASSERT_EQ(init->IsSnapuserdRequired(), snapuserd_required_);
1589     {
1590         // Check that the merge phase is FIRST_PHASE until at least one call
1591         // to ProcessUpdateState() occurs.
1592         ASSERT_TRUE(AcquireLock());
1593         auto local_lock = std::move(lock_);
1594         auto status = init->ReadSnapshotUpdateStatus(local_lock.get());
1595         ASSERT_EQ(status.merge_phase(), MergePhase::FIRST_PHASE);
1596     }
1597 
1598     // Merge should have failed.
1599     ASSERT_EQ(UpdateState::MergeFailed, init->ProcessUpdateState());
1600 
1601     // Simulate shutting down the device and creating partitions again.
1602     ASSERT_TRUE(UnmapAll());
1603 
1604     // Restore the checker.
1605     init->set_merge_consistency_checker(std::move(old_checker));
1606 
1607     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1608 
1609     // Complete the merge.
1610     ASSERT_EQ(UpdateState::MergeCompleted, init->ProcessUpdateState());
1611 
1612     // Check that the target partitions have the same content after the merge.
1613     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
1614         ASSERT_TRUE(IsPartitionUnchanged(name))
1615                 << "Content of " << name << " changes after the merge";
1616     }
1617 }
1618 
1619 // Test that if new system partitions uses empty space in super, that region is not snapshotted.
TEST_F(SnapshotUpdateTest,DirectWriteEmptySpace)1620 TEST_F(SnapshotUpdateTest, DirectWriteEmptySpace) {
1621     GTEST_SKIP() << "b/141889746";
1622     SetSize(sys_, 4_MiB);
1623     // vnd_b and prd_b are unchanged.
1624     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1625     ASSERT_EQ(3_MiB, GetSnapshotSize("sys_b").value_or(0));
1626 }
1627 
1628 // Test that if new system partitions uses space of old vendor partition, that region is
1629 // snapshotted.
TEST_F(SnapshotUpdateTest,SnapshotOldPartitions)1630 TEST_F(SnapshotUpdateTest, SnapshotOldPartitions) {
1631     SetSize(sys_, 4_MiB);  // grows
1632     SetSize(vnd_, 2_MiB);  // shrinks
1633     // prd_b is unchanged
1634     ASSERT_TRUE(sm->BeginUpdate());
1635     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1636     ASSERT_EQ(4_MiB, GetSnapshotSize("sys_b").value_or(0));
1637 }
1638 
1639 // Test that even if there seem to be empty space in target metadata, COW partition won't take
1640 // it because they are used by old partitions.
TEST_F(SnapshotUpdateTest,CowPartitionDoNotTakeOldPartitions)1641 TEST_F(SnapshotUpdateTest, CowPartitionDoNotTakeOldPartitions) {
1642     SetSize(sys_, 2_MiB);  // shrinks
1643     // vnd_b and prd_b are unchanged.
1644     ASSERT_TRUE(sm->BeginUpdate());
1645     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1646 
1647     auto tgt = MetadataBuilder::New(*opener_, "super", 1);
1648     ASSERT_NE(nullptr, tgt);
1649     auto metadata = tgt->Export();
1650     ASSERT_NE(nullptr, metadata);
1651     std::vector<std::string> written;
1652     // Write random data to all COW partitions in super
1653     for (auto p : metadata->partitions) {
1654         if (GetPartitionGroupName(metadata->groups[p.group_index]) != kCowGroupName) {
1655             continue;
1656         }
1657         std::string path;
1658         ASSERT_TRUE(CreateLogicalPartition(
1659                 CreateLogicalPartitionParams{
1660                         .block_device = fake_super,
1661                         .metadata = metadata.get(),
1662                         .partition = &p,
1663                         .timeout_ms = 1s,
1664                         .partition_opener = opener_.get(),
1665                 },
1666                 &path));
1667         ASSERT_TRUE(WriteRandomData(path));
1668         written.push_back(GetPartitionName(p));
1669     }
1670     ASSERT_FALSE(written.empty())
1671             << "No COW partitions are created even if there are empty space in super partition";
1672 
1673     // Make sure source partitions aren't affected.
1674     for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
1675         ASSERT_TRUE(IsPartitionUnchanged(name));
1676     }
1677 }
1678 
1679 // Test that it crashes after creating snapshot status file but before creating COW image, then
1680 // calling CreateUpdateSnapshots again works.
TEST_F(SnapshotUpdateTest,SnapshotStatusFileWithoutCow)1681 TEST_F(SnapshotUpdateTest, SnapshotStatusFileWithoutCow) {
1682     // Write some trash snapshot files to simulate leftovers from previous runs.
1683     {
1684         ASSERT_TRUE(AcquireLock());
1685         auto local_lock = std::move(lock_);
1686         SnapshotStatus status;
1687         status.set_name("sys_b");
1688         ASSERT_TRUE(sm->WriteSnapshotStatus(local_lock.get(), status));
1689         ASSERT_TRUE(image_manager_->CreateBackingImage("sys_b-cow-img", 1_MiB,
1690                                                        IImageManager::CREATE_IMAGE_DEFAULT));
1691     }
1692 
1693     // Redo the update.
1694     ASSERT_TRUE(sm->BeginUpdate());
1695     ASSERT_TRUE(sm->UnmapUpdateSnapshot("sys_b"));
1696 
1697     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1698 
1699     // Check that target partitions can be mapped.
1700     EXPECT_TRUE(MapUpdateSnapshots());
1701 }
1702 
1703 // Test that the old partitions are not modified.
TEST_F(SnapshotUpdateTest,TestRollback)1704 TEST_F(SnapshotUpdateTest, TestRollback) {
1705     // Execute the update.
1706     ASSERT_TRUE(sm->BeginUpdate());
1707     ASSERT_TRUE(sm->UnmapUpdateSnapshot("sys_b"));
1708 
1709     AddOperationForPartitions();
1710 
1711     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1712 
1713     // Write some data to target partitions.
1714     ASSERT_TRUE(WriteSnapshots());
1715 
1716     // Assert that source partitions aren't affected.
1717     for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
1718         ASSERT_TRUE(IsPartitionUnchanged(name));
1719     }
1720 
1721     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1722 
1723     // Simulate shutting down the device.
1724     ASSERT_TRUE(UnmapAll());
1725 
1726     // After reboot, init does first stage mount.
1727     auto init = NewManagerForFirstStageMount("_b");
1728     ASSERT_NE(init, nullptr);
1729     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
1730     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1731 
1732     // Check that the target partitions have the same content.
1733     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
1734         ASSERT_TRUE(IsPartitionUnchanged(name));
1735     }
1736 
1737     // Simulate shutting down the device again.
1738     ASSERT_TRUE(UnmapAll());
1739     init = NewManagerForFirstStageMount("_a");
1740     ASSERT_NE(init, nullptr);
1741     ASSERT_FALSE(init->NeedSnapshotsInFirstStageMount());
1742     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1743 
1744     // Assert that the source partitions aren't affected.
1745     for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
1746         ASSERT_TRUE(IsPartitionUnchanged(name));
1747     }
1748 }
1749 
1750 // Test that if an update is applied but not booted into, it can be canceled.
TEST_F(SnapshotUpdateTest,CancelAfterApply)1751 TEST_F(SnapshotUpdateTest, CancelAfterApply) {
1752     ASSERT_TRUE(sm->BeginUpdate());
1753     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1754     ASSERT_TRUE(sm->CancelUpdate());
1755 }
1756 
ToIntervals(const std::vector<std::unique_ptr<Extent>> & extents)1757 static std::vector<Interval> ToIntervals(const std::vector<std::unique_ptr<Extent>>& extents) {
1758     std::vector<Interval> ret;
1759     std::transform(extents.begin(), extents.end(), std::back_inserter(ret),
1760                    [](const auto& extent) { return extent->AsLinearExtent()->AsInterval(); });
1761     return ret;
1762 }
1763 
1764 // Test that at the second update, old COW partition spaces are reclaimed.
TEST_F(SnapshotUpdateTest,ReclaimCow)1765 TEST_F(SnapshotUpdateTest, ReclaimCow) {
1766     // Make sure VABC cows are small enough that they fit in fake_super.
1767     sys_->set_estimate_cow_size(64_KiB);
1768     vnd_->set_estimate_cow_size(64_KiB);
1769     prd_->set_estimate_cow_size(64_KiB);
1770 
1771     // Execute the first update.
1772     ASSERT_TRUE(sm->BeginUpdate());
1773     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1774     ASSERT_TRUE(MapUpdateSnapshots());
1775     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1776 
1777     // Simulate shutting down the device.
1778     ASSERT_TRUE(UnmapAll());
1779 
1780     // After reboot, init does first stage mount.
1781     auto init = NewManagerForFirstStageMount("_b");
1782     ASSERT_NE(init, nullptr);
1783     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
1784     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1785     init = nullptr;
1786 
1787     // Initiate the merge and wait for it to be completed.
1788     auto new_sm = SnapshotManager::New(new TestDeviceInfo(fake_super, "_b"));
1789     ASSERT_TRUE(new_sm->InitiateMerge());
1790     ASSERT_EQ(UpdateState::MergeCompleted, new_sm->ProcessUpdateState());
1791 
1792     // Execute the second update.
1793     ASSERT_TRUE(new_sm->BeginUpdate());
1794     ASSERT_TRUE(new_sm->CreateUpdateSnapshots(manifest_));
1795 
1796     // Check that the old COW space is reclaimed and does not occupy space of mapped partitions.
1797     auto src = MetadataBuilder::New(*opener_, "super", 1);
1798     ASSERT_NE(src, nullptr);
1799     auto tgt = MetadataBuilder::New(*opener_, "super", 0);
1800     ASSERT_NE(tgt, nullptr);
1801     for (const auto& cow_part_name : {"sys_a-cow", "vnd_a-cow", "prd_a-cow"}) {
1802         auto* cow_part = tgt->FindPartition(cow_part_name);
1803         ASSERT_NE(nullptr, cow_part) << cow_part_name << " does not exist in target metadata";
1804         auto cow_intervals = ToIntervals(cow_part->extents());
1805         for (const auto& old_part_name : {"sys_b", "vnd_b", "prd_b"}) {
1806             auto* old_part = src->FindPartition(old_part_name);
1807             ASSERT_NE(nullptr, old_part) << old_part_name << " does not exist in source metadata";
1808             auto old_intervals = ToIntervals(old_part->extents());
1809 
1810             auto intersect = Interval::Intersect(cow_intervals, old_intervals);
1811             ASSERT_TRUE(intersect.empty()) << "COW uses space of source partitions";
1812         }
1813     }
1814 }
1815 
TEST_F(SnapshotUpdateTest,RetrofitAfterRegularAb)1816 TEST_F(SnapshotUpdateTest, RetrofitAfterRegularAb) {
1817     constexpr auto kRetrofitGroupSize = kGroupSize / 2;
1818 
1819     // Initialize device-mapper / disk
1820     ASSERT_TRUE(UnmapAll());
1821     FormatFakeSuper();
1822 
1823     // Setup source partition metadata to have both _a and _b partitions.
1824     src_ = MetadataBuilder::New(*opener_, "super", 0);
1825     ASSERT_NE(nullptr, src_);
1826     for (const auto& suffix : {"_a"s, "_b"s}) {
1827         ASSERT_TRUE(src_->AddGroup(group_->name() + suffix, kRetrofitGroupSize));
1828         for (const auto& name : {"sys"s, "vnd"s, "prd"s}) {
1829             auto partition = src_->AddPartition(name + suffix, group_->name() + suffix, 0);
1830             ASSERT_NE(nullptr, partition);
1831             ASSERT_TRUE(src_->ResizePartition(partition, 2_MiB));
1832         }
1833     }
1834     auto metadata = src_->Export();
1835     ASSERT_NE(nullptr, metadata);
1836     ASSERT_TRUE(UpdatePartitionTable(*opener_, "super", *metadata.get(), 0));
1837 
1838     // Flash source partitions
1839     std::string path;
1840     for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
1841         ASSERT_TRUE(CreateLogicalPartition(
1842                 CreateLogicalPartitionParams{
1843                         .block_device = fake_super,
1844                         .metadata_slot = 0,
1845                         .partition_name = name,
1846                         .timeout_ms = 1s,
1847                         .partition_opener = opener_.get(),
1848                 },
1849                 &path));
1850         ASSERT_TRUE(WriteRandomData(path));
1851         auto hash = GetHash(path);
1852         ASSERT_TRUE(hash.has_value());
1853         hashes_[name] = *hash;
1854     }
1855 
1856     // Setup manifest.
1857     group_->set_size(kRetrofitGroupSize);
1858     for (auto* partition : {sys_, vnd_, prd_}) {
1859         SetSize(partition, 2_MiB);
1860     }
1861     AddOperationForPartitions();
1862 
1863     ASSERT_TRUE(sm->BeginUpdate());
1864     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1865 
1866     // Test that COW image should not be created for retrofit devices; super
1867     // should be big enough.
1868     ASSERT_FALSE(image_manager_->BackingImageExists("sys_b-cow-img"));
1869     ASSERT_FALSE(image_manager_->BackingImageExists("vnd_b-cow-img"));
1870     ASSERT_FALSE(image_manager_->BackingImageExists("prd_b-cow-img"));
1871 
1872     // Write some data to target partitions.
1873     ASSERT_TRUE(WriteSnapshots());
1874 
1875     // Assert that source partitions aren't affected.
1876     for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
1877         ASSERT_TRUE(IsPartitionUnchanged(name));
1878     }
1879 
1880     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1881 }
1882 
TEST_F(SnapshotUpdateTest,MergeCannotRemoveCow)1883 TEST_F(SnapshotUpdateTest, MergeCannotRemoveCow) {
1884     // Make source partitions as big as possible to force COW image to be created.
1885     SetSize(sys_, 10_MiB);
1886     SetSize(vnd_, 10_MiB);
1887     SetSize(prd_, 10_MiB);
1888     sys_->set_estimate_cow_size(12_MiB);
1889     vnd_->set_estimate_cow_size(12_MiB);
1890     prd_->set_estimate_cow_size(12_MiB);
1891 
1892     src_ = MetadataBuilder::New(*opener_, "super", 0);
1893     ASSERT_NE(src_, nullptr);
1894     src_->RemoveGroupAndPartitions(group_->name() + "_a");
1895     src_->RemoveGroupAndPartitions(group_->name() + "_b");
1896     ASSERT_TRUE(FillFakeMetadata(src_.get(), manifest_, "_a"));
1897     auto metadata = src_->Export();
1898     ASSERT_NE(nullptr, metadata);
1899     ASSERT_TRUE(UpdatePartitionTable(*opener_, "super", *metadata.get(), 0));
1900 
1901     // Add operations for sys. The whole device is written.
1902     AddOperation(sys_);
1903 
1904     // Execute the update.
1905     ASSERT_TRUE(sm->BeginUpdate());
1906     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
1907     ASSERT_TRUE(MapUpdateSnapshots());
1908     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
1909 
1910     // Simulate shutting down the device.
1911     ASSERT_TRUE(UnmapAll());
1912 
1913     // After reboot, init does first stage mount.
1914     // Normally we should use NewManagerForFirstStageMount, but if so,
1915     // "gsid.mapped_image.sys_b-cow-img" won't be set.
1916     auto init = SnapshotManager::New(new TestDeviceInfo(fake_super, "_b"));
1917     ASSERT_NE(init, nullptr);
1918     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1919 
1920     // Keep an open handle to the cow device. This should cause the merge to
1921     // be incomplete.
1922     auto cow_path = android::base::GetProperty("gsid.mapped_image.sys_b-cow-img", "");
1923     unique_fd fd(open(cow_path.c_str(), O_RDONLY | O_CLOEXEC));
1924     ASSERT_GE(fd, 0);
1925 
1926     // COW cannot be removed due to open fd, so expect a soft failure.
1927     ASSERT_TRUE(init->InitiateMerge());
1928     ASSERT_EQ(UpdateState::MergeNeedsReboot, init->ProcessUpdateState());
1929 
1930     // Simulate shutting down the device.
1931     fd.reset();
1932     ASSERT_TRUE(UnmapAll());
1933 
1934     // init does first stage mount again.
1935     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
1936 
1937     // sys_b should be mapped as a dm-linear device directly.
1938     ASSERT_FALSE(sm->IsSnapshotDevice("sys_b", nullptr));
1939 
1940     // Merge should be able to complete now.
1941     ASSERT_EQ(UpdateState::MergeCompleted, init->ProcessUpdateState());
1942 }
1943 
1944 class MetadataMountedTest : public ::testing::Test {
1945   public:
1946     // This is so main() can instantiate this to invoke Cleanup.
TestBody()1947     virtual void TestBody() override {}
SetUp()1948     void SetUp() override {
1949         SKIP_IF_NON_VIRTUAL_AB();
1950         metadata_dir_ = test_device->GetMetadataDir();
1951         ASSERT_TRUE(ReadDefaultFstab(&fstab_));
1952     }
TearDown()1953     void TearDown() override {
1954         RETURN_IF_NON_VIRTUAL_AB();
1955         SetUp();
1956         // Remount /metadata
1957         test_device->set_recovery(false);
1958         EXPECT_TRUE(android::fs_mgr::EnsurePathMounted(&fstab_, metadata_dir_));
1959     }
IsMetadataMounted()1960     AssertionResult IsMetadataMounted() {
1961         Fstab mounted_fstab;
1962         if (!ReadFstabFromFile("/proc/mounts", &mounted_fstab)) {
1963             ADD_FAILURE() << "Failed to scan mounted volumes";
1964             return AssertionFailure() << "Failed to scan mounted volumes";
1965         }
1966 
1967         auto entry = GetEntryForPath(&fstab_, metadata_dir_);
1968         if (entry == nullptr) {
1969             return AssertionFailure() << "No mount point found in fstab for path " << metadata_dir_;
1970         }
1971 
1972         auto mv = GetEntryForMountPoint(&mounted_fstab, entry->mount_point);
1973         if (mv == nullptr) {
1974             return AssertionFailure() << metadata_dir_ << " is not mounted";
1975         }
1976         return AssertionSuccess() << metadata_dir_ << " is mounted";
1977     }
1978     std::string metadata_dir_;
1979     Fstab fstab_;
1980 };
1981 
MountMetadata()1982 void MountMetadata() {
1983     MetadataMountedTest().TearDown();
1984 }
1985 
TEST_F(MetadataMountedTest,Android)1986 TEST_F(MetadataMountedTest, Android) {
1987     auto device = sm->EnsureMetadataMounted();
1988     EXPECT_NE(nullptr, device);
1989     device.reset();
1990 
1991     EXPECT_TRUE(IsMetadataMounted());
1992     EXPECT_TRUE(sm->CancelUpdate()) << "Metadata dir should never be unmounted in Android mode";
1993 }
1994 
TEST_F(MetadataMountedTest,Recovery)1995 TEST_F(MetadataMountedTest, Recovery) {
1996     test_device->set_recovery(true);
1997     metadata_dir_ = test_device->GetMetadataDir();
1998 
1999     EXPECT_TRUE(android::fs_mgr::EnsurePathUnmounted(&fstab_, metadata_dir_));
2000     EXPECT_FALSE(IsMetadataMounted());
2001 
2002     auto device = sm->EnsureMetadataMounted();
2003     EXPECT_NE(nullptr, device);
2004     EXPECT_TRUE(IsMetadataMounted());
2005 
2006     device.reset();
2007     EXPECT_FALSE(IsMetadataMounted());
2008 }
2009 
2010 // Test that during a merge, we can wipe data in recovery.
TEST_F(SnapshotUpdateTest,MergeInRecovery)2011 TEST_F(SnapshotUpdateTest, MergeInRecovery) {
2012     // Execute the first update.
2013     ASSERT_TRUE(sm->BeginUpdate());
2014     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
2015     ASSERT_TRUE(MapUpdateSnapshots());
2016     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
2017 
2018     // Simulate shutting down the device.
2019     ASSERT_TRUE(UnmapAll());
2020 
2021     // After reboot, init does first stage mount.
2022     auto init = NewManagerForFirstStageMount("_b");
2023     ASSERT_NE(init, nullptr);
2024     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
2025     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
2026     init = nullptr;
2027 
2028     // Initiate the merge and then immediately stop it to simulate a reboot.
2029     auto new_sm = SnapshotManager::New(new TestDeviceInfo(fake_super, "_b"));
2030     ASSERT_TRUE(new_sm->InitiateMerge());
2031     ASSERT_TRUE(UnmapAll());
2032 
2033     // Simulate a reboot into recovery.
2034     auto test_device = std::make_unique<TestDeviceInfo>(fake_super, "_b");
2035     test_device->set_recovery(true);
2036     new_sm = NewManagerForFirstStageMount(test_device.release());
2037 
2038     ASSERT_TRUE(new_sm->HandleImminentDataWipe());
2039     ASSERT_EQ(new_sm->GetUpdateState(), UpdateState::None);
2040 }
2041 
2042 // Test that a merge does not clear the snapshot state in fastboot.
TEST_F(SnapshotUpdateTest,MergeInFastboot)2043 TEST_F(SnapshotUpdateTest, MergeInFastboot) {
2044     // Execute the first update.
2045     ASSERT_TRUE(sm->BeginUpdate());
2046     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
2047     ASSERT_TRUE(MapUpdateSnapshots());
2048     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
2049 
2050     // Simulate shutting down the device.
2051     ASSERT_TRUE(UnmapAll());
2052 
2053     // After reboot, init does first stage mount.
2054     auto init = NewManagerForFirstStageMount("_b");
2055     ASSERT_NE(init, nullptr);
2056     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
2057     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
2058     init = nullptr;
2059 
2060     // Initiate the merge and then immediately stop it to simulate a reboot.
2061     auto new_sm = SnapshotManager::New(new TestDeviceInfo(fake_super, "_b"));
2062     ASSERT_TRUE(new_sm->InitiateMerge());
2063     ASSERT_TRUE(UnmapAll());
2064 
2065     // Simulate a reboot into recovery.
2066     auto test_device = std::make_unique<TestDeviceInfo>(fake_super, "_b");
2067     test_device->set_recovery(true);
2068     new_sm = NewManagerForFirstStageMount(test_device.release());
2069 
2070     ASSERT_TRUE(new_sm->FinishMergeInRecovery());
2071 
2072     ASSERT_TRUE(UnmapAll());
2073 
2074     auto mount = new_sm->EnsureMetadataMounted();
2075     ASSERT_TRUE(mount && mount->HasDevice());
2076     ASSERT_EQ(new_sm->ProcessUpdateState(), UpdateState::MergeCompleted);
2077 
2078     // Finish the merge in a normal boot.
2079     test_device = std::make_unique<TestDeviceInfo>(fake_super, "_b");
2080     init = NewManagerForFirstStageMount(test_device.release());
2081     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
2082     init = nullptr;
2083 
2084     test_device = std::make_unique<TestDeviceInfo>(fake_super, "_b");
2085     new_sm = NewManagerForFirstStageMount(test_device.release());
2086     ASSERT_EQ(new_sm->ProcessUpdateState(), UpdateState::MergeCompleted);
2087     ASSERT_EQ(new_sm->ProcessUpdateState(), UpdateState::None);
2088 }
2089 
2090 // Test that after an OTA, before a merge, we can wipe data in recovery.
TEST_F(SnapshotUpdateTest,DataWipeRollbackInRecovery)2091 TEST_F(SnapshotUpdateTest, DataWipeRollbackInRecovery) {
2092     // Execute the first update.
2093     ASSERT_TRUE(sm->BeginUpdate());
2094     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
2095     ASSERT_TRUE(MapUpdateSnapshots());
2096     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
2097 
2098     // Simulate shutting down the device.
2099     ASSERT_TRUE(UnmapAll());
2100 
2101     // Simulate a reboot into recovery.
2102     auto test_device = new TestDeviceInfo(fake_super, "_b");
2103     test_device->set_recovery(true);
2104     auto new_sm = NewManagerForFirstStageMount(test_device);
2105 
2106     ASSERT_TRUE(new_sm->HandleImminentDataWipe());
2107     // Manually mount metadata so that we can call GetUpdateState() below.
2108     MountMetadata();
2109     EXPECT_EQ(new_sm->GetUpdateState(), UpdateState::None);
2110     EXPECT_TRUE(test_device->IsSlotUnbootable(1));
2111     EXPECT_FALSE(test_device->IsSlotUnbootable(0));
2112 }
2113 
2114 // Test that after an OTA and a bootloader rollback with no merge, we can wipe
2115 // data in recovery.
TEST_F(SnapshotUpdateTest,DataWipeAfterRollback)2116 TEST_F(SnapshotUpdateTest, DataWipeAfterRollback) {
2117     // Execute the first update.
2118     ASSERT_TRUE(sm->BeginUpdate());
2119     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
2120     ASSERT_TRUE(MapUpdateSnapshots());
2121     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
2122 
2123     // Simulate shutting down the device.
2124     ASSERT_TRUE(UnmapAll());
2125 
2126     // Simulate a rollback, with reboot into recovery.
2127     auto test_device = new TestDeviceInfo(fake_super, "_a");
2128     test_device->set_recovery(true);
2129     auto new_sm = NewManagerForFirstStageMount(test_device);
2130 
2131     ASSERT_TRUE(new_sm->HandleImminentDataWipe());
2132     EXPECT_EQ(new_sm->GetUpdateState(), UpdateState::None);
2133     EXPECT_FALSE(test_device->IsSlotUnbootable(0));
2134     EXPECT_FALSE(test_device->IsSlotUnbootable(1));
2135 }
2136 
2137 // Test update package that requests data wipe.
TEST_F(SnapshotUpdateTest,DataWipeRequiredInPackage)2138 TEST_F(SnapshotUpdateTest, DataWipeRequiredInPackage) {
2139     AddOperationForPartitions();
2140     // Execute the update.
2141     ASSERT_TRUE(sm->BeginUpdate());
2142     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
2143 
2144     // Write some data to target partitions.
2145     ASSERT_TRUE(WriteSnapshots());
2146 
2147     ASSERT_TRUE(sm->FinishedSnapshotWrites(true /* wipe */));
2148 
2149     // Simulate shutting down the device.
2150     ASSERT_TRUE(UnmapAll());
2151 
2152     // Simulate a reboot into recovery.
2153     auto test_device = new TestDeviceInfo(fake_super, "_b");
2154     test_device->set_recovery(true);
2155     auto new_sm = NewManagerForFirstStageMount(test_device);
2156 
2157     ASSERT_TRUE(new_sm->HandleImminentDataWipe());
2158     // Manually mount metadata so that we can call GetUpdateState() below.
2159     MountMetadata();
2160     EXPECT_EQ(new_sm->GetUpdateState(), UpdateState::None);
2161     ASSERT_FALSE(test_device->IsSlotUnbootable(1));
2162     ASSERT_FALSE(test_device->IsSlotUnbootable(0));
2163 
2164     ASSERT_TRUE(UnmapAll());
2165 
2166     // Now reboot into new slot.
2167     test_device = new TestDeviceInfo(fake_super, "_b");
2168     auto init = NewManagerForFirstStageMount(test_device);
2169     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
2170     // Verify that we are on the downgraded build.
2171     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
2172         ASSERT_TRUE(IsPartitionUnchanged(name)) << name;
2173     }
2174 }
2175 
2176 // Test update package that requests data wipe.
TEST_F(SnapshotUpdateTest,DataWipeWithStaleSnapshots)2177 TEST_F(SnapshotUpdateTest, DataWipeWithStaleSnapshots) {
2178     AddOperationForPartitions();
2179 
2180     // Execute the update.
2181     ASSERT_TRUE(sm->BeginUpdate());
2182     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
2183 
2184     // Write some data to target partitions.
2185     ASSERT_TRUE(WriteSnapshots());
2186 
2187     // Create a stale snapshot that should not exist.
2188     {
2189         ASSERT_TRUE(AcquireLock());
2190 
2191         PartitionCowCreator cow_creator = {
2192                 .using_snapuserd = snapuserd_required_,
2193                 .compression_algorithm = snapuserd_required_ ? FLAGS_compression_method : "",
2194         };
2195         SnapshotStatus status;
2196         status.set_name("sys_a");
2197         status.set_device_size(1_MiB);
2198         status.set_snapshot_size(2_MiB);
2199         status.set_cow_partition_size(2_MiB);
2200 
2201         ASSERT_TRUE(sm->CreateSnapshot(lock_.get(), &cow_creator, &status));
2202         lock_ = nullptr;
2203 
2204         ASSERT_TRUE(sm->EnsureImageManager());
2205         ASSERT_TRUE(sm->image_manager()->CreateBackingImage("sys_a", 1_MiB, 0));
2206     }
2207 
2208     ASSERT_TRUE(sm->FinishedSnapshotWrites(true /* wipe */));
2209 
2210     // Simulate shutting down the device.
2211     ASSERT_TRUE(UnmapAll());
2212 
2213     // Simulate a reboot into recovery.
2214     auto test_device = new TestDeviceInfo(fake_super, "_b");
2215     test_device->set_recovery(true);
2216     auto new_sm = NewManagerForFirstStageMount(test_device);
2217 
2218     ASSERT_TRUE(new_sm->HandleImminentDataWipe());
2219     // Manually mount metadata so that we can call GetUpdateState() below.
2220     MountMetadata();
2221     EXPECT_EQ(new_sm->GetUpdateState(), UpdateState::None);
2222     ASSERT_FALSE(test_device->IsSlotUnbootable(1));
2223     ASSERT_FALSE(test_device->IsSlotUnbootable(0));
2224 
2225     ASSERT_TRUE(UnmapAll());
2226 
2227     // Now reboot into new slot.
2228     test_device = new TestDeviceInfo(fake_super, "_b");
2229     auto init = NewManagerForFirstStageMount(test_device);
2230     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
2231     // Verify that we are on the downgraded build.
2232     for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
2233         ASSERT_TRUE(IsPartitionUnchanged(name)) << name;
2234     }
2235 }
2236 
TEST_F(SnapshotUpdateTest,Hashtree)2237 TEST_F(SnapshotUpdateTest, Hashtree) {
2238     constexpr auto partition_size = 4_MiB;
2239     constexpr auto data_size = 3_MiB;
2240     constexpr auto hashtree_size = 512_KiB;
2241     constexpr auto fec_size = partition_size - data_size - hashtree_size;
2242 
2243     const auto block_size = manifest_.block_size();
2244     SetSize(sys_, partition_size);
2245     AddOperation(sys_, data_size);
2246 
2247     sys_->set_estimate_cow_size(partition_size + data_size);
2248 
2249     // Set hastree extents.
2250     sys_->mutable_hash_tree_data_extent()->set_start_block(0);
2251     sys_->mutable_hash_tree_data_extent()->set_num_blocks(data_size / block_size);
2252 
2253     sys_->mutable_hash_tree_extent()->set_start_block(data_size / block_size);
2254     sys_->mutable_hash_tree_extent()->set_num_blocks(hashtree_size / block_size);
2255 
2256     // Set FEC extents.
2257     sys_->mutable_fec_data_extent()->set_start_block(0);
2258     sys_->mutable_fec_data_extent()->set_num_blocks((data_size + hashtree_size) / block_size);
2259 
2260     sys_->mutable_fec_extent()->set_start_block((data_size + hashtree_size) / block_size);
2261     sys_->mutable_fec_extent()->set_num_blocks(fec_size / block_size);
2262 
2263     ASSERT_TRUE(sm->BeginUpdate());
2264     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
2265 
2266     // Map and write some data to target partition.
2267     ASSERT_TRUE(MapUpdateSnapshots({"vnd_b", "prd_b"}));
2268     ASSERT_TRUE(WriteSnapshotAndHash(sys_));
2269 
2270     // Finish update.
2271     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
2272 
2273     // Simulate shutting down the device.
2274     ASSERT_TRUE(UnmapAll());
2275 
2276     // After reboot, init does first stage mount.
2277     auto init = NewManagerForFirstStageMount("_b");
2278     ASSERT_NE(init, nullptr);
2279     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
2280     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
2281 
2282     // Check that the target partition have the same content. Hashtree and FEC extents
2283     // should be accounted for.
2284     ASSERT_TRUE(IsPartitionUnchanged("sys_b"));
2285 }
2286 
2287 // Test for overflow bit after update
TEST_F(SnapshotUpdateTest,Overflow)2288 TEST_F(SnapshotUpdateTest, Overflow) {
2289     if (snapuserd_required_) {
2290         GTEST_SKIP() << "No overflow bit set for snapuserd COWs";
2291     }
2292 
2293     const auto actual_write_size = GetSize(sys_);
2294     const auto declared_write_size = actual_write_size - 1_MiB;
2295 
2296     AddOperation(sys_, declared_write_size);
2297 
2298     // Execute the update.
2299     ASSERT_TRUE(sm->BeginUpdate());
2300     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
2301 
2302     // Map and write some data to target partitions.
2303     ASSERT_TRUE(MapUpdateSnapshots({"vnd_b", "prd_b"}));
2304     ASSERT_TRUE(WriteSnapshotAndHash(sys_));
2305 
2306     std::vector<android::dm::DeviceMapper::TargetInfo> table;
2307     ASSERT_TRUE(DeviceMapper::Instance().GetTableStatus("sys_b", &table));
2308     ASSERT_EQ(1u, table.size());
2309     EXPECT_TRUE(table[0].IsOverflowSnapshot());
2310 
2311     ASSERT_FALSE(sm->FinishedSnapshotWrites(false))
2312             << "FinishedSnapshotWrites should detect overflow of CoW device.";
2313 }
2314 
TEST_F(SnapshotUpdateTest,AddPartition)2315 TEST_F(SnapshotUpdateTest, AddPartition) {
2316     group_->add_partition_names("dlkm");
2317 
2318     auto dlkm = manifest_.add_partitions();
2319     dlkm->set_partition_name("dlkm");
2320     dlkm->set_estimate_cow_size(2_MiB);
2321     SetSize(dlkm, 3_MiB);
2322 
2323     // Grow all partitions. Set |prd| large enough that |sys| and |vnd|'s COWs
2324     // fit in super, but not |prd|.
2325     constexpr uint64_t partition_size = 3788_KiB;
2326     SetSize(sys_, partition_size);
2327     SetSize(vnd_, partition_size);
2328     SetSize(prd_, partition_size);
2329     SetSize(dlkm, partition_size);
2330 
2331     AddOperationForPartitions({sys_, vnd_, prd_, dlkm});
2332 
2333     // Execute the update.
2334     ASSERT_TRUE(sm->BeginUpdate());
2335     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
2336 
2337     // Write some data to target partitions.
2338     for (const auto& partition : {sys_, vnd_, prd_, dlkm}) {
2339         ASSERT_TRUE(WriteSnapshotAndHash(partition));
2340     }
2341 
2342     // Assert that source partitions aren't affected.
2343     for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
2344         ASSERT_TRUE(IsPartitionUnchanged(name));
2345     }
2346 
2347     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
2348 
2349     // Simulate shutting down the device.
2350     ASSERT_TRUE(UnmapAll());
2351 
2352     // After reboot, init does first stage mount.
2353     auto init = NewManagerForFirstStageMount("_b");
2354     ASSERT_NE(init, nullptr);
2355 
2356     ASSERT_TRUE(init->EnsureSnapuserdConnected());
2357     init->set_use_first_stage_snapuserd(true);
2358 
2359     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
2360     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
2361 
2362     // Check that the target partitions have the same content.
2363     std::vector<std::string> partitions = {"sys_b", "vnd_b", "prd_b", "dlkm_b"};
2364     for (const auto& name : partitions) {
2365         ASSERT_TRUE(IsPartitionUnchanged(name));
2366     }
2367 
2368     ASSERT_TRUE(init->PerformInitTransition(SnapshotManager::InitTransition::SECOND_STAGE));
2369     for (const auto& name : partitions) {
2370         ASSERT_TRUE(init->snapuserd_client()->WaitForDeviceDelete(name + "-user-cow-init"));
2371     }
2372 
2373     // Initiate the merge and wait for it to be completed.
2374     ASSERT_TRUE(init->InitiateMerge());
2375     ASSERT_EQ(UpdateState::MergeCompleted, init->ProcessUpdateState());
2376 
2377     // Check that the target partitions have the same content after the merge.
2378     for (const auto& name : {"sys_b", "vnd_b", "prd_b", "dlkm_b"}) {
2379         ASSERT_TRUE(IsPartitionUnchanged(name))
2380                 << "Content of " << name << " changes after the merge";
2381     }
2382 }
2383 
2384 class AutoKill final {
2385   public:
AutoKill(pid_t pid)2386     explicit AutoKill(pid_t pid) : pid_(pid) {}
~AutoKill()2387     ~AutoKill() {
2388         if (pid_ > 0) kill(pid_, SIGKILL);
2389     }
2390 
valid() const2391     bool valid() const { return pid_ > 0; }
2392 
2393   private:
2394     pid_t pid_;
2395 };
2396 
TEST_F(SnapshotUpdateTest,DaemonTransition)2397 TEST_F(SnapshotUpdateTest, DaemonTransition) {
2398     if (!snapuserd_required_) {
2399         GTEST_SKIP() << "Skipping snapuserd test";
2400     }
2401 
2402     // Ensure a connection to the second-stage daemon, but use the first-stage
2403     // code paths thereafter.
2404     ASSERT_TRUE(sm->EnsureSnapuserdConnected());
2405     sm->set_use_first_stage_snapuserd(true);
2406 
2407     AddOperationForPartitions();
2408     // Execute the update.
2409     ASSERT_TRUE(sm->BeginUpdate());
2410     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
2411     ASSERT_TRUE(MapUpdateSnapshots());
2412     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
2413     ASSERT_TRUE(UnmapAll());
2414 
2415     auto init = NewManagerForFirstStageMount("_b");
2416     ASSERT_NE(init, nullptr);
2417 
2418     ASSERT_TRUE(init->EnsureSnapuserdConnected());
2419     init->set_use_first_stage_snapuserd(true);
2420 
2421     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
2422     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
2423 
2424     bool userspace_snapshots = init->UpdateUsesUserSnapshots();
2425 
2426     if (userspace_snapshots) {
2427         ASSERT_EQ(access("/dev/dm-user/sys_b-init", F_OK), 0);
2428         ASSERT_EQ(access("/dev/dm-user/sys_b", F_OK), -1);
2429     } else {
2430         ASSERT_EQ(access("/dev/dm-user/sys_b-user-cow-init", F_OK), 0);
2431         ASSERT_EQ(access("/dev/dm-user/sys_b-user-cow", F_OK), -1);
2432     }
2433 
2434     ASSERT_TRUE(init->PerformInitTransition(SnapshotManager::InitTransition::SECOND_STAGE));
2435 
2436     // :TODO: this is a workaround to ensure the handler list stays empty. We
2437     // should make this test more like actual init, and spawn two copies of
2438     // snapuserd, given how many other tests we now have for normal snapuserd.
2439     if (userspace_snapshots) {
2440         ASSERT_TRUE(init->snapuserd_client()->WaitForDeviceDelete("sys_b-init"));
2441         ASSERT_TRUE(init->snapuserd_client()->WaitForDeviceDelete("vnd_b-init"));
2442         ASSERT_TRUE(init->snapuserd_client()->WaitForDeviceDelete("prd_b-init"));
2443 
2444         // The control device should have been renamed.
2445         ASSERT_TRUE(android::fs_mgr::WaitForFileDeleted("/dev/dm-user/sys_b-init", 10s));
2446         ASSERT_EQ(access("/dev/dm-user/sys_b", F_OK), 0);
2447     } else {
2448         ASSERT_TRUE(init->snapuserd_client()->WaitForDeviceDelete("sys_b-user-cow-init"));
2449         ASSERT_TRUE(init->snapuserd_client()->WaitForDeviceDelete("vnd_b-user-cow-init"));
2450         ASSERT_TRUE(init->snapuserd_client()->WaitForDeviceDelete("prd_b-user-cow-init"));
2451 
2452         // The control device should have been renamed.
2453         ASSERT_TRUE(android::fs_mgr::WaitForFileDeleted("/dev/dm-user/sys_b-user-cow-init", 10s));
2454         ASSERT_EQ(access("/dev/dm-user/sys_b-user-cow", F_OK), 0);
2455     }
2456 }
2457 
TEST_F(SnapshotUpdateTest,MapAllSnapshots)2458 TEST_F(SnapshotUpdateTest, MapAllSnapshots) {
2459     AddOperationForPartitions();
2460     // Execute the update.
2461     ASSERT_TRUE(sm->BeginUpdate());
2462     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
2463     ASSERT_TRUE(WriteSnapshots());
2464     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
2465     ASSERT_TRUE(sm->MapAllSnapshots(10s));
2466 
2467     // Read bytes back and verify they match the cache.
2468     ASSERT_TRUE(IsPartitionUnchanged("sys_b"));
2469 
2470     ASSERT_TRUE(sm->UnmapAllSnapshots());
2471 }
2472 
TEST_F(SnapshotUpdateTest,CancelOnTargetSlot)2473 TEST_F(SnapshotUpdateTest, CancelOnTargetSlot) {
2474     AddOperationForPartitions();
2475 
2476     ASSERT_TRUE(UnmapAll());
2477 
2478     // Execute the update from B->A.
2479     test_device->set_slot_suffix("_b");
2480     ASSERT_TRUE(sm->BeginUpdate());
2481     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
2482 
2483     std::string path;
2484     ASSERT_TRUE(CreateLogicalPartition(
2485             CreateLogicalPartitionParams{
2486                     .block_device = fake_super,
2487                     .metadata_slot = 0,
2488                     .partition_name = "sys_a",
2489                     .timeout_ms = 1s,
2490                     .partition_opener = opener_.get(),
2491             },
2492             &path));
2493 
2494     bool userspace_snapshots = sm->UpdateUsesUserSnapshots();
2495 
2496     unique_fd fd;
2497     if (!userspace_snapshots) {
2498         // Hold sys_a open so it can't be unmapped.
2499         fd.reset(open(path.c_str(), O_RDONLY));
2500     }
2501 
2502     // Switch back to "A", make sure we can cancel. Instead of unmapping sys_a
2503     // we should simply delete the old snapshots.
2504     test_device->set_slot_suffix("_a");
2505     ASSERT_TRUE(sm->BeginUpdate());
2506 }
2507 
TEST_F(SnapshotUpdateTest,QueryStatusError)2508 TEST_F(SnapshotUpdateTest, QueryStatusError) {
2509     // Grow all partitions. Set |prd| large enough that |sys| and |vnd|'s COWs
2510     // fit in super, but not |prd|.
2511     constexpr uint64_t partition_size = 3788_KiB;
2512     SetSize(sys_, partition_size);
2513 
2514     AddOperationForPartitions();
2515 
2516     // Execute the update.
2517     ASSERT_TRUE(sm->BeginUpdate());
2518     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
2519 
2520     if (sm->UpdateUsesUserSnapshots()) {
2521         GTEST_SKIP() << "Test does not apply to userspace snapshots";
2522     }
2523 
2524     ASSERT_TRUE(WriteSnapshots());
2525     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
2526 
2527     ASSERT_TRUE(UnmapAll());
2528 
2529     class DmStatusFailure final : public DeviceMapperWrapper {
2530       public:
2531         bool GetTableStatus(const std::string& name, std::vector<TargetInfo>* table) override {
2532             if (!DeviceMapperWrapper::GetTableStatus(name, table)) {
2533                 return false;
2534             }
2535             if (name == "sys_b" && !table->empty()) {
2536                 auto& info = table->at(0);
2537                 if (DeviceMapper::GetTargetType(info.spec) == "snapshot-merge") {
2538                     info.data = "Merge failed";
2539                 }
2540             }
2541             return true;
2542         }
2543     };
2544     DmStatusFailure wrapper;
2545 
2546     // After reboot, init does first stage mount.
2547     auto info = new TestDeviceInfo(fake_super, "_b");
2548     info->set_dm(&wrapper);
2549 
2550     auto init = NewManagerForFirstStageMount(info);
2551     ASSERT_NE(init, nullptr);
2552 
2553     ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
2554     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
2555 
2556     // Initiate the merge and wait for it to be completed.
2557     ASSERT_TRUE(init->InitiateMerge());
2558     ASSERT_EQ(UpdateState::MergeFailed, init->ProcessUpdateState());
2559 
2560     // Simulate a reboot that tries the merge again, with the non-failing dm.
2561     ASSERT_TRUE(UnmapAll());
2562     init = NewManagerForFirstStageMount("_b");
2563     ASSERT_NE(init, nullptr);
2564     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
2565     ASSERT_EQ(UpdateState::MergeCompleted, init->ProcessUpdateState());
2566 }
2567 
2568 class FlashAfterUpdateTest : public SnapshotUpdateTest,
2569                              public WithParamInterface<std::tuple<uint32_t, bool>> {
2570   public:
InitiateMerge(const std::string & slot_suffix)2571     AssertionResult InitiateMerge(const std::string& slot_suffix) {
2572         auto sm = SnapshotManager::New(new TestDeviceInfo(fake_super, slot_suffix));
2573         if (!sm->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_)) {
2574             return AssertionFailure() << "Cannot CreateLogicalAndSnapshotPartitions";
2575         }
2576         if (!sm->InitiateMerge()) {
2577             return AssertionFailure() << "Cannot initiate merge";
2578         }
2579         return AssertionSuccess();
2580     }
2581 };
2582 
TEST_P(FlashAfterUpdateTest,FlashSlotAfterUpdate)2583 TEST_P(FlashAfterUpdateTest, FlashSlotAfterUpdate) {
2584     // Execute the update.
2585     ASSERT_TRUE(sm->BeginUpdate());
2586     ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
2587     ASSERT_TRUE(MapUpdateSnapshots());
2588     ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
2589 
2590     // Simulate shutting down the device.
2591     ASSERT_TRUE(UnmapAll());
2592 
2593     bool after_merge = std::get<1>(GetParam());
2594     if (after_merge) {
2595         ASSERT_TRUE(InitiateMerge("_b"));
2596         // Simulate shutting down the device after merge has initiated.
2597         ASSERT_TRUE(UnmapAll());
2598     }
2599 
2600     auto flashed_slot = std::get<0>(GetParam());
2601     auto flashed_slot_suffix = SlotSuffixForSlotNumber(flashed_slot);
2602 
2603     // Simulate flashing |flashed_slot|. This clears the UPDATED flag.
2604     auto flashed_builder = MetadataBuilder::New(*opener_, "super", flashed_slot);
2605     ASSERT_NE(flashed_builder, nullptr);
2606     flashed_builder->RemoveGroupAndPartitions(group_->name() + flashed_slot_suffix);
2607     flashed_builder->RemoveGroupAndPartitions(kCowGroupName);
2608     ASSERT_TRUE(FillFakeMetadata(flashed_builder.get(), manifest_, flashed_slot_suffix));
2609 
2610     // Deliberately remove a partition from this build so that
2611     // InitiateMerge do not switch state to "merging". This is possible in
2612     // practice because the list of dynamic partitions may change.
2613     ASSERT_NE(nullptr, flashed_builder->FindPartition("prd" + flashed_slot_suffix));
2614     flashed_builder->RemovePartition("prd" + flashed_slot_suffix);
2615 
2616     // Note that fastbootd always updates the partition table of both slots.
2617     auto flashed_metadata = flashed_builder->Export();
2618     ASSERT_NE(nullptr, flashed_metadata);
2619     ASSERT_TRUE(UpdatePartitionTable(*opener_, "super", *flashed_metadata, 0));
2620     ASSERT_TRUE(UpdatePartitionTable(*opener_, "super", *flashed_metadata, 1));
2621 
2622     std::string path;
2623     for (const auto& name : {"sys", "vnd"}) {
2624         ASSERT_TRUE(CreateLogicalPartition(
2625                 CreateLogicalPartitionParams{
2626                         .block_device = fake_super,
2627                         .metadata_slot = flashed_slot,
2628                         .partition_name = name + flashed_slot_suffix,
2629                         .timeout_ms = 1s,
2630                         .partition_opener = opener_.get(),
2631                 },
2632                 &path));
2633         ASSERT_TRUE(WriteRandomData(path));
2634         auto hash = GetHash(path);
2635         ASSERT_TRUE(hash.has_value());
2636         hashes_[name + flashed_slot_suffix] = *hash;
2637     }
2638 
2639     // Simulate shutting down the device after flash.
2640     ASSERT_TRUE(UnmapAll());
2641 
2642     // Simulate reboot. After reboot, init does first stage mount.
2643     auto init = NewManagerForFirstStageMount(flashed_slot_suffix);
2644     ASSERT_NE(init, nullptr);
2645 
2646     if (flashed_slot && after_merge) {
2647         ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
2648     }
2649     ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
2650 
2651     // Check that the target partitions have the same content.
2652     for (const auto& name : {"sys", "vnd"}) {
2653         ASSERT_TRUE(IsPartitionUnchanged(name + flashed_slot_suffix));
2654     }
2655 
2656     // There should be no snapshot to merge.
2657     auto new_sm = SnapshotManager::New(new TestDeviceInfo(fake_super, flashed_slot_suffix));
2658     if (flashed_slot == 0 && after_merge) {
2659         ASSERT_EQ(UpdateState::MergeCompleted, new_sm->ProcessUpdateState());
2660     } else {
2661         // update_engine calls ProcessUpdateState first -- should see Cancelled.
2662         ASSERT_EQ(UpdateState::Cancelled, new_sm->ProcessUpdateState());
2663     }
2664 
2665     // Next OTA calls CancelUpdate no matter what.
2666     ASSERT_TRUE(new_sm->CancelUpdate());
2667 }
2668 
2669 INSTANTIATE_TEST_SUITE_P(Snapshot, FlashAfterUpdateTest, Combine(Values(0, 1), Bool()),
__anon2cbfbe5c0702(const TestParamInfo<FlashAfterUpdateTest::ParamType>& info) 2670                          [](const TestParamInfo<FlashAfterUpdateTest::ParamType>& info) {
2671                              return "Flash"s + (std::get<0>(info.param) ? "New"s : "Old"s) +
2672                                     "Slot"s + (std::get<1>(info.param) ? "After"s : "Before"s) +
2673                                     "Merge"s;
2674                          });
2675 
Mkdir(const std::string & path)2676 bool Mkdir(const std::string& path) {
2677     if (mkdir(path.c_str(), 0700) && errno != EEXIST) {
2678         std::cerr << "Could not mkdir " << path << ": " << strerror(errno) << std::endl;
2679         return false;
2680     }
2681     return true;
2682 }
2683 
2684 class SnapshotTestEnvironment : public ::testing::Environment {
2685   public:
~SnapshotTestEnvironment()2686     ~SnapshotTestEnvironment() override {}
2687     void SetUp() override;
2688     void TearDown() override;
2689 
2690   private:
2691     bool CreateFakeSuper();
2692 
2693     std::unique_ptr<IImageManager> super_images_;
2694 };
2695 
CreateFakeSuper()2696 bool SnapshotTestEnvironment::CreateFakeSuper() {
2697     // Create and map the fake super partition.
2698     static constexpr int kImageFlags =
2699             IImageManager::CREATE_IMAGE_DEFAULT | IImageManager::CREATE_IMAGE_ZERO_FILL;
2700     if (!super_images_->CreateBackingImage("fake-super", kSuperSize, kImageFlags)) {
2701         LOG(ERROR) << "Could not create fake super partition";
2702         return false;
2703     }
2704     if (!super_images_->MapImageDevice("fake-super", 10s, &fake_super)) {
2705         LOG(ERROR) << "Could not map fake super partition";
2706         return false;
2707     }
2708     test_device->set_fake_super(fake_super);
2709     return true;
2710 }
2711 
SetUp()2712 void SnapshotTestEnvironment::SetUp() {
2713     // b/163082876: GTEST_SKIP in Environment will make atest report incorrect results. Until
2714     // that is fixed, don't call GTEST_SKIP here, but instead call GTEST_SKIP in individual test
2715     // suites.
2716     RETURN_IF_NON_VIRTUAL_AB_MSG("Virtual A/B is not enabled, skipping global setup.\n");
2717 
2718     std::vector<std::string> paths = {
2719             // clang-format off
2720             "/data/gsi/ota/test",
2721             "/data/gsi/ota/test/super",
2722             "/metadata/gsi/ota/test",
2723             "/metadata/gsi/ota/test/super",
2724             "/metadata/ota/test",
2725             "/metadata/ota/test/snapshots",
2726             // clang-format on
2727     };
2728     for (const auto& path : paths) {
2729         ASSERT_TRUE(Mkdir(path));
2730     }
2731 
2732     // Create this once, otherwise, gsid will start/stop between each test.
2733     test_device = new TestDeviceInfo();
2734     sm = SnapshotManager::New(test_device);
2735     ASSERT_NE(nullptr, sm) << "Could not create snapshot manager";
2736 
2737     // Use a separate image manager for our fake super partition.
2738     super_images_ = IImageManager::Open("ota/test/super", 10s);
2739     ASSERT_NE(nullptr, super_images_) << "Could not create image manager";
2740 
2741     // Map the old image if one exists so we can safely unmap everything that
2742     // depends on it.
2743     bool recreate_fake_super;
2744     if (super_images_->BackingImageExists("fake-super")) {
2745         if (super_images_->IsImageMapped("fake-super")) {
2746             ASSERT_TRUE(super_images_->GetMappedImageDevice("fake-super", &fake_super));
2747         } else {
2748             ASSERT_TRUE(super_images_->MapImageDevice("fake-super", 10s, &fake_super));
2749         }
2750         test_device->set_fake_super(fake_super);
2751         recreate_fake_super = true;
2752     } else {
2753         ASSERT_TRUE(CreateFakeSuper());
2754         recreate_fake_super = false;
2755     }
2756 
2757     // Clean up previous run.
2758     MetadataMountedTest().TearDown();
2759     SnapshotUpdateTest().Cleanup();
2760     SnapshotTest().Cleanup();
2761 
2762     if (recreate_fake_super) {
2763         // Clean up any old copy.
2764         DeleteBackingImage(super_images_.get(), "fake-super");
2765         ASSERT_TRUE(CreateFakeSuper());
2766     }
2767 }
2768 
TearDown()2769 void SnapshotTestEnvironment::TearDown() {
2770     RETURN_IF_NON_VIRTUAL_AB();
2771     if (super_images_ != nullptr) {
2772         DeleteBackingImage(super_images_.get(), "fake-super");
2773     }
2774 }
2775 
KillSnapuserd()2776 void KillSnapuserd() {
2777     auto status = android::base::GetProperty("init.svc.snapuserd", "stopped");
2778     if (status == "stopped") {
2779         return;
2780     }
2781     auto snapuserd_client = SnapuserdClient::Connect(kSnapuserdSocket, 5s);
2782     if (!snapuserd_client) {
2783         return;
2784     }
2785     snapuserd_client->DetachSnapuserd();
2786 }
2787 
2788 }  // namespace snapshot
2789 }  // namespace android
2790 
main(int argc,char ** argv)2791 int main(int argc, char** argv) {
2792     ::testing::InitGoogleTest(&argc, argv);
2793     ::testing::AddGlobalTestEnvironment(new ::android::snapshot::SnapshotTestEnvironment());
2794     gflags::ParseCommandLineFlags(&argc, &argv, false);
2795 
2796     android::base::SetProperty("ctl.stop", "snapuserd");
2797 
2798     std::unordered_set<std::string> modes = {"", "vab-legacy", "vabc-legacy"};
2799     if (modes.count(FLAGS_force_mode) == 0) {
2800         std::cerr << "Unexpected force_config argument\n";
2801         return 1;
2802     }
2803 
2804     // This is necessary if the configuration we're testing doesn't match the device.
2805     android::snapshot::KillSnapuserd();
2806 
2807     int ret = RUN_ALL_TESTS();
2808 
2809     android::base::SetProperty("snapuserd.test.dm.snapshots", "0");
2810     android::base::SetProperty("snapuserd.test.io_uring.force_disable", "0");
2811 
2812     android::snapshot::KillSnapuserd();
2813     return ret;
2814 }
2815