Loading fs_mgr/libsnapshot/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ filegroup { "device_info.cpp", "snapshot.cpp", "snapshot_stats.cpp", "snapshot_stub.cpp", "snapshot_metadata_updater.cpp", "partition_cow_creator.cpp", "return.cpp", Loading fs_mgr/libsnapshot/include/libsnapshot/mock_device_info.h 0 → 100644 +37 −0 Original line number Diff line number Diff line // Copyright (C) 2020 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #include <libsnapshot/snapshot.h> #include <gmock/gmock.h> namespace android::snapshot { class MockDeviceInfo : public SnapshotManager::IDeviceInfo { public: MOCK_METHOD(std::string, GetGsidDir, (), (const, override)); MOCK_METHOD(std::string, GetMetadataDir, (), (const, override)); MOCK_METHOD(std::string, GetSlotSuffix, (), (const, override)); MOCK_METHOD(std::string, GetOtherSlotSuffix, (), (const, override)); MOCK_METHOD(std::string, GetSuperDevice, (uint32_t slot), (const, override)); MOCK_METHOD(const android::fs_mgr::IPartitionOpener&, GetPartitionOpener, (), (const)); MOCK_METHOD(bool, IsOverlayfsSetup, (), (const, override)); MOCK_METHOD(bool, SetBootControlMergeStatus, (MergeStatus status), (override)); MOCK_METHOD(bool, SetSlotAsUnbootable, (unsigned int slot), (override)); MOCK_METHOD(bool, IsRecovery, (), (const, override)); }; } // namespace android::snapshot fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h 0 → 100644 +54 −0 Original line number Diff line number Diff line // Copyright (C) 2020 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #include <libsnapshot/snapshot.h> #include <gmock/gmock.h> namespace android::snapshot { class MockSnapshotManager : public ISnapshotManager { public: MOCK_METHOD(bool, BeginUpdate, (), (override)); MOCK_METHOD(bool, CancelUpdate, (), (override)); MOCK_METHOD(bool, FinishedSnapshotWrites, (bool wipe), (override)); MOCK_METHOD(bool, InitiateMerge, (), (override)); MOCK_METHOD(UpdateState, ProcessUpdateState, (const std::function<bool()>& callback, const std::function<bool()>& before_cancel), (override)); MOCK_METHOD(UpdateState, GetUpdateState, (double* progress), (override)); MOCK_METHOD(Return, CreateUpdateSnapshots, (const chromeos_update_engine::DeltaArchiveManifest& manifest), (override)); MOCK_METHOD(bool, MapUpdateSnapshot, (const android::fs_mgr::CreateLogicalPartitionParams& params, std::string* snapshot_path), (override)); MOCK_METHOD(bool, UnmapUpdateSnapshot, (const std::string& target_partition_name), (override)); MOCK_METHOD(bool, NeedSnapshotsInFirstStageMount, (), (override)); MOCK_METHOD(bool, CreateLogicalAndSnapshotPartitions, (const std::string& super_device, const std::chrono::milliseconds& timeout_ms), (override)); MOCK_METHOD(bool, HandleImminentDataWipe, (const std::function<void()>& callback), (override)); MOCK_METHOD(CreateResult, RecoveryCreateSnapshotDevices, (), (override)); MOCK_METHOD(CreateResult, RecoveryCreateSnapshotDevices, (const std::unique_ptr<AutoDevice>& metadata_device), (override)); MOCK_METHOD(bool, Dump, (std::ostream & os), (override)); MOCK_METHOD(std::unique_ptr<AutoDevice>, EnsureMetadataMounted, (), (override)); MOCK_METHOD(ISnapshotMergeStats*, GetSnapshotMergeStatsInstance, (), (override)); }; } // namespace android::snapshot fs_mgr/libsnapshot/include/libsnapshot/snapshot.h +86 −49 Original line number Diff line number Diff line Loading @@ -70,6 +70,8 @@ struct AutoDeleteCowImage; struct AutoDeleteSnapshot; struct AutoDeviceList; struct PartitionCowCreator; class ISnapshotMergeStats; class SnapshotMergeStats; class SnapshotStatus; static constexpr const std::string_view kCowGroupName = "cow"; Loading @@ -83,17 +85,7 @@ enum class CreateResult : unsigned int { NOT_CREATED, }; class SnapshotManager final { using CreateLogicalPartitionParams = android::fs_mgr::CreateLogicalPartitionParams; using IPartitionOpener = android::fs_mgr::IPartitionOpener; using LpMetadata = android::fs_mgr::LpMetadata; using MetadataBuilder = android::fs_mgr::MetadataBuilder; using DeltaArchiveManifest = chromeos_update_engine::DeltaArchiveManifest; using MergeStatus = android::hardware::boot::V1_1::MergeStatus; using FiemapStatus = android::fiemap::FiemapStatus; friend class SnapshotMergeStats; class ISnapshotManager { public: // Dependency injection for testing. class IDeviceInfo { Loading @@ -104,39 +96,23 @@ class SnapshotManager final { virtual std::string GetSlotSuffix() const = 0; virtual std::string GetOtherSlotSuffix() const = 0; virtual std::string GetSuperDevice(uint32_t slot) const = 0; virtual const IPartitionOpener& GetPartitionOpener() const = 0; virtual const android::fs_mgr::IPartitionOpener& GetPartitionOpener() const = 0; virtual bool IsOverlayfsSetup() const = 0; virtual bool SetBootControlMergeStatus(MergeStatus status) = 0; virtual bool SetBootControlMergeStatus( android::hardware::boot::V1_1::MergeStatus status) = 0; virtual bool SetSlotAsUnbootable(unsigned int slot) = 0; virtual bool IsRecovery() const = 0; }; ~SnapshotManager(); // Return a new SnapshotManager instance, or null on error. The device // pointer is owned for the lifetime of SnapshotManager. If null, a default // instance will be created. static std::unique_ptr<SnapshotManager> New(IDeviceInfo* device = nullptr); // This is similar to New(), except designed specifically for first-stage // init or recovery. static std::unique_ptr<SnapshotManager> NewForFirstStageMount(IDeviceInfo* device = nullptr); // Helper function for first-stage init to check whether a SnapshotManager // might be needed to perform first-stage mounts. static bool IsSnapshotManagerNeeded(); // Helper function for second stage init to restorecon on the rollback indicator. static std::string GetGlobalRollbackIndicatorPath(); virtual ~ISnapshotManager() = default; // Begin an update. This must be called before creating any snapshots. It // will fail if GetUpdateState() != None. bool BeginUpdate(); virtual bool BeginUpdate() = 0; // Cancel an update; any snapshots will be deleted. This is allowed if the // state == Initiated, None, or Unverified (before rebooting to the new // slot). bool CancelUpdate(); virtual bool CancelUpdate() = 0; // Mark snapshot writes as having completed. After this, new snapshots cannot // be created, and the device must either cancel the OTA (either before Loading @@ -144,11 +120,11 @@ class SnapshotManager final { // Before calling this function, all snapshots must be mapped. // If |wipe| is set to true, wipe is scheduled after reboot, and snapshots // may need to be merged before wiping. bool FinishedSnapshotWrites(bool wipe); virtual bool FinishedSnapshotWrites(bool wipe) = 0; // Initiate a merge on all snapshot devices. This should only be used after an // update has been marked successful after booting. bool InitiateMerge(); virtual bool InitiateMerge() = 0; // Perform any necessary post-boot actions. This should be run soon after // /data is mounted. Loading Loading @@ -178,8 +154,8 @@ class SnapshotManager final { // // The optional callback allows the caller to periodically check the // progress with GetUpdateState(). UpdateState ProcessUpdateState(const std::function<bool()>& callback = {}, const std::function<bool()>& before_cancel = {}); virtual UpdateState ProcessUpdateState(const std::function<bool()>& callback = {}, const std::function<bool()>& before_cancel = {}) = 0; // Find the status of the current update, if any. // Loading @@ -187,28 +163,30 @@ class SnapshotManager final { // Merging: Value in the range [0, 100] // MergeCompleted: 100 // Other: 0 UpdateState GetUpdateState(double* progress = nullptr); virtual UpdateState GetUpdateState(double* progress = nullptr) = 0; // Create necessary COW device / files for OTA clients. New logical partitions will be added to // group "cow" in target_metadata. Regions of partitions of current_metadata will be // "write-protected" and snapshotted. Return CreateUpdateSnapshots(const DeltaArchiveManifest& manifest); virtual Return CreateUpdateSnapshots( const chromeos_update_engine::DeltaArchiveManifest& manifest) = 0; // Map a snapshotted partition for OTA clients to write to. Write-protected regions are // determined previously in CreateSnapshots. bool MapUpdateSnapshot(const CreateLogicalPartitionParams& params, std::string* snapshot_path); virtual bool MapUpdateSnapshot(const android::fs_mgr::CreateLogicalPartitionParams& params, std::string* snapshot_path) = 0; // Unmap a snapshot device that's previously mapped with MapUpdateSnapshot. bool UnmapUpdateSnapshot(const std::string& target_partition_name); virtual bool UnmapUpdateSnapshot(const std::string& target_partition_name) = 0; // If this returns true, first-stage mount must call // CreateLogicalAndSnapshotPartitions rather than CreateLogicalPartitions. bool NeedSnapshotsInFirstStageMount(); virtual bool NeedSnapshotsInFirstStageMount() = 0; // Perform first-stage mapping of snapshot targets. This replaces init's // call to CreateLogicalPartitions when snapshots are present. bool CreateLogicalAndSnapshotPartitions(const std::string& super_device, const std::chrono::milliseconds& timeout_ms = {}); virtual bool CreateLogicalAndSnapshotPartitions( const std::string& super_device, const std::chrono::milliseconds& timeout_ms = {}) = 0; // This method should be called preceding any wipe or flash of metadata or // userdata. It is only valid in recovery or fastbootd, and it ensures that Loading @@ -221,7 +199,7 @@ class SnapshotManager final { // // Returns true on success (or nothing to do), false on failure. The // optional callback fires periodically to query progress via GetUpdateState. bool HandleImminentDataWipe(const std::function<void()>& callback = {}); virtual bool HandleImminentDataWipe(const std::function<void()>& callback = {}) = 0; // This method is only allowed in recovery and is used as a helper to // initialize the snapshot devices as a requirement to mount a snapshotted Loading @@ -234,14 +212,15 @@ class SnapshotManager final { // be aborted. // This function mounts /metadata when called, and unmounts /metadata upon // return. CreateResult RecoveryCreateSnapshotDevices(); virtual CreateResult RecoveryCreateSnapshotDevices() = 0; // Same as RecoveryCreateSnapshotDevices(), but does not auto mount/umount // /metadata. CreateResult RecoveryCreateSnapshotDevices(const std::unique_ptr<AutoDevice>& metadata_device); virtual CreateResult RecoveryCreateSnapshotDevices( const std::unique_ptr<AutoDevice>& metadata_device) = 0; // Dump debug information. bool Dump(std::ostream& os); virtual bool Dump(std::ostream& os) = 0; // Ensure metadata directory is mounted in recovery. When the returned // AutoDevice is destroyed, the metadata directory is automatically Loading @@ -257,7 +236,65 @@ class SnapshotManager final { // auto b = mgr->EnsureMetadataMounted(); // does nothing // b.reset() // unmounts // a.reset() // does nothing std::unique_ptr<AutoDevice> EnsureMetadataMounted(); virtual std::unique_ptr<AutoDevice> EnsureMetadataMounted() = 0; // Return the associated ISnapshotMergeStats instance. Never null. virtual ISnapshotMergeStats* GetSnapshotMergeStatsInstance() = 0; }; class SnapshotManager final : public ISnapshotManager { using CreateLogicalPartitionParams = android::fs_mgr::CreateLogicalPartitionParams; using IPartitionOpener = android::fs_mgr::IPartitionOpener; using LpMetadata = android::fs_mgr::LpMetadata; using MetadataBuilder = android::fs_mgr::MetadataBuilder; using DeltaArchiveManifest = chromeos_update_engine::DeltaArchiveManifest; using MergeStatus = android::hardware::boot::V1_1::MergeStatus; using FiemapStatus = android::fiemap::FiemapStatus; friend class SnapshotMergeStats; public: ~SnapshotManager(); // Return a new SnapshotManager instance, or null on error. The device // pointer is owned for the lifetime of SnapshotManager. If null, a default // instance will be created. static std::unique_ptr<SnapshotManager> New(IDeviceInfo* device = nullptr); // This is similar to New(), except designed specifically for first-stage // init or recovery. static std::unique_ptr<SnapshotManager> NewForFirstStageMount(IDeviceInfo* device = nullptr); // Helper function for first-stage init to check whether a SnapshotManager // might be needed to perform first-stage mounts. static bool IsSnapshotManagerNeeded(); // Helper function for second stage init to restorecon on the rollback indicator. static std::string GetGlobalRollbackIndicatorPath(); // ISnapshotManager overrides. bool BeginUpdate() override; bool CancelUpdate() override; bool FinishedSnapshotWrites(bool wipe) override; bool InitiateMerge() override; UpdateState ProcessUpdateState(const std::function<bool()>& callback = {}, const std::function<bool()>& before_cancel = {}) override; UpdateState GetUpdateState(double* progress = nullptr) override; Return CreateUpdateSnapshots(const DeltaArchiveManifest& manifest) override; bool MapUpdateSnapshot(const CreateLogicalPartitionParams& params, std::string* snapshot_path) override; bool UnmapUpdateSnapshot(const std::string& target_partition_name) override; bool NeedSnapshotsInFirstStageMount() override; bool CreateLogicalAndSnapshotPartitions( const std::string& super_device, const std::chrono::milliseconds& timeout_ms = {}) override; bool HandleImminentDataWipe(const std::function<void()>& callback = {}) override; CreateResult RecoveryCreateSnapshotDevices() override; CreateResult RecoveryCreateSnapshotDevices( const std::unique_ptr<AutoDevice>& metadata_device) override; bool Dump(std::ostream& os) override; std::unique_ptr<AutoDevice> EnsureMetadataMounted() override; ISnapshotMergeStats* GetSnapshotMergeStatsInstance() override; private: FRIEND_TEST(SnapshotTest, CleanFirstStageMount); Loading fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h +17 −7 Original line number Diff line number Diff line Loading @@ -23,14 +23,12 @@ namespace android { namespace snapshot { class SnapshotMergeStats { class ISnapshotMergeStats { public: // Not thread safe. static SnapshotMergeStats* GetInstance(SnapshotManager& manager); virtual ~ISnapshotMergeStats() = default; // Called when merge starts or resumes. bool Start(); void set_state(android::snapshot::UpdateState state); virtual bool Start() = 0; virtual void set_state(android::snapshot::UpdateState state) = 0; // Called when merge ends. Properly clean up permanent storage. class Result { Loading @@ -40,7 +38,19 @@ class SnapshotMergeStats { // Time between successful Start() / Resume() to Finish(). virtual std::chrono::steady_clock::duration merge_time() const = 0; }; std::unique_ptr<Result> Finish(); // Return nullptr if any failure. virtual std::unique_ptr<Result> Finish() = 0; }; class SnapshotMergeStats : public ISnapshotMergeStats { public: // Not thread safe. static SnapshotMergeStats* GetInstance(SnapshotManager& manager); // ISnapshotMergeStats overrides bool Start() override; void set_state(android::snapshot::UpdateState state) override; std::unique_ptr<Result> Finish() override; private: bool ReadState(); Loading Loading
fs_mgr/libsnapshot/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ filegroup { "device_info.cpp", "snapshot.cpp", "snapshot_stats.cpp", "snapshot_stub.cpp", "snapshot_metadata_updater.cpp", "partition_cow_creator.cpp", "return.cpp", Loading
fs_mgr/libsnapshot/include/libsnapshot/mock_device_info.h 0 → 100644 +37 −0 Original line number Diff line number Diff line // Copyright (C) 2020 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #include <libsnapshot/snapshot.h> #include <gmock/gmock.h> namespace android::snapshot { class MockDeviceInfo : public SnapshotManager::IDeviceInfo { public: MOCK_METHOD(std::string, GetGsidDir, (), (const, override)); MOCK_METHOD(std::string, GetMetadataDir, (), (const, override)); MOCK_METHOD(std::string, GetSlotSuffix, (), (const, override)); MOCK_METHOD(std::string, GetOtherSlotSuffix, (), (const, override)); MOCK_METHOD(std::string, GetSuperDevice, (uint32_t slot), (const, override)); MOCK_METHOD(const android::fs_mgr::IPartitionOpener&, GetPartitionOpener, (), (const)); MOCK_METHOD(bool, IsOverlayfsSetup, (), (const, override)); MOCK_METHOD(bool, SetBootControlMergeStatus, (MergeStatus status), (override)); MOCK_METHOD(bool, SetSlotAsUnbootable, (unsigned int slot), (override)); MOCK_METHOD(bool, IsRecovery, (), (const, override)); }; } // namespace android::snapshot
fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h 0 → 100644 +54 −0 Original line number Diff line number Diff line // Copyright (C) 2020 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #include <libsnapshot/snapshot.h> #include <gmock/gmock.h> namespace android::snapshot { class MockSnapshotManager : public ISnapshotManager { public: MOCK_METHOD(bool, BeginUpdate, (), (override)); MOCK_METHOD(bool, CancelUpdate, (), (override)); MOCK_METHOD(bool, FinishedSnapshotWrites, (bool wipe), (override)); MOCK_METHOD(bool, InitiateMerge, (), (override)); MOCK_METHOD(UpdateState, ProcessUpdateState, (const std::function<bool()>& callback, const std::function<bool()>& before_cancel), (override)); MOCK_METHOD(UpdateState, GetUpdateState, (double* progress), (override)); MOCK_METHOD(Return, CreateUpdateSnapshots, (const chromeos_update_engine::DeltaArchiveManifest& manifest), (override)); MOCK_METHOD(bool, MapUpdateSnapshot, (const android::fs_mgr::CreateLogicalPartitionParams& params, std::string* snapshot_path), (override)); MOCK_METHOD(bool, UnmapUpdateSnapshot, (const std::string& target_partition_name), (override)); MOCK_METHOD(bool, NeedSnapshotsInFirstStageMount, (), (override)); MOCK_METHOD(bool, CreateLogicalAndSnapshotPartitions, (const std::string& super_device, const std::chrono::milliseconds& timeout_ms), (override)); MOCK_METHOD(bool, HandleImminentDataWipe, (const std::function<void()>& callback), (override)); MOCK_METHOD(CreateResult, RecoveryCreateSnapshotDevices, (), (override)); MOCK_METHOD(CreateResult, RecoveryCreateSnapshotDevices, (const std::unique_ptr<AutoDevice>& metadata_device), (override)); MOCK_METHOD(bool, Dump, (std::ostream & os), (override)); MOCK_METHOD(std::unique_ptr<AutoDevice>, EnsureMetadataMounted, (), (override)); MOCK_METHOD(ISnapshotMergeStats*, GetSnapshotMergeStatsInstance, (), (override)); }; } // namespace android::snapshot
fs_mgr/libsnapshot/include/libsnapshot/snapshot.h +86 −49 Original line number Diff line number Diff line Loading @@ -70,6 +70,8 @@ struct AutoDeleteCowImage; struct AutoDeleteSnapshot; struct AutoDeviceList; struct PartitionCowCreator; class ISnapshotMergeStats; class SnapshotMergeStats; class SnapshotStatus; static constexpr const std::string_view kCowGroupName = "cow"; Loading @@ -83,17 +85,7 @@ enum class CreateResult : unsigned int { NOT_CREATED, }; class SnapshotManager final { using CreateLogicalPartitionParams = android::fs_mgr::CreateLogicalPartitionParams; using IPartitionOpener = android::fs_mgr::IPartitionOpener; using LpMetadata = android::fs_mgr::LpMetadata; using MetadataBuilder = android::fs_mgr::MetadataBuilder; using DeltaArchiveManifest = chromeos_update_engine::DeltaArchiveManifest; using MergeStatus = android::hardware::boot::V1_1::MergeStatus; using FiemapStatus = android::fiemap::FiemapStatus; friend class SnapshotMergeStats; class ISnapshotManager { public: // Dependency injection for testing. class IDeviceInfo { Loading @@ -104,39 +96,23 @@ class SnapshotManager final { virtual std::string GetSlotSuffix() const = 0; virtual std::string GetOtherSlotSuffix() const = 0; virtual std::string GetSuperDevice(uint32_t slot) const = 0; virtual const IPartitionOpener& GetPartitionOpener() const = 0; virtual const android::fs_mgr::IPartitionOpener& GetPartitionOpener() const = 0; virtual bool IsOverlayfsSetup() const = 0; virtual bool SetBootControlMergeStatus(MergeStatus status) = 0; virtual bool SetBootControlMergeStatus( android::hardware::boot::V1_1::MergeStatus status) = 0; virtual bool SetSlotAsUnbootable(unsigned int slot) = 0; virtual bool IsRecovery() const = 0; }; ~SnapshotManager(); // Return a new SnapshotManager instance, or null on error. The device // pointer is owned for the lifetime of SnapshotManager. If null, a default // instance will be created. static std::unique_ptr<SnapshotManager> New(IDeviceInfo* device = nullptr); // This is similar to New(), except designed specifically for first-stage // init or recovery. static std::unique_ptr<SnapshotManager> NewForFirstStageMount(IDeviceInfo* device = nullptr); // Helper function for first-stage init to check whether a SnapshotManager // might be needed to perform first-stage mounts. static bool IsSnapshotManagerNeeded(); // Helper function for second stage init to restorecon on the rollback indicator. static std::string GetGlobalRollbackIndicatorPath(); virtual ~ISnapshotManager() = default; // Begin an update. This must be called before creating any snapshots. It // will fail if GetUpdateState() != None. bool BeginUpdate(); virtual bool BeginUpdate() = 0; // Cancel an update; any snapshots will be deleted. This is allowed if the // state == Initiated, None, or Unverified (before rebooting to the new // slot). bool CancelUpdate(); virtual bool CancelUpdate() = 0; // Mark snapshot writes as having completed. After this, new snapshots cannot // be created, and the device must either cancel the OTA (either before Loading @@ -144,11 +120,11 @@ class SnapshotManager final { // Before calling this function, all snapshots must be mapped. // If |wipe| is set to true, wipe is scheduled after reboot, and snapshots // may need to be merged before wiping. bool FinishedSnapshotWrites(bool wipe); virtual bool FinishedSnapshotWrites(bool wipe) = 0; // Initiate a merge on all snapshot devices. This should only be used after an // update has been marked successful after booting. bool InitiateMerge(); virtual bool InitiateMerge() = 0; // Perform any necessary post-boot actions. This should be run soon after // /data is mounted. Loading Loading @@ -178,8 +154,8 @@ class SnapshotManager final { // // The optional callback allows the caller to periodically check the // progress with GetUpdateState(). UpdateState ProcessUpdateState(const std::function<bool()>& callback = {}, const std::function<bool()>& before_cancel = {}); virtual UpdateState ProcessUpdateState(const std::function<bool()>& callback = {}, const std::function<bool()>& before_cancel = {}) = 0; // Find the status of the current update, if any. // Loading @@ -187,28 +163,30 @@ class SnapshotManager final { // Merging: Value in the range [0, 100] // MergeCompleted: 100 // Other: 0 UpdateState GetUpdateState(double* progress = nullptr); virtual UpdateState GetUpdateState(double* progress = nullptr) = 0; // Create necessary COW device / files for OTA clients. New logical partitions will be added to // group "cow" in target_metadata. Regions of partitions of current_metadata will be // "write-protected" and snapshotted. Return CreateUpdateSnapshots(const DeltaArchiveManifest& manifest); virtual Return CreateUpdateSnapshots( const chromeos_update_engine::DeltaArchiveManifest& manifest) = 0; // Map a snapshotted partition for OTA clients to write to. Write-protected regions are // determined previously in CreateSnapshots. bool MapUpdateSnapshot(const CreateLogicalPartitionParams& params, std::string* snapshot_path); virtual bool MapUpdateSnapshot(const android::fs_mgr::CreateLogicalPartitionParams& params, std::string* snapshot_path) = 0; // Unmap a snapshot device that's previously mapped with MapUpdateSnapshot. bool UnmapUpdateSnapshot(const std::string& target_partition_name); virtual bool UnmapUpdateSnapshot(const std::string& target_partition_name) = 0; // If this returns true, first-stage mount must call // CreateLogicalAndSnapshotPartitions rather than CreateLogicalPartitions. bool NeedSnapshotsInFirstStageMount(); virtual bool NeedSnapshotsInFirstStageMount() = 0; // Perform first-stage mapping of snapshot targets. This replaces init's // call to CreateLogicalPartitions when snapshots are present. bool CreateLogicalAndSnapshotPartitions(const std::string& super_device, const std::chrono::milliseconds& timeout_ms = {}); virtual bool CreateLogicalAndSnapshotPartitions( const std::string& super_device, const std::chrono::milliseconds& timeout_ms = {}) = 0; // This method should be called preceding any wipe or flash of metadata or // userdata. It is only valid in recovery or fastbootd, and it ensures that Loading @@ -221,7 +199,7 @@ class SnapshotManager final { // // Returns true on success (or nothing to do), false on failure. The // optional callback fires periodically to query progress via GetUpdateState. bool HandleImminentDataWipe(const std::function<void()>& callback = {}); virtual bool HandleImminentDataWipe(const std::function<void()>& callback = {}) = 0; // This method is only allowed in recovery and is used as a helper to // initialize the snapshot devices as a requirement to mount a snapshotted Loading @@ -234,14 +212,15 @@ class SnapshotManager final { // be aborted. // This function mounts /metadata when called, and unmounts /metadata upon // return. CreateResult RecoveryCreateSnapshotDevices(); virtual CreateResult RecoveryCreateSnapshotDevices() = 0; // Same as RecoveryCreateSnapshotDevices(), but does not auto mount/umount // /metadata. CreateResult RecoveryCreateSnapshotDevices(const std::unique_ptr<AutoDevice>& metadata_device); virtual CreateResult RecoveryCreateSnapshotDevices( const std::unique_ptr<AutoDevice>& metadata_device) = 0; // Dump debug information. bool Dump(std::ostream& os); virtual bool Dump(std::ostream& os) = 0; // Ensure metadata directory is mounted in recovery. When the returned // AutoDevice is destroyed, the metadata directory is automatically Loading @@ -257,7 +236,65 @@ class SnapshotManager final { // auto b = mgr->EnsureMetadataMounted(); // does nothing // b.reset() // unmounts // a.reset() // does nothing std::unique_ptr<AutoDevice> EnsureMetadataMounted(); virtual std::unique_ptr<AutoDevice> EnsureMetadataMounted() = 0; // Return the associated ISnapshotMergeStats instance. Never null. virtual ISnapshotMergeStats* GetSnapshotMergeStatsInstance() = 0; }; class SnapshotManager final : public ISnapshotManager { using CreateLogicalPartitionParams = android::fs_mgr::CreateLogicalPartitionParams; using IPartitionOpener = android::fs_mgr::IPartitionOpener; using LpMetadata = android::fs_mgr::LpMetadata; using MetadataBuilder = android::fs_mgr::MetadataBuilder; using DeltaArchiveManifest = chromeos_update_engine::DeltaArchiveManifest; using MergeStatus = android::hardware::boot::V1_1::MergeStatus; using FiemapStatus = android::fiemap::FiemapStatus; friend class SnapshotMergeStats; public: ~SnapshotManager(); // Return a new SnapshotManager instance, or null on error. The device // pointer is owned for the lifetime of SnapshotManager. If null, a default // instance will be created. static std::unique_ptr<SnapshotManager> New(IDeviceInfo* device = nullptr); // This is similar to New(), except designed specifically for first-stage // init or recovery. static std::unique_ptr<SnapshotManager> NewForFirstStageMount(IDeviceInfo* device = nullptr); // Helper function for first-stage init to check whether a SnapshotManager // might be needed to perform first-stage mounts. static bool IsSnapshotManagerNeeded(); // Helper function for second stage init to restorecon on the rollback indicator. static std::string GetGlobalRollbackIndicatorPath(); // ISnapshotManager overrides. bool BeginUpdate() override; bool CancelUpdate() override; bool FinishedSnapshotWrites(bool wipe) override; bool InitiateMerge() override; UpdateState ProcessUpdateState(const std::function<bool()>& callback = {}, const std::function<bool()>& before_cancel = {}) override; UpdateState GetUpdateState(double* progress = nullptr) override; Return CreateUpdateSnapshots(const DeltaArchiveManifest& manifest) override; bool MapUpdateSnapshot(const CreateLogicalPartitionParams& params, std::string* snapshot_path) override; bool UnmapUpdateSnapshot(const std::string& target_partition_name) override; bool NeedSnapshotsInFirstStageMount() override; bool CreateLogicalAndSnapshotPartitions( const std::string& super_device, const std::chrono::milliseconds& timeout_ms = {}) override; bool HandleImminentDataWipe(const std::function<void()>& callback = {}) override; CreateResult RecoveryCreateSnapshotDevices() override; CreateResult RecoveryCreateSnapshotDevices( const std::unique_ptr<AutoDevice>& metadata_device) override; bool Dump(std::ostream& os) override; std::unique_ptr<AutoDevice> EnsureMetadataMounted() override; ISnapshotMergeStats* GetSnapshotMergeStatsInstance() override; private: FRIEND_TEST(SnapshotTest, CleanFirstStageMount); Loading
fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h +17 −7 Original line number Diff line number Diff line Loading @@ -23,14 +23,12 @@ namespace android { namespace snapshot { class SnapshotMergeStats { class ISnapshotMergeStats { public: // Not thread safe. static SnapshotMergeStats* GetInstance(SnapshotManager& manager); virtual ~ISnapshotMergeStats() = default; // Called when merge starts or resumes. bool Start(); void set_state(android::snapshot::UpdateState state); virtual bool Start() = 0; virtual void set_state(android::snapshot::UpdateState state) = 0; // Called when merge ends. Properly clean up permanent storage. class Result { Loading @@ -40,7 +38,19 @@ class SnapshotMergeStats { // Time between successful Start() / Resume() to Finish(). virtual std::chrono::steady_clock::duration merge_time() const = 0; }; std::unique_ptr<Result> Finish(); // Return nullptr if any failure. virtual std::unique_ptr<Result> Finish() = 0; }; class SnapshotMergeStats : public ISnapshotMergeStats { public: // Not thread safe. static SnapshotMergeStats* GetInstance(SnapshotManager& manager); // ISnapshotMergeStats overrides bool Start() override; void set_state(android::snapshot::UpdateState state) override; std::unique_ptr<Result> Finish() override; private: bool ReadState(); Loading