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