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 19 #include <chrono> 20 #include <map> 21 #include <memory> 22 #include <optional> 23 #include <ostream> 24 #include <string> 25 #include <string_view> 26 #include <vector> 27 28 #include <android-base/unique_fd.h> 29 #include <android/snapshot/snapshot.pb.h> 30 #include <fs_mgr_dm_linear.h> 31 #include <libdm/dm.h> 32 #include <libfiemap/image_manager.h> 33 #include <liblp/builder.h> 34 #include <liblp/liblp.h> 35 #include <update_engine/update_metadata.pb.h> 36 37 #include <libsnapshot/auto_device.h> 38 #include <libsnapshot/return.h> 39 40 #ifndef FRIEND_TEST 41 #define FRIEND_TEST(test_set_name, individual_test) \ 42 friend class test_set_name##_##individual_test##_Test 43 #define DEFINED_FRIEND_TEST 44 #endif 45 46 namespace android { 47 48 namespace fiemap { 49 class IImageManager; 50 } // namespace fiemap 51 52 namespace fs_mgr { 53 struct CreateLogicalPartitionParams; 54 class IPartitionOpener; 55 } // namespace fs_mgr 56 57 // Forward declare IBootControl types since we cannot include only the headers 58 // with Soong. Note: keep the enum width in sync. 59 namespace hardware { 60 namespace boot { 61 namespace V1_1 { 62 enum class MergeStatus : int32_t; 63 } // namespace V1_1 64 } // namespace boot 65 } // namespace hardware 66 67 namespace snapshot { 68 69 struct AutoDeleteCowImage; 70 struct AutoDeleteSnapshot; 71 struct AutoDeviceList; 72 struct PartitionCowCreator; 73 class SnapshotStatus; 74 75 static constexpr const std::string_view kCowGroupName = "cow"; 76 77 bool OptimizeSourceCopyOperation(const chromeos_update_engine::InstallOperation& operation, 78 chromeos_update_engine::InstallOperation* optimized); 79 80 enum class CreateResult : unsigned int { 81 ERROR, 82 CREATED, 83 NOT_CREATED, 84 }; 85 86 class SnapshotManager final { 87 using CreateLogicalPartitionParams = android::fs_mgr::CreateLogicalPartitionParams; 88 using IPartitionOpener = android::fs_mgr::IPartitionOpener; 89 using LpMetadata = android::fs_mgr::LpMetadata; 90 using MetadataBuilder = android::fs_mgr::MetadataBuilder; 91 using DeltaArchiveManifest = chromeos_update_engine::DeltaArchiveManifest; 92 using MergeStatus = android::hardware::boot::V1_1::MergeStatus; 93 using FiemapStatus = android::fiemap::FiemapStatus; 94 95 friend class SnapshotMergeStats; 96 97 public: 98 // Dependency injection for testing. 99 class IDeviceInfo { 100 public: ~IDeviceInfo()101 virtual ~IDeviceInfo() {} 102 virtual std::string GetGsidDir() const = 0; 103 virtual std::string GetMetadataDir() const = 0; 104 virtual std::string GetSlotSuffix() const = 0; 105 virtual std::string GetOtherSlotSuffix() const = 0; 106 virtual std::string GetSuperDevice(uint32_t slot) const = 0; 107 virtual const IPartitionOpener& GetPartitionOpener() const = 0; 108 virtual bool IsOverlayfsSetup() const = 0; 109 virtual bool SetBootControlMergeStatus(MergeStatus status) = 0; 110 virtual bool SetSlotAsUnbootable(unsigned int slot) = 0; 111 virtual bool IsRecovery() const = 0; 112 }; 113 114 ~SnapshotManager(); 115 116 // Return a new SnapshotManager instance, or null on error. The device 117 // pointer is owned for the lifetime of SnapshotManager. If null, a default 118 // instance will be created. 119 static std::unique_ptr<SnapshotManager> New(IDeviceInfo* device = nullptr); 120 121 // This is similar to New(), except designed specifically for first-stage 122 // init or recovery. 123 static std::unique_ptr<SnapshotManager> NewForFirstStageMount(IDeviceInfo* device = nullptr); 124 125 // Helper function for first-stage init to check whether a SnapshotManager 126 // might be needed to perform first-stage mounts. 127 static bool IsSnapshotManagerNeeded(); 128 129 // Helper function for second stage init to restorecon on the rollback indicator. 130 static std::string GetGlobalRollbackIndicatorPath(); 131 132 // Begin an update. This must be called before creating any snapshots. It 133 // will fail if GetUpdateState() != None. 134 bool BeginUpdate(); 135 136 // Cancel an update; any snapshots will be deleted. This is allowed if the 137 // state == Initiated, None, or Unverified (before rebooting to the new 138 // slot). 139 bool CancelUpdate(); 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 bool FinishedSnapshotWrites(bool wipe); 148 149 // Initiate a merge on all snapshot devices. This should only be used after an 150 // update has been marked successful after booting. 151 bool InitiateMerge(uint64_t* cow_file_size = nullptr); 152 153 // Perform any necessary post-boot actions. This should be run soon after 154 // /data is mounted. 155 // 156 // If a merge is in progress, this function will block until the merge is 157 // completed. 158 // - Callback is called periodically during the merge. If callback() 159 // returns false during the merge, ProcessUpdateState() will pause 160 // and returns Merging. 161 // If a merge or update was cancelled, this will clean up any 162 // update artifacts and return. 163 // 164 // Note that after calling this, GetUpdateState() may still return that a 165 // merge is in progress: 166 // MergeFailed indicates that a fatal error occurred. WaitForMerge() may 167 // called any number of times again to attempt to make more progress, but 168 // we do not expect it to succeed if a catastrophic error occurred. 169 // 170 // MergeNeedsReboot indicates that the merge has completed, but cleanup 171 // failed. This can happen if for some reason resources were not closed 172 // properly. In this case another reboot is needed before we can take 173 // another OTA. However, WaitForMerge() can be called again without 174 // rebooting, to attempt to finish cleanup anyway. 175 // 176 // MergeCompleted indicates that the update has fully completed. 177 // GetUpdateState will return None, and a new update can begin. 178 // 179 // The optional callback allows the caller to periodically check the 180 // progress with GetUpdateState(). 181 UpdateState ProcessUpdateState(const std::function<bool()>& callback = {}, 182 const std::function<bool()>& before_cancel = {}); 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 UpdateState GetUpdateState(double* progress = nullptr); 191 192 // Create necessary COW device / files for OTA clients. New logical partitions will be added to 193 // group "cow" in target_metadata. Regions of partitions of current_metadata will be 194 // "write-protected" and snapshotted. 195 Return CreateUpdateSnapshots(const DeltaArchiveManifest& manifest); 196 197 // Map a snapshotted partition for OTA clients to write to. Write-protected regions are 198 // determined previously in CreateSnapshots. 199 bool MapUpdateSnapshot(const CreateLogicalPartitionParams& params, std::string* snapshot_path); 200 201 // Unmap a snapshot device that's previously mapped with MapUpdateSnapshot. 202 bool UnmapUpdateSnapshot(const std::string& target_partition_name); 203 204 // If this returns true, first-stage mount must call 205 // CreateLogicalAndSnapshotPartitions rather than CreateLogicalPartitions. 206 bool NeedSnapshotsInFirstStageMount(); 207 208 // Perform first-stage mapping of snapshot targets. This replaces init's 209 // call to CreateLogicalPartitions when snapshots are present. 210 bool CreateLogicalAndSnapshotPartitions(const std::string& super_device, 211 const std::chrono::milliseconds& timeout_ms = {}); 212 213 // This method should be called preceding any wipe or flash of metadata or 214 // userdata. It is only valid in recovery or fastbootd, and it ensures that 215 // a merge has been completed. 216 // 217 // When userdata will be wiped or flashed, it is necessary to clean up any 218 // snapshot state. If a merge is in progress, the merge must be finished. 219 // If a snapshot is present but not yet merged, the slot must be marked as 220 // unbootable. 221 // 222 // Returns true on success (or nothing to do), false on failure. The 223 // optional callback fires periodically to query progress via GetUpdateState. 224 bool HandleImminentDataWipe(const std::function<void()>& callback = {}); 225 226 // Force a merge to complete in recovery. This is similar to HandleImminentDataWipe 227 // but does not expect a data wipe after. 228 bool FinishMergeInRecovery(); 229 230 // This method is only allowed in recovery and is used as a helper to 231 // initialize the snapshot devices as a requirement to mount a snapshotted 232 // /system in recovery. 233 // This function returns: 234 // - CreateResult::CREATED if snapshot devices were successfully created; 235 // - CreateResult::NOT_CREATED if it was not necessary to create snapshot 236 // devices; 237 // - CreateResult::ERROR if a fatal error occurred, mounting /system should 238 // be aborted. 239 // This function mounts /metadata when called, and unmounts /metadata upon 240 // return. 241 CreateResult RecoveryCreateSnapshotDevices(); 242 243 // Same as RecoveryCreateSnapshotDevices(), but does not auto mount/umount 244 // /metadata. 245 CreateResult RecoveryCreateSnapshotDevices(const std::unique_ptr<AutoDevice>& metadata_device); 246 247 // Dump debug information. 248 bool Dump(std::ostream& os); 249 250 // Ensure metadata directory is mounted in recovery. When the returned 251 // AutoDevice is destroyed, the metadata directory is automatically 252 // unmounted. 253 // Return nullptr if any failure. 254 // In Android mode, Return an AutoDevice that does nothing 255 // In recovery, return an AutoDevice that does nothing if metadata entry 256 // is not found in fstab. 257 // Note: if this function is called the second time before the AutoDevice returned from the 258 // first call is destroyed, the device will be unmounted when any of these AutoDevices is 259 // destroyed. For example: 260 // auto a = mgr->EnsureMetadataMounted(); // mounts 261 // auto b = mgr->EnsureMetadataMounted(); // does nothing 262 // b.reset() // unmounts 263 // a.reset() // does nothing 264 std::unique_ptr<AutoDevice> EnsureMetadataMounted(); 265 266 private: 267 FRIEND_TEST(SnapshotTest, CleanFirstStageMount); 268 FRIEND_TEST(SnapshotTest, CreateSnapshot); 269 FRIEND_TEST(SnapshotTest, FirstStageMountAfterRollback); 270 FRIEND_TEST(SnapshotTest, FirstStageMountAndMerge); 271 FRIEND_TEST(SnapshotTest, FlashSuperDuringMerge); 272 FRIEND_TEST(SnapshotTest, FlashSuperDuringUpdate); 273 FRIEND_TEST(SnapshotTest, MapPartialSnapshot); 274 FRIEND_TEST(SnapshotTest, MapSnapshot); 275 FRIEND_TEST(SnapshotTest, Merge); 276 FRIEND_TEST(SnapshotTest, NoMergeBeforeReboot); 277 FRIEND_TEST(SnapshotTest, UpdateBootControlHal); 278 FRIEND_TEST(SnapshotUpdateTest, DataWipeAfterRollback); 279 FRIEND_TEST(SnapshotUpdateTest, DataWipeRollbackInRecovery); 280 FRIEND_TEST(SnapshotUpdateTest, FullUpdateFlow); 281 FRIEND_TEST(SnapshotUpdateTest, MergeCannotRemoveCow); 282 FRIEND_TEST(SnapshotUpdateTest, MergeInRecovery); 283 FRIEND_TEST(SnapshotUpdateTest, SnapshotStatusFileWithoutCow); 284 friend class SnapshotTest; 285 friend class SnapshotUpdateTest; 286 friend class FlashAfterUpdateTest; 287 friend class LockTestConsumer; 288 friend struct AutoDeleteCowImage; 289 friend struct AutoDeleteSnapshot; 290 friend struct PartitionCowCreator; 291 292 using DmTargetSnapshot = android::dm::DmTargetSnapshot; 293 using IImageManager = android::fiemap::IImageManager; 294 using TargetInfo = android::dm::DeviceMapper::TargetInfo; 295 296 explicit SnapshotManager(IDeviceInfo* info); 297 298 // This is created lazily since it can connect via binder. 299 bool EnsureImageManager(); 300 301 // Helper for first-stage init. 302 bool ForceLocalImageManager(); 303 304 // Helper function for tests. image_manager()305 IImageManager* image_manager() const { return images_.get(); } 306 307 // Since libsnapshot is included into multiple processes, we flock() our 308 // files for simple synchronization. LockedFile is a helper to assist with 309 // this. It also serves as a proof-of-lock for some functions. 310 class LockedFile final { 311 public: LockedFile(const std::string & path,android::base::unique_fd && fd,int lock_mode)312 LockedFile(const std::string& path, android::base::unique_fd&& fd, int lock_mode) 313 : path_(path), fd_(std::move(fd)), lock_mode_(lock_mode) {} 314 ~LockedFile(); lock_mode()315 int lock_mode() const { return lock_mode_; } 316 317 private: 318 std::string path_; 319 android::base::unique_fd fd_; 320 int lock_mode_; 321 }; 322 static std::unique_ptr<LockedFile> OpenFile(const std::string& file, int lock_flags); 323 324 // Create a new snapshot record. This creates the backing COW store and 325 // persists information needed to map the device. The device can be mapped 326 // with MapSnapshot(). 327 // 328 // |status|.device_size should be the size of the base_device that will be passed 329 // via MapDevice(). |status|.snapshot_size should be the number of bytes in the 330 // base device, starting from 0, that will be snapshotted. |status|.cow_file_size 331 // should be the amount of space that will be allocated to store snapshot 332 // deltas. 333 // 334 // If |status|.snapshot_size < |status|.device_size, then the device will always 335 // be mapped with two table entries: a dm-snapshot range covering 336 // snapshot_size, and a dm-linear range covering the remainder. 337 // 338 // All sizes are specified in bytes, and the device, snapshot, COW partition and COW file sizes 339 // must be a multiple of the sector size (512 bytes). 340 bool CreateSnapshot(LockedFile* lock, SnapshotStatus* status); 341 342 // |name| should be the base partition name (e.g. "system_a"). Create the 343 // backing COW image using the size previously passed to CreateSnapshot(). 344 Return CreateCowImage(LockedFile* lock, const std::string& name); 345 346 // Map a snapshot device that was previously created with CreateSnapshot. 347 // If a merge was previously initiated, the device-mapper table will have a 348 // snapshot-merge target instead of a snapshot target. If the timeout 349 // parameter greater than zero, this function will wait the given amount 350 // of time for |dev_path| to become available, and fail otherwise. If 351 // timeout_ms is 0, then no wait will occur and |dev_path| may not yet 352 // exist on return. 353 bool MapSnapshot(LockedFile* lock, const std::string& name, const std::string& base_device, 354 const std::string& cow_device, const std::chrono::milliseconds& timeout_ms, 355 std::string* dev_path); 356 357 // Map a COW image that was previous created with CreateCowImage. 358 std::optional<std::string> MapCowImage(const std::string& name, 359 const std::chrono::milliseconds& timeout_ms); 360 361 // Remove the backing copy-on-write image and snapshot states for the named snapshot. The 362 // caller is responsible for ensuring that the snapshot is unmapped. 363 bool DeleteSnapshot(LockedFile* lock, const std::string& name); 364 365 // Unmap a snapshot device previously mapped with MapSnapshotDevice(). 366 bool UnmapSnapshot(LockedFile* lock, const std::string& name); 367 368 // Unmap a COW image device previously mapped with MapCowImage(). 369 bool UnmapCowImage(const std::string& name); 370 371 // Unmap and remove all known snapshots. 372 bool RemoveAllSnapshots(LockedFile* lock); 373 374 // List the known snapshot names. 375 bool ListSnapshots(LockedFile* lock, std::vector<std::string>* snapshots); 376 377 // Check for a cancelled or rolled back merge, returning true if such a 378 // condition was detected and handled. 379 bool HandleCancelledUpdate(LockedFile* lock, const std::function<bool()>& before_cancel); 380 381 // Helper for HandleCancelledUpdate. Assumes booting from new slot. 382 bool AreAllSnapshotsCancelled(LockedFile* lock); 383 384 // Determine whether partition names in |snapshots| have been flashed and 385 // store result to |out|. 386 // Return true if values are successfully retrieved and false on error 387 // (e.g. super partition metadata cannot be read). When it returns true, 388 // |out| stores true for partitions that have been flashed and false for 389 // partitions that have not been flashed. 390 bool GetSnapshotFlashingStatus(LockedFile* lock, const std::vector<std::string>& snapshots, 391 std::map<std::string, bool>* out); 392 393 // Remove artifacts created by the update process, such as snapshots, and 394 // set the update state to None. 395 bool RemoveAllUpdateState(LockedFile* lock, const std::function<bool()>& prolog = {}); 396 397 // Interact with /metadata/ota. 398 std::unique_ptr<LockedFile> OpenLock(int lock_flags); 399 std::unique_ptr<LockedFile> LockShared(); 400 std::unique_ptr<LockedFile> LockExclusive(); 401 std::string GetLockPath() const; 402 403 // Interact with /metadata/ota/state. 404 UpdateState ReadUpdateState(LockedFile* file); 405 SnapshotUpdateStatus ReadSnapshotUpdateStatus(LockedFile* file); 406 bool WriteUpdateState(LockedFile* file, UpdateState state); 407 bool WriteSnapshotUpdateStatus(LockedFile* file, const SnapshotUpdateStatus& status); 408 std::string GetStateFilePath() const; 409 410 // Interact with /metadata/ota/merge_state. 411 // This file contains information related to the snapshot merge process. 412 std::string GetMergeStateFilePath() const; 413 414 // Helpers for merging. 415 bool SwitchSnapshotToMerge(LockedFile* lock, const std::string& name); 416 bool RewriteSnapshotDeviceTable(const std::string& dm_name); 417 bool MarkSnapshotMergeCompleted(LockedFile* snapshot_lock, const std::string& snapshot_name); 418 void AcknowledgeMergeSuccess(LockedFile* lock); 419 void AcknowledgeMergeFailure(); 420 std::unique_ptr<LpMetadata> ReadCurrentMetadata(); 421 422 enum class MetadataPartitionState { 423 // Partition does not exist. 424 None, 425 // Partition is flashed. 426 Flashed, 427 // Partition is created by OTA client. 428 Updated, 429 }; 430 // Helper function to check the state of a partition as described in metadata. 431 MetadataPartitionState GetMetadataPartitionState(const LpMetadata& metadata, 432 const std::string& name); 433 434 // Note that these require the name of the device containing the snapshot, 435 // which may be the "inner" device. Use GetsnapshotDeviecName(). 436 bool QuerySnapshotStatus(const std::string& dm_name, std::string* target_type, 437 DmTargetSnapshot::Status* status); 438 bool IsSnapshotDevice(const std::string& dm_name, TargetInfo* target = nullptr); 439 440 // Internal callback for when merging is complete. 441 bool OnSnapshotMergeComplete(LockedFile* lock, const std::string& name, 442 const SnapshotStatus& status); 443 bool CollapseSnapshotDevice(const std::string& name, const SnapshotStatus& status); 444 445 // Only the following UpdateStates are used here: 446 // UpdateState::Merging 447 // UpdateState::MergeCompleted 448 // UpdateState::MergeFailed 449 // UpdateState::MergeNeedsReboot 450 UpdateState CheckMergeState(const std::function<bool()>& before_cancel); 451 UpdateState CheckMergeState(LockedFile* lock, const std::function<bool()>& before_cancel); 452 UpdateState CheckTargetMergeState(LockedFile* lock, const std::string& name); 453 454 // Interact with status files under /metadata/ota/snapshots. 455 bool WriteSnapshotStatus(LockedFile* lock, const SnapshotStatus& status); 456 bool ReadSnapshotStatus(LockedFile* lock, const std::string& name, SnapshotStatus* status); 457 std::string GetSnapshotStatusFilePath(const std::string& name); 458 459 std::string GetSnapshotBootIndicatorPath(); 460 std::string GetRollbackIndicatorPath(); 461 std::string GetForwardMergeIndicatorPath(); 462 463 // Return the name of the device holding the "snapshot" or "snapshot-merge" 464 // target. This may not be the final device presented via MapSnapshot(), if 465 // for example there is a linear segment. 466 std::string GetSnapshotDeviceName(const std::string& snapshot_name, 467 const SnapshotStatus& status); 468 469 // Map the base device, COW devices, and snapshot device. 470 bool MapPartitionWithSnapshot(LockedFile* lock, CreateLogicalPartitionParams params, 471 std::string* path); 472 473 // Map the COW devices, including the partition in super and the images. 474 // |params|: 475 // - |partition_name| should be the name of the top-level partition (e.g. system_b), 476 // not system_b-cow-img 477 // - |device_name| and |partition| is ignored 478 // - |timeout_ms| and the rest is respected 479 // Return the path in |cow_device_path| (e.g. /dev/block/dm-1) and major:minor in 480 // |cow_device_string| 481 bool MapCowDevices(LockedFile* lock, const CreateLogicalPartitionParams& params, 482 const SnapshotStatus& snapshot_status, AutoDeviceList* created_devices, 483 std::string* cow_name); 484 485 // The reverse of MapCowDevices. 486 bool UnmapCowDevices(LockedFile* lock, const std::string& name); 487 488 // The reverse of MapPartitionWithSnapshot. 489 bool UnmapPartitionWithSnapshot(LockedFile* lock, const std::string& target_partition_name); 490 491 // If there isn't a previous update, return true. |needs_merge| is set to false. 492 // If there is a previous update but the device has not boot into it, tries to cancel the 493 // update and delete any snapshots. Return true if successful. |needs_merge| is set to false. 494 // If there is a previous update and the device has boot into it, do nothing and return true. 495 // |needs_merge| is set to true. 496 bool TryCancelUpdate(bool* needs_merge); 497 498 // Helper for CreateUpdateSnapshots. 499 // Creates all underlying images, COW partitions and snapshot files. Does not initialize them. 500 Return CreateUpdateSnapshotsInternal( 501 LockedFile* lock, const DeltaArchiveManifest& manifest, 502 PartitionCowCreator* cow_creator, AutoDeviceList* created_devices, 503 std::map<std::string, SnapshotStatus>* all_snapshot_status); 504 505 // Initialize snapshots so that they can be mapped later. 506 // Map the COW partition and zero-initialize the header. 507 Return InitializeUpdateSnapshots( 508 LockedFile* lock, MetadataBuilder* target_metadata, 509 const LpMetadata* exported_target_metadata, const std::string& target_suffix, 510 const std::map<std::string, SnapshotStatus>& all_snapshot_status); 511 512 // Unmap all partitions that were mapped by CreateLogicalAndSnapshotPartitions. 513 // This should only be called in recovery. 514 bool UnmapAllPartitions(); 515 516 // Sanity check no snapshot overflows. Note that this returns false negatives if the snapshot 517 // overflows, then is remapped and not written afterwards. Hence, the function may only serve 518 // as a sanity check. 519 bool EnsureNoOverflowSnapshot(LockedFile* lock); 520 521 enum class Slot { Unknown, Source, Target }; 522 friend std::ostream& operator<<(std::ostream& os, SnapshotManager::Slot slot); 523 Slot GetCurrentSlot(); 524 525 std::string ReadUpdateSourceSlotSuffix(); 526 527 // Helper for RemoveAllSnapshots. 528 // Check whether |name| should be deleted as a snapshot name. 529 bool ShouldDeleteSnapshot(LockedFile* lock, const std::map<std::string, bool>& flashing_status, 530 Slot current_slot, const std::string& name); 531 532 // Create or delete forward merge indicator given |wipe|. Iff wipe is scheduled, 533 // allow forward merge on FDR. 534 bool UpdateForwardMergeIndicator(bool wipe); 535 536 // Helper for HandleImminentDataWipe. 537 // Call ProcessUpdateState and handle states with special rules before data wipe. Specifically, 538 // if |allow_forward_merge| and allow-forward-merge indicator exists, initiate merge if 539 // necessary. 540 bool ProcessUpdateStateOnDataWipe(bool allow_forward_merge, 541 const std::function<bool()>& callback); 542 543 // Return device string of a mapped image, or if it is not available, the mapped image path. 544 bool GetMappedImageDeviceStringOrPath(const std::string& device_name, 545 std::string* device_string_or_mapped_path); 546 547 std::string gsid_dir_; 548 std::string metadata_dir_; 549 std::unique_ptr<IDeviceInfo> device_; 550 std::unique_ptr<IImageManager> images_; 551 bool has_local_image_manager_ = false; 552 bool in_factory_data_reset_ = false; 553 }; 554 555 } // namespace snapshot 556 } // namespace android 557 558 #ifdef DEFINED_FRIEND_TEST 559 #undef DEFINED_FRIEND_TEST 560 #undef FRIEND_TEST 561 #endif 562