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