Merge "Utility class to measure snapshot merge duration" am: e87527faa3 am: e6060c927c am: 5a88ff5e18
Change-Id: Ie2f86222e09bdaf1976f10fd996912d550b47e7d
diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp
index adfee1d..d274ba4 100644
--- a/fs_mgr/libsnapshot/Android.bp
+++ b/fs_mgr/libsnapshot/Android.bp
@@ -72,6 +72,7 @@
"android/snapshot/snapshot.proto",
"device_info.cpp",
"snapshot.cpp",
+ "snapshot_stats.cpp",
"snapshot_metadata_updater.cpp",
"partition_cow_creator.cpp",
"return.cpp",
diff --git a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
index a3a518d..2ac0c44 100644
--- a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
+++ b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
@@ -131,3 +131,13 @@
// Sectors allocated for metadata in all the snapshot devices.
uint64 metadata_sectors = 4;
}
+
+// Next: 2
+message SnapshotMergeReport {
+ // Status of the update after the merge attempts.
+ UpdateState state = 1;
+
+ // Number of reboots that occurred after issuing and before completeing the
+ // merge of all the snapshot devices.
+ int32 resume_count = 2;
+}
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
index a56078a..0cf579d 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
@@ -91,6 +91,8 @@
using MergeStatus = android::hardware::boot::V1_1::MergeStatus;
using FiemapStatus = android::fiemap::FiemapStatus;
+ friend class SnapshotMergeStats;
+
public:
// Dependency injection for testing.
class IDeviceInfo {
diff --git a/fs_mgr/libsnapshot/snapshot_stats.cpp b/fs_mgr/libsnapshot/snapshot_stats.cpp
new file mode 100644
index 0000000..c48509e
--- /dev/null
+++ b/fs_mgr/libsnapshot/snapshot_stats.cpp
@@ -0,0 +1,80 @@
+// 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.
+
+#include "snapshot_stats.h"
+
+#include <sstream>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include "utility.h"
+
+namespace android {
+namespace snapshot {
+
+SnapshotMergeStats::SnapshotMergeStats(SnapshotManager& parent) : parent_(parent) {
+ init_time_ = std::chrono::steady_clock::now();
+}
+
+SnapshotMergeStats::~SnapshotMergeStats() {
+ std::string error;
+ auto file_path = parent_.GetMergeStateFilePath();
+ if (!android::base::RemoveFileIfExists(file_path, &error)) {
+ LOG(ERROR) << "Failed to remove merge statistics file " << file_path << ": " << error;
+ return;
+ }
+}
+
+void SnapshotMergeStats::Start() {
+ SnapshotMergeReport report;
+ report.set_resume_count(0);
+ report.set_state(UpdateState::None);
+
+ std::string contents;
+ if (!report.SerializeToString(&contents)) {
+ LOG(ERROR) << "Unable to serialize SnapshotMergeStats.";
+ return;
+ }
+ auto file_path = parent_.GetMergeStateFilePath();
+ if (!WriteStringToFileAtomic(contents, file_path)) {
+ PLOG(ERROR) << "Could not write to merge statistics file";
+ return;
+ }
+}
+
+void SnapshotMergeStats::Resume() {
+ std::string contents;
+ if (!android::base::ReadFileToString(parent_.GetMergeStateFilePath(), &contents)) {
+ PLOG(INFO) << "Read merge statistics file failed";
+ return;
+ }
+
+ if (!report_.ParseFromString(contents)) {
+ LOG(ERROR) << "Unable to parse merge statistics file as SnapshotMergeReport";
+ return;
+ }
+
+ report_.set_resume_count(report_.resume_count() + 1);
+}
+
+void SnapshotMergeStats::set_state(android::snapshot::UpdateState state) {
+ report_.set_state(state);
+}
+
+SnapshotMergeReport SnapshotMergeStats::GetReport() {
+ return report_;
+}
+
+} // namespace snapshot
+} // namespace android
diff --git a/fs_mgr/libsnapshot/snapshot_stats.h b/fs_mgr/libsnapshot/snapshot_stats.h
new file mode 100644
index 0000000..1ca9156
--- /dev/null
+++ b/fs_mgr/libsnapshot/snapshot_stats.h
@@ -0,0 +1,42 @@
+// 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 <chrono>
+
+#include <android/snapshot/snapshot.pb.h>
+#include <libsnapshot/snapshot.h>
+
+namespace android {
+namespace snapshot {
+
+class SnapshotMergeStats {
+ public:
+ SnapshotMergeStats(SnapshotManager& parent);
+ ~SnapshotMergeStats();
+ void Start();
+ void Resume();
+ void set_state(android::snapshot::UpdateState state);
+ SnapshotMergeReport GetReport();
+
+ private:
+ const SnapshotManager& parent_;
+ SnapshotMergeReport report_;
+ std::chrono::time_point<std::chrono::steady_clock> init_time_;
+ std::chrono::time_point<std::chrono::steady_clock> end_time_;
+};
+
+} // namespace snapshot
+} // namespace android