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