• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2019 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 #pragma once
16 
17 #include <stdint.h>
18 #include <unistd.h>
19 
20 #include <chrono>
21 #include <map>
22 #include <memory>
23 #include <optional>
24 #include <ostream>
25 #include <string>
26 #include <string_view>
27 #include <vector>
28 
29 #include <android-base/unique_fd.h>
30 #include <android/snapshot/snapshot.pb.h>
31 #include <fs_mgr_dm_linear.h>
32 #include <libdm/dm.h>
33 #include <libfiemap/image_manager.h>
34 #include <liblp/builder.h>
35 #include <liblp/liblp.h>
36 #include <libsnapshot/auto_device.h>
37 #include <libsnapshot/cow_writer.h>
38 #include <libsnapshot/return.h>
39 #include <snapuserd/snapuserd_client.h>
40 #include <update_engine/update_metadata.pb.h>
41 
42 #ifndef FRIEND_TEST
43 #define FRIEND_TEST(test_set_name, individual_test) \
44     friend class test_set_name##_##individual_test##_Test
45 #define DEFINED_FRIEND_TEST
46 #endif
47 
48 namespace aidl::android::hardware::boot {
49 enum class MergeStatus;
50 }
51 
52 namespace android {
53 
54 namespace fiemap {
55 class IImageManager;
56 }  // namespace fiemap
57 
58 namespace fs_mgr {
59 struct CreateLogicalPartitionParams;
60 class IPartitionOpener;
61 }  // namespace fs_mgr
62 
63 // Forward declare IBootControl types since we cannot include only the headers
64 // with Soong. Note: keep the enum width in sync.
65 
66 namespace snapshot {
67 
68 struct AutoDeleteCowImage;
69 struct AutoDeleteSnapshot;
70 struct AutoDeviceList;
71 struct PartitionCowCreator;
72 class ISnapshotMergeStats;
73 class SnapshotMergeStats;
74 class SnapshotStatus;
75 
76 using std::chrono::duration_cast;
77 using namespace std::chrono_literals;
78 
79 static constexpr const std::string_view kCowGroupName = "cow";
80 static constexpr char kVirtualAbCompressionProp[] = "ro.virtual_ab.compression.enabled";
81 
82 bool OptimizeSourceCopyOperation(const chromeos_update_engine::InstallOperation& operation,
83                                  chromeos_update_engine::InstallOperation* optimized);
84 
85 enum class CreateResult : unsigned int {
86     ERROR,
87     CREATED,
88     NOT_CREATED,
89 };
90 
91 enum class CancelResult : unsigned int {
92     OK,
93     ERROR,
94     LIVE_SNAPSHOTS,
95     NEEDS_MERGE,
96 };
97 
98 class ISnapshotManager {
99   public:
100     // Dependency injection for testing.
101     class IDeviceInfo {
102       public:
103         using IImageManager = android::fiemap::IImageManager;
104         using MergeStatus = aidl::android::hardware::boot::MergeStatus;
105 
~IDeviceInfo()106         virtual ~IDeviceInfo() {}
107         virtual std::string GetMetadataDir() const = 0;
108         virtual std::string GetSlotSuffix() const = 0;
109         virtual std::string GetOtherSlotSuffix() const = 0;
110         virtual std::string GetSuperDevice(uint32_t slot) const = 0;
111         virtual const android::fs_mgr::IPartitionOpener& GetPartitionOpener() const = 0;
112         virtual bool IsOverlayfsSetup() const = 0;
113         virtual bool SetBootControlMergeStatus(MergeStatus status) = 0;
114         virtual bool SetActiveBootSlot(unsigned int slot) = 0;
115         virtual bool SetSlotAsUnbootable(unsigned int slot) = 0;
116         virtual bool IsRecovery() const = 0;
IsTestDevice()117         virtual bool IsTestDevice() const { return false; }
118         virtual bool IsFirstStageInit() const = 0;
119         virtual std::unique_ptr<IImageManager> OpenImageManager() const = 0;
120         virtual android::dm::IDeviceMapper& GetDeviceMapper() = 0;
121         virtual bool IsTempMetadata() const = 0;
122 
123         // Helper method for implementing OpenImageManager.
124         std::unique_ptr<IImageManager> OpenImageManager(const std::string& gsid_dir) const;
125     };
126     virtual ~ISnapshotManager() = default;
127 
128     // Begin an update. This must be called before creating any snapshots. It
129     // will fail if GetUpdateState() != None.
130     virtual bool BeginUpdate() = 0;
131 
132     // Cancel an update; any snapshots will be deleted. This is allowed if the
133     // state == Initiated, None, or Unverified (before rebooting to the new
134     // slot).
135     //
136     // In recovery, it will cancel an update even if a merge is in progress.
137     // Thus, it should only be called if a new OTA will be sideloaded. The
138     // safety can be checked via IsCancelUpdateSafe().
139     virtual bool CancelUpdate() = 0;
140 
141     // Mark snapshot writes as having completed. After this, new snapshots cannot
142     // be created, and the device must either cancel the OTA (either before
143     // rebooting or after rolling back), or merge the OTA.
144     // Before calling this function, all snapshots must be mapped.
145     // If |wipe| is set to true, wipe is scheduled after reboot, and snapshots
146     // may need to be merged before wiping.
147     virtual bool FinishedSnapshotWrites(bool wipe) = 0;
148 
149     // Set feature flags on an ISnapshotMergeStats object.
150     virtual void SetMergeStatsFeatures(ISnapshotMergeStats* stats) = 0;
151 
152     // Update an ISnapshotMergeStats object with statistics about COW usage.
153     // This should be called before the merge begins as otherwise snapshots
154     // may be deleted.
155     virtual void UpdateCowStats(ISnapshotMergeStats* stats) = 0;
156 
157     // Initiate a merge on all snapshot devices. This should only be used after an
158     // update has been marked successful after booting.
159     virtual bool InitiateMerge() = 0;
160 
161     // Perform any necessary post-boot actions. This should be run soon after
162     // /data is mounted.
163     //
164     // If a merge is in progress, this function will block until the merge is
165     // completed.
166     //    - Callback is called periodically during the merge. If callback()
167     //      returns false during the merge, ProcessUpdateState() will pause
168     //      and returns Merging.
169     // If a merge or update was cancelled, this will clean up any
170     // update artifacts and return.
171     //
172     // Note that after calling this, GetUpdateState() may still return that a
173     // merge is in progress:
174     //   MergeFailed indicates that a fatal error occurred. WaitForMerge() may
175     //   called any number of times again to attempt to make more progress, but
176     //   we do not expect it to succeed if a catastrophic error occurred.
177     //
178     //   MergeNeedsReboot indicates that the merge has completed, but cleanup
179     //   failed. This can happen if for some reason resources were not closed
180     //   properly. In this case another reboot is needed before we can take
181     //   another OTA. However, WaitForMerge() can be called again without
182     //   rebooting, to attempt to finish cleanup anyway.
183     //
184     //   MergeCompleted indicates that the update has fully completed.
185     //   GetUpdateState will return None, and a new update can begin.
186     //
187     // The optional callback allows the caller to periodically check the
188     // progress with GetUpdateState().
189     virtual UpdateState ProcessUpdateState(const std::function<bool()>& callback = {},
190                                            const std::function<bool()>& before_cancel = {}) = 0;
191 
192     // If ProcessUpdateState() returned MergeFailed, this returns the appropriate
193     // code. Otherwise, MergeFailureCode::Ok is returned.
194     virtual MergeFailureCode ReadMergeFailureCode() = 0;
195 
196     // If an update is in progress, return the source build fingerprint.
197     virtual std::string ReadSourceBuildFingerprint() = 0;
198 
199     // Find the status of the current update, if any.
200     //
201     // |progress| depends on the returned status:
202     //   Merging: Value in the range [0, 100]
203     //   MergeCompleted: 100
204     //   Other: 0
205     virtual UpdateState GetUpdateState(double* progress = nullptr) = 0;
206 
207     // Returns true if compression is enabled for the current update. This always returns false if
208     // UpdateState is None, or no snapshots have been created.
209     virtual bool UpdateUsesCompression() = 0;
210 
211     // Returns true if userspace snapshots is enabled for the current update.
212     virtual bool UpdateUsesUserSnapshots() = 0;
213 
214     // Create necessary COW device / files for OTA clients. New logical partitions will be added to
215     // group "cow" in target_metadata. Regions of partitions of current_metadata will be
216     // "write-protected" and snapshotted.
217     virtual Return CreateUpdateSnapshots(
218             const chromeos_update_engine::DeltaArchiveManifest& manifest) = 0;
219 
220     // Map a snapshotted partition for OTA clients to write to. Write-protected regions are
221     // determined previously in CreateSnapshots.
222     //
223     // |snapshot_path| must not be nullptr.
224     //
225     // This method will return false if ro.virtual_ab.compression.enabled is true.
226     virtual bool MapUpdateSnapshot(const android::fs_mgr::CreateLogicalPartitionParams& params,
227                                    std::string* snapshot_path) = 0;
228 
229     // Create an ICowWriter to build a snapshot against a target partition. The partition name
230     // must be suffixed. If a source partition exists, it must be specified as well. The source
231     // partition will only be used if raw bytes are needed. The source partition should be an
232     // absolute path to the device, not a partition name.
233     virtual std::unique_ptr<ICowWriter> OpenSnapshotWriter(
234             const android::fs_mgr::CreateLogicalPartitionParams& params,
235             std::optional<uint64_t> label = {}) = 0;
236 
237     // Unmap a snapshot device or CowWriter that was previously opened with MapUpdateSnapshot,
238     // OpenSnapshotWriter. All outstanding open descriptors, writers, or
239     // readers must be deleted before this is called.
240     virtual bool UnmapUpdateSnapshot(const std::string& target_partition_name) = 0;
241 
242     // If this returns true, first-stage mount must call
243     // CreateLogicalAndSnapshotPartitions rather than CreateLogicalPartitions.
244     virtual bool NeedSnapshotsInFirstStageMount() = 0;
245 
246     // Perform first-stage mapping of snapshot targets. This replaces init's
247     // call to CreateLogicalPartitions when snapshots are present.
248     virtual bool CreateLogicalAndSnapshotPartitions(
249             const std::string& super_device, const std::chrono::milliseconds& timeout_ms = {}) = 0;
250 
251     // Map all snapshots. This is analogous to CreateLogicalAndSnapshotPartitions, except it maps
252     // the target slot rather than the current slot. It should only be used immediately after
253     // applying an update, before rebooting to the new slot.
254     virtual bool MapAllSnapshots(const std::chrono::milliseconds& timeout_ms = {}) = 0;
255 
256     // Unmap all snapshots. This should be called to undo MapAllSnapshots().
257     virtual bool UnmapAllSnapshots() = 0;
258 
259     // This method should be called preceding any wipe or flash of metadata or
260     // userdata. It is only valid in recovery or fastbootd, and it ensures that
261     // a merge has been completed.
262     //
263     // When userdata will be wiped or flashed, it is necessary to clean up any
264     // snapshot state. If a merge is in progress, the merge must be finished.
265     // If a snapshot is present but not yet merged, the slot must be marked as
266     // unbootable.
267     //
268     // Returns true on success (or nothing to do), false on failure. The
269     // optional callback fires periodically to query progress via GetUpdateState.
270     virtual bool HandleImminentDataWipe(const std::function<void()>& callback = {}) = 0;
271 
272     // Force a merge to complete in recovery. This is similar to HandleImminentDataWipe
273     // but does not expect a data wipe after.
274     virtual bool FinishMergeInRecovery() = 0;
275 
276     // This method is only allowed in recovery and is used as a helper to
277     // initialize the snapshot devices as a requirement to mount a snapshotted
278     // /system in recovery.
279     // This function returns:
280     // - CreateResult::CREATED if snapshot devices were successfully created;
281     // - CreateResult::NOT_CREATED if it was not necessary to create snapshot
282     // devices;
283     // - CreateResult::ERROR if a fatal error occurred, mounting /system should
284     // be aborted.
285     // This function mounts /metadata when called, and unmounts /metadata upon
286     // return.
287     virtual CreateResult RecoveryCreateSnapshotDevices() = 0;
288 
289     // Same as RecoveryCreateSnapshotDevices(), but does not auto mount/umount
290     // /metadata.
291     virtual CreateResult RecoveryCreateSnapshotDevices(
292             const std::unique_ptr<AutoDevice>& metadata_device) = 0;
293 
294     // Dump debug information.
295     virtual bool Dump(std::ostream& os) = 0;
296 
297     // Ensure metadata directory is mounted in recovery. When the returned
298     // AutoDevice is destroyed, the metadata directory is automatically
299     // unmounted.
300     // Return nullptr if any failure.
301     // In Android mode, Return an AutoDevice that does nothing
302     // In recovery, return an AutoDevice that does nothing if metadata entry
303     // is not found in fstab.
304     // Note: if this function is called the second time before the AutoDevice returned from the
305     // first call is destroyed, the device will be unmounted when any of these AutoDevices is
306     // destroyed. For example:
307     //   auto a = mgr->EnsureMetadataMounted(); // mounts
308     //   auto b = mgr->EnsureMetadataMounted(); // does nothing
309     //   b.reset() // unmounts
310     //   a.reset() // does nothing
311     virtual std::unique_ptr<AutoDevice> EnsureMetadataMounted() = 0;
312 
313     // Return the associated ISnapshotMergeStats instance. Never null.
314     virtual ISnapshotMergeStats* GetSnapshotMergeStatsInstance() = 0;
315 
316     // Return whether cancelling an update is safe. This is for use in recovery.
317     virtual bool IsCancelUpdateSafe() = 0;
318 };
319 
320 class SnapshotManager final : public ISnapshotManager {
321     using CreateLogicalPartitionParams = android::fs_mgr::CreateLogicalPartitionParams;
322     using IPartitionOpener = android::fs_mgr::IPartitionOpener;
323     using LpMetadata = android::fs_mgr::LpMetadata;
324     using MetadataBuilder = android::fs_mgr::MetadataBuilder;
325     using DeltaArchiveManifest = chromeos_update_engine::DeltaArchiveManifest;
326     using MergeStatus = aidl::android::hardware::boot::MergeStatus;
327     using FiemapStatus = android::fiemap::FiemapStatus;
328 
329     friend class SnapshotMergeStats;
330 
331   public:
332     ~SnapshotManager();
333 
334     // Return a new SnapshotManager instance, or null on error. The device
335     // pointer is owned for the lifetime of SnapshotManager. If null, a default
336     // instance will be created.
337     static std::unique_ptr<SnapshotManager> New(IDeviceInfo* device = nullptr);
338 
339     // This is similar to New(), except designed specifically for first-stage
340     // init or recovery.
341     static std::unique_ptr<SnapshotManager> NewForFirstStageMount(IDeviceInfo* device = nullptr);
342 
343     // Helper function for first-stage init to check whether a SnapshotManager
344     // might be needed to perform first-stage mounts.
345     static bool IsSnapshotManagerNeeded();
346 
347     // Map the temp OTA metadata partition from super
348     static bool MapTempOtaMetadataPartitionIfNeeded(
349             const std::function<bool(const std::string&)>& init);
350 
351     // Helper function for second stage init to restorecon on the rollback indicator.
352     static std::string GetGlobalRollbackIndicatorPath();
353 
354     // Populate |snapuserd_argv| with the necessary arguments to restart snapuserd
355     // after loading selinux policy.
356     bool PrepareSnapuserdArgsForSelinux(std::vector<std::string>* snapuserd_argv);
357 
358     // If snapuserd from first stage init was started from system partition.
359     bool MarkSnapuserdFromSystem();
360 
361     // Detach dm-user devices from the first stage snapuserd. Load
362     // new dm-user tables after loading selinux policy.
363     bool DetachFirstStageSnapuserdForSelinux();
364 
365     // Perform the transition from the selinux stage of snapuserd into the
366     // second-stage of snapuserd. This process involves re-creating the dm-user
367     // table entries for each device, so that they connect to the new daemon.
368     // Once all new tables have been activated, we ask the first-stage daemon
369     // to cleanly exit.
370     bool PerformSecondStageInitTransition();
371 
372     // ISnapshotManager overrides.
373     bool BeginUpdate() override;
374     bool CancelUpdate() override;
375     bool FinishedSnapshotWrites(bool wipe) override;
376     void UpdateCowStats(ISnapshotMergeStats* stats) override;
377     MergeFailureCode ReadMergeFailureCode() override;
378     bool InitiateMerge() override;
379     UpdateState ProcessUpdateState(const std::function<bool()>& callback = {},
380                                    const std::function<bool()>& before_cancel = {}) override;
381     UpdateState GetUpdateState(double* progress = nullptr) override;
382     bool UpdateUsesCompression() override;
383     bool UpdateUsesUserSnapshots() override;
384     Return CreateUpdateSnapshots(const DeltaArchiveManifest& manifest) override;
385     bool MapUpdateSnapshot(const CreateLogicalPartitionParams& params,
386                            std::string* snapshot_path) override;
387     std::unique_ptr<ICowWriter> OpenSnapshotWriter(
388             const android::fs_mgr::CreateLogicalPartitionParams& params,
389             std::optional<uint64_t> label) override;
390     bool UnmapUpdateSnapshot(const std::string& target_partition_name) override;
391     bool NeedSnapshotsInFirstStageMount() override;
392     bool CreateLogicalAndSnapshotPartitions(
393             const std::string& super_device,
394             const std::chrono::milliseconds& timeout_ms = {}) override;
395     bool HandleImminentDataWipe(const std::function<void()>& callback = {}) override;
396     bool FinishMergeInRecovery() override;
397     CreateResult RecoveryCreateSnapshotDevices() override;
398     CreateResult RecoveryCreateSnapshotDevices(
399             const std::unique_ptr<AutoDevice>& metadata_device) override;
400     bool Dump(std::ostream& os) override;
401     std::unique_ptr<AutoDevice> EnsureMetadataMounted() override;
402     ISnapshotMergeStats* GetSnapshotMergeStatsInstance() override;
403     bool MapAllSnapshots(const std::chrono::milliseconds& timeout_ms = {}) override;
404     bool UnmapAllSnapshots() override;
405     std::string ReadSourceBuildFingerprint() override;
406     void SetMergeStatsFeatures(ISnapshotMergeStats* stats) override;
407     bool IsCancelUpdateSafe() override;
408 
409     // We can't use WaitForFile during first-stage init, because ueventd is not
410     // running and therefore will not automatically create symlinks. Instead,
411     // we let init provide us with the correct function to use to ensure
412     // uevents have been processed and symlink/mknod calls completed.
SetUeventRegenCallback(std::function<bool (const std::string &)> callback)413     void SetUeventRegenCallback(std::function<bool(const std::string&)> callback) {
414         uevent_regen_callback_ = callback;
415     }
416 
417     // If true, compression is enabled for this update. This is used by
418     // first-stage to decide whether to launch snapuserd.
419     bool IsSnapuserdRequired();
420 
421     // This is primarily invoked during device reboot after an OTA update.
422     //
423     // a: Check if the partitions are mounted off snapshots.
424     //
425     // b: Store all dynamic partitions which are mounted off snapshots. This
426     // is used to unmount the partition.
427     bool IsUserspaceSnapshotUpdateInProgress(std::vector<std::string>& dynamic_partitions);
428 
429     // Pause the snapshot merge.
430     bool PauseSnapshotMerge();
431 
432     // Resume the snapshot merge.
433     bool ResumeSnapshotMerge();
434 
435     enum class SnapshotDriver {
436         DM_SNAPSHOT,
437         DM_USER,
438     };
439 
440     // Add new public entries above this line.
441 
442   private:
443     FRIEND_TEST(SnapshotTest, CleanFirstStageMount);
444     FRIEND_TEST(SnapshotTest, CreateSnapshot);
445     FRIEND_TEST(SnapshotTest, FirstStageMountAfterRollback);
446     FRIEND_TEST(SnapshotTest, FirstStageMountAndMerge);
447     FRIEND_TEST(SnapshotTest, FlagCheck);
448     FRIEND_TEST(SnapshotTest, FlashSuperDuringMerge);
449     FRIEND_TEST(SnapshotTest, FlashSuperDuringUpdate);
450     FRIEND_TEST(SnapshotTest, MapPartialSnapshot);
451     FRIEND_TEST(SnapshotTest, MapSnapshot);
452     FRIEND_TEST(SnapshotTest, Merge);
453     FRIEND_TEST(SnapshotTest, MergeFailureCode);
454     FRIEND_TEST(SnapshotTest, NoMergeBeforeReboot);
455     FRIEND_TEST(SnapshotTest, UpdateBootControlHal);
456     FRIEND_TEST(SnapshotTest, BootSnapshotWithoutSlotSwitch);
457     FRIEND_TEST(SnapshotUpdateTest, AddPartition);
458     FRIEND_TEST(SnapshotUpdateTest, ConsistencyCheckResume);
459     FRIEND_TEST(SnapshotUpdateTest, DaemonTransition);
460     FRIEND_TEST(SnapshotUpdateTest, DataWipeAfterRollback);
461     FRIEND_TEST(SnapshotUpdateTest, DataWipeRollbackInRecovery);
462     FRIEND_TEST(SnapshotUpdateTest, DataWipeWithStaleSnapshots);
463     FRIEND_TEST(SnapshotUpdateTest, FlagCheck);
464     FRIEND_TEST(SnapshotUpdateTest, FullUpdateFlow);
465     FRIEND_TEST(SnapshotUpdateTest, MergeCannotRemoveCow);
466     FRIEND_TEST(SnapshotUpdateTest, MergeInRecovery);
467     FRIEND_TEST(SnapshotUpdateTest, QueryStatusError);
468     FRIEND_TEST(SnapshotUpdateTest, SnapshotStatusFileWithoutCow);
469     FRIEND_TEST(SnapshotUpdateTest, SpaceSwapUpdate);
470     FRIEND_TEST(SnapshotUpdateTest, InterruptMergeDuringPhaseUpdate);
471     FRIEND_TEST(SnapshotUpdateTest, MapAllSnapshotsWithoutSlotSwitch);
472     FRIEND_TEST(SnapshotUpdateTest, CancelInRecovery);
473     friend class SnapshotTest;
474     friend class SnapshotUpdateTest;
475     friend class FlashAfterUpdateTest;
476     friend class LockTestConsumer;
477     friend class SnapshotFuzzEnv;
478     friend class MapSnapshots;
479     friend struct AutoDeleteCowImage;
480     friend struct AutoDeleteSnapshot;
481     friend struct PartitionCowCreator;
482 
483     using DmTargetSnapshot = android::dm::DmTargetSnapshot;
484     using IImageManager = android::fiemap::IImageManager;
485     using TargetInfo = android::dm::DeviceMapper::TargetInfo;
486 
487     explicit SnapshotManager(IDeviceInfo* info);
488 
489     // This is created lazily since it can connect via binder.
490     bool EnsureImageManager();
491 
492     // Ensure we're connected to snapuserd.
493     bool EnsureSnapuserdConnected(std::chrono::milliseconds timeout_ms = 10s);
494 
495     // Helpers for first-stage init.
device()496     const std::unique_ptr<IDeviceInfo>& device() const { return device_; }
497 
498     // Helper functions for tests.
image_manager()499     IImageManager* image_manager() const { return images_.get(); }
set_use_first_stage_snapuserd(bool value)500     void set_use_first_stage_snapuserd(bool value) { use_first_stage_snapuserd_ = value; }
501 
502     // Since libsnapshot is included into multiple processes, we flock() our
503     // files for simple synchronization. LockedFile is a helper to assist with
504     // this. It also serves as a proof-of-lock for some functions.
505     class LockedFile final {
506       public:
LockedFile(const std::string & path,android::base::unique_fd && fd,int lock_mode)507         LockedFile(const std::string& path, android::base::unique_fd&& fd, int lock_mode)
508             : path_(path), fd_(std::move(fd)), lock_mode_(lock_mode) {}
509         ~LockedFile();
lock_mode()510         int lock_mode() const { return lock_mode_; }
511 
512       private:
513         std::string path_;
514         android::base::unique_fd fd_;
515         int lock_mode_;
516     };
517     static std::unique_ptr<LockedFile> OpenFile(const std::string& file, int lock_flags);
518 
519     SnapshotDriver GetSnapshotDriver(LockedFile* lock);
520 
521     // Create a new snapshot record. This creates the backing COW store and
522     // persists information needed to map the device. The device can be mapped
523     // with MapSnapshot().
524     //
525     // |status|.device_size should be the size of the base_device that will be passed
526     // via MapDevice(). |status|.snapshot_size should be the number of bytes in the
527     // base device, starting from 0, that will be snapshotted. |status|.cow_file_size
528     // should be the amount of space that will be allocated to store snapshot
529     // deltas.
530     //
531     // If |status|.snapshot_size < |status|.device_size, then the device will always
532     // be mapped with two table entries: a dm-snapshot range covering
533     // snapshot_size, and a dm-linear range covering the remainder.
534     //
535     // All sizes are specified in bytes, and the device, snapshot, COW partition and COW file sizes
536     // must be a multiple of the sector size (512 bytes).
537     bool CreateSnapshot(LockedFile* lock, PartitionCowCreator* cow_creator, SnapshotStatus* status);
538 
539     // |name| should be the base partition name (e.g. "system_a"). Create the
540     // backing COW image using the size previously passed to CreateSnapshot().
541     Return CreateCowImage(LockedFile* lock, const std::string& name);
542 
543     // Map a snapshot device that was previously created with CreateSnapshot.
544     // If a merge was previously initiated, the device-mapper table will have a
545     // snapshot-merge target instead of a snapshot target. If the timeout
546     // parameter greater than zero, this function will wait the given amount
547     // of time for |dev_path| to become available, and fail otherwise. If
548     // timeout_ms is 0, then no wait will occur and |dev_path| may not yet
549     // exist on return.
550     bool MapSnapshot(LockedFile* lock, const std::string& name, const std::string& base_device,
551                      const std::string& cow_device, const std::chrono::milliseconds& timeout_ms,
552                      std::string* dev_path);
553 
554     // Create a dm-user device for a given snapshot.
555     bool MapDmUserCow(LockedFile* lock, const std::string& name, const std::string& cow_file,
556                       const std::string& base_device, const std::string& base_path_merge,
557                       const std::chrono::milliseconds& timeout_ms, std::string* path);
558 
559     // Map the source device used for dm-user.
560     bool MapSourceDevice(LockedFile* lock, const std::string& name,
561                          const std::chrono::milliseconds& timeout_ms, std::string* path);
562 
563     // Map a COW image that was previous created with CreateCowImage.
564     std::optional<std::string> MapCowImage(const std::string& name,
565                                            const std::chrono::milliseconds& timeout_ms);
566 
567     // Remove the backing copy-on-write image and snapshot states for the named snapshot. The
568     // caller is responsible for ensuring that the snapshot is unmapped.
569     bool DeleteSnapshot(LockedFile* lock, const std::string& name);
570 
571     // Unmap a snapshot device previously mapped with MapSnapshotDevice().
572     bool UnmapSnapshot(LockedFile* lock, const std::string& name);
573 
574     // Unmap a COW image device previously mapped with MapCowImage().
575     bool UnmapCowImage(const std::string& name);
576 
577     // Unmap a COW and remove it from a MetadataBuilder.
578     void UnmapAndDeleteCowPartition(MetadataBuilder* current_metadata);
579 
580     // Remove invalid snapshots if any
581     void RemoveInvalidSnapshots(LockedFile* lock);
582 
583     // Unmap and remove all known snapshots.
584     bool RemoveAllSnapshots(LockedFile* lock);
585 
586     // Boot device off snapshots without slot switch
587     bool BootFromSnapshotsWithoutSlotSwitch();
588 
589     // Remove kBootSnapshotsWithoutSlotSwitch so that device can boot
590     // without snapshots on the current slot
591     bool PrepareDeviceToBootWithoutSnapshot();
592 
593     // Is the kBootSnapshotsWithoutSlotSwitch present
594     bool IsSnapshotWithoutSlotSwitch();
595 
596     // List the known snapshot names.
597     bool ListSnapshots(LockedFile* lock, std::vector<std::string>* snapshots,
598                        const std::string& suffix = "");
599 
600     // Check for a cancelled or rolled back merge, returning true if such a
601     // condition was detected and handled.
602     bool HandleCancelledUpdate(LockedFile* lock, const std::function<bool()>& before_cancel);
603 
604     // Helper for HandleCancelledUpdate. Assumes booting from new slot.
605     bool AreAllSnapshotsCancelled(LockedFile* lock);
606 
607     // Determine whether partition names in |snapshots| have been flashed and
608     // store result to |out|.
609     // Return true if values are successfully retrieved and false on error
610     // (e.g. super partition metadata cannot be read). When it returns true,
611     // |out| stores true for partitions that have been flashed and false for
612     // partitions that have not been flashed.
613     bool GetSnapshotFlashingStatus(LockedFile* lock, const std::vector<std::string>& snapshots,
614                                    std::map<std::string, bool>* out);
615 
616     // Remove artifacts created by the update process, such as snapshots, and
617     // set the update state to None.
618     bool RemoveAllUpdateState(LockedFile* lock, const std::function<bool()>& prolog = {});
619 
620     // Interact with /metadata/ota.
621     std::unique_ptr<LockedFile> OpenLock(int lock_flags);
622     std::unique_ptr<LockedFile> LockShared();
623     std::unique_ptr<LockedFile> LockExclusive();
624     std::string GetLockPath() const;
625 
626     // Interact with /metadata/ota/state.
627     UpdateState ReadUpdateState(LockedFile* file);
628     SnapshotUpdateStatus ReadSnapshotUpdateStatus(LockedFile* file);
629     bool WriteUpdateState(LockedFile* file, UpdateState state,
630                           MergeFailureCode failure_code = MergeFailureCode::Ok);
631     bool WriteSnapshotUpdateStatus(LockedFile* file, const SnapshotUpdateStatus& status);
632     std::string GetStateFilePath() const;
633 
634     // Interact with /metadata/ota/merge_state.
635     // This file contains information related to the snapshot merge process.
636     std::string GetMergeStateFilePath() const;
637 
638     // Helpers for merging.
639     MergeFailureCode MergeSecondPhaseSnapshots(LockedFile* lock);
640     MergeFailureCode SwitchSnapshotToMerge(LockedFile* lock, const std::string& name);
641     MergeFailureCode RewriteSnapshotDeviceTable(const std::string& dm_name);
642     bool MarkSnapshotMergeCompleted(LockedFile* snapshot_lock, const std::string& snapshot_name);
643     void AcknowledgeMergeSuccess(LockedFile* lock);
644     void AcknowledgeMergeFailure(MergeFailureCode failure_code);
645     MergePhase DecideMergePhase(const SnapshotStatus& status);
646     std::unique_ptr<LpMetadata> ReadCurrentMetadata();
647 
648     enum class MetadataPartitionState {
649         // Partition does not exist.
650         None,
651         // Partition is flashed.
652         Flashed,
653         // Partition is created by OTA client.
654         Updated,
655     };
656     // Helper function to check the state of a partition as described in metadata.
657     MetadataPartitionState GetMetadataPartitionState(const LpMetadata& metadata,
658                                                      const std::string& name);
659 
660     // Note that these require the name of the device containing the snapshot,
661     // which may be the "inner" device. Use GetsnapshotDeviecName().
662     bool QuerySnapshotStatus(const std::string& dm_name, std::string* target_type,
663                              DmTargetSnapshot::Status* status);
664     bool IsSnapshotDevice(const std::string& dm_name, TargetInfo* target = nullptr);
665 
666     // Internal callback for when merging is complete.
667     bool OnSnapshotMergeComplete(LockedFile* lock, const std::string& name,
668                                  const SnapshotStatus& status);
669     bool CollapseSnapshotDevice(LockedFile* lock, const std::string& name,
670                                 const SnapshotStatus& status);
671 
672     struct [[nodiscard]] MergeResult {
673         explicit MergeResult(UpdateState state,
674                              MergeFailureCode failure_code = MergeFailureCode::Ok)
stateMergeResult675             : state(state), failure_code(failure_code) {}
676         UpdateState state;
677         MergeFailureCode failure_code;
678     };
679 
680     // Only the following UpdateStates are used here:
681     //   UpdateState::Merging
682     //   UpdateState::MergeCompleted
683     //   UpdateState::MergeFailed
684     //   UpdateState::MergeNeedsReboot
685     MergeResult CheckMergeState(const std::function<bool()>& before_cancel);
686     MergeResult CheckMergeState(LockedFile* lock, const std::function<bool()>& before_cancel);
687     MergeResult CheckTargetMergeState(LockedFile* lock, const std::string& name,
688                                       const SnapshotUpdateStatus& update_status);
689 
690     auto UpdateStateToStr(enum UpdateState state);
691     // Get status or table information about a device-mapper node with a single target.
692     enum class TableQuery {
693         Table,
694         Status,
695     };
696     bool GetSingleTarget(const std::string& dm_name, TableQuery query,
697                          android::dm::DeviceMapper::TargetInfo* target);
698 
699     // Interact with status files under /metadata/ota/snapshots.
700     bool WriteSnapshotStatus(LockedFile* lock, const SnapshotStatus& status);
701     bool ReadSnapshotStatus(LockedFile* lock, const std::string& name, SnapshotStatus* status);
702     std::string GetSnapshotStatusFilePath(const std::string& name);
703 
704     std::string GetSnapshotBootIndicatorPath();
705     std::string GetRollbackIndicatorPath();
706     std::string GetForwardMergeIndicatorPath();
707     std::string GetOldPartitionMetadataPath();
708     std::string GetBootSnapshotsWithoutSlotSwitchPath();
709     std::string GetSnapuserdFromSystemPath();
710 
711     bool HasForwardMergeIndicator();
712 
713     const LpMetadata* ReadOldPartitionMetadata(LockedFile* lock);
714 
715     bool MapAllPartitions(LockedFile* lock, const std::string& super_device, uint32_t slot,
716                           const std::chrono::milliseconds& timeout_ms);
717 
718     // Reason for calling MapPartitionWithSnapshot.
719     enum class SnapshotContext {
720         // For writing or verification (during update_engine).
721         Update,
722 
723         // For mounting a full readable device.
724         Mount,
725     };
726 
727     struct SnapshotPaths {
728         // Target/base device (eg system_b), always present.
729         std::string target_device;
730 
731         // COW name (eg system_cow). Not present if no COW is needed.
732         std::string cow_device_name;
733 
734         // dm-snapshot instance. Not present in Update mode for VABC.
735         std::string snapshot_device;
736     };
737 
738     // Helpers for OpenSnapshotWriter.
739     std::unique_ptr<ICowWriter> OpenCompressedSnapshotWriter(LockedFile* lock,
740                                                              const SnapshotStatus& status,
741                                                              const SnapshotPaths& paths,
742                                                              std::optional<uint64_t> label);
743 
744     // Map the base device, COW devices, and snapshot device.
745     bool MapPartitionWithSnapshot(LockedFile* lock, CreateLogicalPartitionParams params,
746                                   SnapshotContext context, SnapshotPaths* paths);
747 
748     // Map the COW devices, including the partition in super and the images.
749     // |params|:
750     //    - |partition_name| should be the name of the top-level partition (e.g. system_b),
751     //            not system_b-cow-img
752     //    - |device_name| and |partition| is ignored
753     //    - |timeout_ms| and the rest is respected
754     // Return the path in |cow_device_path| (e.g. /dev/block/dm-1) and major:minor in
755     // |cow_device_string|
756     bool MapCowDevices(LockedFile* lock, const CreateLogicalPartitionParams& params,
757                        const SnapshotStatus& snapshot_status, AutoDeviceList* created_devices,
758                        std::string* cow_name);
759 
760     // The reverse of MapCowDevices.
761     bool UnmapCowDevices(LockedFile* lock, const std::string& name);
762 
763     // The reverse of MapPartitionWithSnapshot.
764     bool UnmapPartitionWithSnapshot(LockedFile* lock, const std::string& target_partition_name);
765 
766     // Unmap a dm-user device through snapuserd.
767     bool UnmapDmUserDevice(const std::string& dm_user_name);
768 
769     // Unmap a dm-user device for user space snapshots
770     bool UnmapUserspaceSnapshotDevice(LockedFile* lock, const std::string& snapshot_name);
771 
772     CancelResult TryCancelUpdate();
773     CancelResult IsCancelUpdateSafe(UpdateState state);
774 
775     // Helper for CreateUpdateSnapshots.
776     // Creates all underlying images, COW partitions and snapshot files. Does not initialize them.
777     Return CreateUpdateSnapshotsInternal(
778             LockedFile* lock, const DeltaArchiveManifest& manifest,
779             PartitionCowCreator* cow_creator, AutoDeviceList* created_devices,
780             std::map<std::string, SnapshotStatus>* all_snapshot_status);
781 
782     // Initialize snapshots so that they can be mapped later.
783     // Map the COW partition and zero-initialize the header.
784     Return InitializeUpdateSnapshots(
785             LockedFile* lock, uint32_t cow_version, MetadataBuilder* target_metadata,
786             const LpMetadata* exported_target_metadata, const std::string& target_suffix,
787             const std::map<std::string, SnapshotStatus>& all_snapshot_status);
788 
789     // Implementation of UnmapAllSnapshots(), with the lock provided.
790     bool UnmapAllSnapshots(LockedFile* lock);
791 
792     // Unmap all partitions that were mapped by CreateLogicalAndSnapshotPartitions.
793     // This should only be called in recovery.
794     bool UnmapAllPartitionsInRecovery();
795 
796     // Check no snapshot overflows. Note that this returns false negatives if the snapshot
797     // overflows, then is remapped and not written afterwards.
798     bool EnsureNoOverflowSnapshot(LockedFile* lock);
799 
800     enum class Slot { Unknown, Source, Target };
801     friend std::ostream& operator<<(std::ostream& os, SnapshotManager::Slot slot);
802     Slot GetCurrentSlot();
803 
804     // Return the suffix we expect snapshots to have.
805     std::string GetSnapshotSlotSuffix();
806 
807     std::string ReadUpdateSourceSlotSuffix();
808 
809     // Helper for RemoveAllSnapshots.
810     // Check whether |name| should be deleted as a snapshot name.
811     bool ShouldDeleteSnapshot(const std::map<std::string, bool>& flashing_status, Slot current_slot,
812                               const std::string& name);
813 
814     // Create or delete forward merge indicator given |wipe|. Iff wipe is scheduled,
815     // allow forward merge on FDR.
816     bool UpdateForwardMergeIndicator(bool wipe);
817 
818     // Helper for HandleImminentDataWipe.
819     // Call ProcessUpdateState and handle states with special rules before data wipe.
820     UpdateState ProcessUpdateStateOnDataWipe(const std::function<bool()>& callback);
821 
822     // Return device string of a mapped image, or if it is not available, the mapped image path.
823     bool GetMappedImageDeviceStringOrPath(const std::string& device_name,
824                                           std::string* device_string_or_mapped_path);
825 
826     // Same as above, but for paths only (no major:minor device strings).
827     bool GetMappedImageDevicePath(const std::string& device_name, std::string* device_path);
828 
829     // Wait for a device to be created by ueventd (eg, its symlink or node to be populated).
830     // This is needed for any code that uses device-mapper path in first-stage init. If
831     // |timeout_ms| is empty or the given device is not a path, WaitForDevice immediately
832     // returns true.
833     bool WaitForDevice(const std::string& device, std::chrono::milliseconds timeout_ms);
834 
835     enum class InitTransition { SELINUX_DETACH, SECOND_STAGE };
836 
837     // Initiate the transition from first-stage to second-stage snapuserd. This
838     // process involves re-creating the dm-user table entries for each device,
839     // so that they connect to the new daemon. Once all new tables have been
840     // activated, we ask the first-stage daemon to cleanly exit.
841     //
842     // If the mode is SELINUX_DETACH, snapuserd_argv must be non-null and will
843     // be populated with a list of snapuserd arguments to pass to execve(). It
844     // is otherwise ignored.
845     bool PerformInitTransition(InitTransition transition,
846                                std::vector<std::string>* snapuserd_argv = nullptr);
847 
snapuserd_client()848     SnapuserdClient* snapuserd_client() const { return snapuserd_client_.get(); }
849 
850     // Helper of UpdateUsesCompression
851     bool UpdateUsesCompression(LockedFile* lock);
852     // Locked and unlocked functions to test whether the current update uses
853     // userspace snapshots.
854     bool UpdateUsesUserSnapshots(LockedFile* lock);
855 
856     // Check if io_uring API's need to be used
857     bool UpdateUsesIouring(LockedFile* lock);
858 
859     // Check if direct reads are enabled for the source image
860     bool UpdateUsesODirect(LockedFile* lock);
861 
862     // Check if we skip the verification of the target image
863     bool UpdateUsesSkipVerification(LockedFile* lock);
864 
865     // Get value of maximum cow op merge size
866     uint32_t GetUpdateCowOpMergeSize(LockedFile* lock);
867 
868     // Get number of threads to perform post OTA boot verification
869     uint32_t GetUpdateWorkerCount(LockedFile* lock);
870 
871     // Get the verification block size
872     uint32_t GetVerificationBlockSize(LockedFile* lock);
873 
874     // Get the number of verification threads
875     uint32_t GetNumVerificationThreads(LockedFile* lock);
876 
877     // Wrapper around libdm, with diagnostics.
878     bool DeleteDeviceIfExists(const std::string& name,
879                               const std::chrono::milliseconds& timeout_ms = {});
880 
881     // Set read-ahead size during OTA
882     void SetReadAheadSize(const std::string& entry_block_device, off64_t size_kb);
883 
884     // Returns true post OTA reboot if legacy snapuserd is required
885     bool IsLegacySnapuserdPostReboot();
886 
887     android::dm::IDeviceMapper& dm_;
888     std::unique_ptr<IDeviceInfo> device_;
889     std::string metadata_dir_;
890     std::unique_ptr<IImageManager> images_;
891     bool use_first_stage_snapuserd_ = false;
892     std::function<bool(const std::string&)> uevent_regen_callback_;
893     std::unique_ptr<SnapuserdClient> snapuserd_client_;
894     std::unique_ptr<LpMetadata> old_partition_metadata_;
895     std::optional<bool> is_snapshot_userspace_;
896     std::optional<bool> is_legacy_snapuserd_;
897 };
898 
899 }  // namespace snapshot
900 }  // namespace android
901 
902 #ifdef DEFINED_FRIEND_TEST
903 #undef DEFINED_FRIEND_TEST
904 #undef FRIEND_TEST
905 #endif
906