From 02e639d1f5f68d25a63e0e0bb45266233c4dbeb6 Mon Sep 17 00:00:00 2001 From: Alessio Balsini Date: Tue, 26 May 2020 12:09:59 +0100 Subject: [PATCH] libsnapshot: Export COW image size Enable libsnapshot to export the size of the COW image, representing the fraction of the COW device that is temporarily created in the /data partition, computed just before initializing a merge operation. Thise additional information can be used by other components (i.e., update engine) to enrich Virtual A/B metrics. Bug: 154016862 Test: manual OTA Signed-off-by: Alessio Balsini Change-Id: I4faa0785f23884e26161e0d51268dd7a305d86bf Merged-In: I4faa0785f23884e26161e0d51268dd7a305d86bf --- fs_mgr/libsnapshot/android/snapshot/snapshot.proto | 3 +++ .../libsnapshot/include/libsnapshot/mock_snapshot.h | 2 +- fs_mgr/libsnapshot/include/libsnapshot/snapshot.h | 4 ++-- .../include/libsnapshot/snapshot_stats.h | 4 ++++ .../libsnapshot/include/libsnapshot/snapshot_stub.h | 2 +- fs_mgr/libsnapshot/snapshot.cpp | 13 ++++++++++++- fs_mgr/libsnapshot/snapshot_stats.cpp | 9 +++++++++ fs_mgr/libsnapshot/snapshot_stub.cpp | 4 +++- 8 files changed, 35 insertions(+), 6 deletions(-) diff --git a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto index 2ac0c4485..587089e76 100644 --- a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto +++ b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto @@ -140,4 +140,7 @@ message SnapshotMergeReport { // Number of reboots that occurred after issuing and before completeing the // merge of all the snapshot devices. int32 resume_count = 2; + + // Total size of all the COW images before the update. + uint64 cow_file_size = 4; } diff --git a/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h index cf0b08519..4457de398 100644 --- a/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h +++ b/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h @@ -25,7 +25,7 @@ class MockSnapshotManager : public ISnapshotManager { MOCK_METHOD(bool, BeginUpdate, (), (override)); MOCK_METHOD(bool, CancelUpdate, (), (override)); MOCK_METHOD(bool, FinishedSnapshotWrites, (bool wipe), (override)); - MOCK_METHOD(bool, InitiateMerge, (), (override)); + MOCK_METHOD(bool, InitiateMerge, (uint64_t * cow_file_size), (override)); MOCK_METHOD(UpdateState, ProcessUpdateState, (const std::function& callback, const std::function& before_cancel), diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h index 2d6071fe1..3c2c77683 100644 --- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h +++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h @@ -124,7 +124,7 @@ class ISnapshotManager { // Initiate a merge on all snapshot devices. This should only be used after an // update has been marked successful after booting. - virtual bool InitiateMerge() = 0; + virtual bool InitiateMerge(uint64_t* cow_file_size = nullptr) = 0; // Perform any necessary post-boot actions. This should be run soon after // /data is mounted. @@ -281,7 +281,7 @@ class SnapshotManager final : public ISnapshotManager { bool BeginUpdate() override; bool CancelUpdate() override; bool FinishedSnapshotWrites(bool wipe) override; - bool InitiateMerge() override; + bool InitiateMerge(uint64_t* cow_file_size = nullptr) override; UpdateState ProcessUpdateState(const std::function& callback = {}, const std::function& before_cancel = {}) override; UpdateState GetUpdateState(double* progress = nullptr) override; diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h index 4caf63231..d691d4f31 100644 --- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h +++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h @@ -29,6 +29,8 @@ class ISnapshotMergeStats { // Called when merge starts or resumes. virtual bool Start() = 0; virtual void set_state(android::snapshot::UpdateState state) = 0; + virtual void set_cow_file_size(uint64_t cow_file_size) = 0; + virtual uint64_t cow_file_size() = 0; // Called when merge ends. Properly clean up permanent storage. class Result { @@ -50,6 +52,8 @@ class SnapshotMergeStats : public ISnapshotMergeStats { // ISnapshotMergeStats overrides bool Start() override; void set_state(android::snapshot::UpdateState state) override; + void set_cow_file_size(uint64_t cow_file_size) override; + uint64_t cow_file_size() override; std::unique_ptr Finish() override; private: diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h index 9c8290697..7a27fadca 100644 --- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h +++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h @@ -27,7 +27,7 @@ class SnapshotManagerStub : public ISnapshotManager { bool BeginUpdate() override; bool CancelUpdate() override; bool FinishedSnapshotWrites(bool wipe) override; - bool InitiateMerge() override; + bool InitiateMerge(uint64_t* cow_file_size = nullptr) override; UpdateState ProcessUpdateState(const std::function& callback = {}, const std::function& before_cancel = {}) override; UpdateState GetUpdateState(double* progress = nullptr) override; diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp index 488009a9c..5909cff79 100644 --- a/fs_mgr/libsnapshot/snapshot.cpp +++ b/fs_mgr/libsnapshot/snapshot.cpp @@ -555,7 +555,7 @@ bool SnapshotManager::DeleteSnapshot(LockedFile* lock, const std::string& name) return true; } -bool SnapshotManager::InitiateMerge() { +bool SnapshotManager::InitiateMerge(uint64_t* cow_file_size) { auto lock = LockExclusive(); if (!lock) return false; @@ -618,6 +618,7 @@ bool SnapshotManager::InitiateMerge() { } } + uint64_t total_cow_file_size = 0; DmTargetSnapshot::Status initial_target_values = {}; for (const auto& snapshot : snapshots) { DmTargetSnapshot::Status current_status; @@ -627,6 +628,16 @@ bool SnapshotManager::InitiateMerge() { initial_target_values.sectors_allocated += current_status.sectors_allocated; initial_target_values.total_sectors += current_status.total_sectors; initial_target_values.metadata_sectors += current_status.metadata_sectors; + + SnapshotStatus snapshot_status; + if (!ReadSnapshotStatus(lock.get(), snapshot, &snapshot_status)) { + return false; + } + total_cow_file_size += snapshot_status.cow_file_size(); + } + + if (cow_file_size) { + *cow_file_size = total_cow_file_size; } SnapshotUpdateStatus initial_status; diff --git a/fs_mgr/libsnapshot/snapshot_stats.cpp b/fs_mgr/libsnapshot/snapshot_stats.cpp index 5da7b9873..372373086 100644 --- a/fs_mgr/libsnapshot/snapshot_stats.cpp +++ b/fs_mgr/libsnapshot/snapshot_stats.cpp @@ -88,6 +88,15 @@ void SnapshotMergeStats::set_state(android::snapshot::UpdateState state) { report_.set_state(state); } +void SnapshotMergeStats::set_cow_file_size(uint64_t cow_file_size) { + report_.set_cow_file_size(cow_file_size); + WriteState(); +} + +uint64_t SnapshotMergeStats::cow_file_size() { + return report_.cow_file_size(); +} + class SnapshotMergeStatsResultImpl : public SnapshotMergeStats::Result { public: SnapshotMergeStatsResultImpl(const SnapshotMergeReport& report, diff --git a/fs_mgr/libsnapshot/snapshot_stub.cpp b/fs_mgr/libsnapshot/snapshot_stub.cpp index 2aaa78c85..9b6f758cc 100644 --- a/fs_mgr/libsnapshot/snapshot_stub.cpp +++ b/fs_mgr/libsnapshot/snapshot_stub.cpp @@ -42,7 +42,7 @@ bool SnapshotManagerStub::FinishedSnapshotWrites(bool) { return false; } -bool SnapshotManagerStub::InitiateMerge() { +bool SnapshotManagerStub::InitiateMerge(uint64_t*) { LOG(ERROR) << __FUNCTION__ << " should never be called."; return false; } @@ -118,6 +118,8 @@ std::unique_ptr SnapshotManagerStub::EnsureMetadataMounted() { class SnapshotMergeStatsStub : public ISnapshotMergeStats { bool Start() override { return false; } void set_state(android::snapshot::UpdateState) override {} + void set_cow_file_size(uint64_t) override {} + uint64_t cow_file_size() override { return 0; } std::unique_ptr Finish() override { return nullptr; } };