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