libsnapshot: Add a source build fingerprint to the update state.
Bug: 188909957
Test: manual test
Change-Id: I9aa155eee25dd49f48baede4f0a2e4ab2ab76980
Merged-In: I9aa155eee25dd49f48baede4f0a2e4ab2ab76980
diff --git a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
index 9f227c9..de8768c 100644
--- a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
+++ b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
@@ -191,6 +191,9 @@
// Merge failure code, filled if state == MergeFailed.
MergeFailureCode merge_failure_code = 7;
+
+ // Source build fingerprint.
+ string source_build_fingerprint = 8;
}
// Next: 10
@@ -222,4 +225,7 @@
// Merge failure code, filled if state == MergeFailed.
MergeFailureCode merge_failure_code = 9;
+
+ // The source fingerprint at the time the OTA was downloaded.
+ string source_build_fingerprint = 10;
}
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h
index 94d5055..ec58cca 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h
@@ -60,6 +60,7 @@
MOCK_METHOD(bool, Dump, (std::ostream & os), (override));
MOCK_METHOD(std::unique_ptr<AutoDevice>, EnsureMetadataMounted, (), (override));
MOCK_METHOD(ISnapshotMergeStats*, GetSnapshotMergeStatsInstance, (), (override));
+ MOCK_METHOD(std::string, ReadSourceBuildFingerprint, (), (override));
};
} // namespace android::snapshot
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot_merge_stats.h b/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot_merge_stats.h
index 067f99c..3d384cc 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot_merge_stats.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot_merge_stats.h
@@ -35,13 +35,16 @@
MOCK_METHOD(void, set_boot_complete_time_ms, (uint32_t), (override));
MOCK_METHOD(void, set_boot_complete_to_merge_start_time_ms, (uint32_t), (override));
MOCK_METHOD(void, set_merge_failure_code, (MergeFailureCode), (override));
+ MOCK_METHOD(void, set_source_build_fingerprint, (const std::string&), (override));
MOCK_METHOD(uint64_t, cow_file_size, (), (override));
MOCK_METHOD(uint64_t, total_cow_size_bytes, (), (override));
MOCK_METHOD(uint64_t, estimated_cow_size_bytes, (), (override));
MOCK_METHOD(uint32_t, boot_complete_time_ms, (), (override));
MOCK_METHOD(uint32_t, boot_complete_to_merge_start_time_ms, (), (override));
+ MOCK_METHOD(std::string, source_build_fingerprint, (), (override));
MOCK_METHOD(MergeFailureCode, merge_failure_code, (), (override));
MOCK_METHOD(std::unique_ptr<Result>, Finish, (), (override));
+ MOCK_METHOD(bool, WriteState, (), (override));
using ISnapshotMergeStats::Result;
// Return nullptr if any failure.
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
index 65034f7..15882b3 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
@@ -177,6 +177,9 @@
// code. Otherwise, MergeFailureCode::Ok is returned.
virtual MergeFailureCode ReadMergeFailureCode() = 0;
+ // If an update is in progress, return the source build fingerprint.
+ virtual std::string ReadSourceBuildFingerprint() = 0;
+
// Find the status of the current update, if any.
//
// |progress| depends on the returned status:
@@ -369,6 +372,7 @@
ISnapshotMergeStats* GetSnapshotMergeStatsInstance() override;
bool MapAllSnapshots(const std::chrono::milliseconds& timeout_ms = {}) override;
bool UnmapAllSnapshots() override;
+ std::string ReadSourceBuildFingerprint() override;
// We can't use WaitForFile during first-stage init, because ueventd is not
// running and therefore will not automatically create symlinks. Instead,
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h
index 4ce5077..8c2fec7 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h
@@ -35,12 +35,14 @@
virtual void set_boot_complete_time_ms(uint32_t ms) = 0;
virtual void set_boot_complete_to_merge_start_time_ms(uint32_t ms) = 0;
virtual void set_merge_failure_code(MergeFailureCode code) = 0;
+ virtual void set_source_build_fingerprint(const std::string& fingerprint) = 0;
virtual uint64_t cow_file_size() = 0;
virtual uint64_t total_cow_size_bytes() = 0;
virtual uint64_t estimated_cow_size_bytes() = 0;
virtual uint32_t boot_complete_time_ms() = 0;
virtual uint32_t boot_complete_to_merge_start_time_ms() = 0;
virtual MergeFailureCode merge_failure_code() = 0;
+ virtual std::string source_build_fingerprint() = 0;
// Called when merge ends. Properly clean up permanent storage.
class Result {
@@ -52,6 +54,10 @@
};
// Return nullptr if any failure.
virtual std::unique_ptr<Result> Finish() = 0;
+
+ // Write out the current state. This should be called when data might be lost that
+ // cannot be recovered (eg the COW sizes).
+ virtual bool WriteState() = 0;
};
class SnapshotMergeStats : public ISnapshotMergeStats {
@@ -74,11 +80,13 @@
uint32_t boot_complete_to_merge_start_time_ms() override;
void set_merge_failure_code(MergeFailureCode code) override;
MergeFailureCode merge_failure_code() override;
+ void set_source_build_fingerprint(const std::string& fingerprint) override;
+ std::string source_build_fingerprint() override;
std::unique_ptr<Result> Finish() override;
+ bool WriteState() override;
private:
bool ReadState();
- bool WriteState();
bool DeleteState();
SnapshotMergeStats(const std::string& path);
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h
index a7cd939..74b78c5 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h
@@ -57,6 +57,7 @@
ISnapshotMergeStats* GetSnapshotMergeStatsInstance() override;
bool MapAllSnapshots(const std::chrono::milliseconds& timeout_ms) override;
bool UnmapAllSnapshots() override;
+ std::string ReadSourceBuildFingerprint() override;
};
} // namespace android::snapshot
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index be732ec..0e36da1 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -716,7 +716,7 @@
}
}
- SnapshotUpdateStatus initial_status;
+ SnapshotUpdateStatus initial_status = ReadSnapshotUpdateStatus(lock.get());
initial_status.set_state(UpdateState::Merging);
initial_status.set_sectors_allocated(initial_target_values.sectors_allocated);
initial_status.set_total_sectors(initial_target_values.total_sectors);
@@ -2515,15 +2515,25 @@
SnapshotUpdateStatus status;
status.set_state(state);
- if (state == UpdateState::MergeFailed) {
- status.set_merge_failure_code(failure_code);
+ switch (state) {
+ case UpdateState::MergeFailed:
+ status.set_merge_failure_code(failure_code);
+ break;
+ case UpdateState::Initiated:
+ status.set_source_build_fingerprint(
+ android::base::GetProperty("ro.build.fingerprint", ""));
+ break;
+ default:
+ break;
}
// If we're transitioning between two valid states (eg, we're not beginning
- // or ending an OTA), then make sure to propagate the compression bit.
+ // or ending an OTA), then make sure to propagate the compression bit and
+ // build fingerprint.
if (!(state == UpdateState::Initiated || state == UpdateState::None)) {
SnapshotUpdateStatus old_status = ReadSnapshotUpdateStatus(lock);
status.set_compression_enabled(old_status.compression_enabled());
+ status.set_source_build_fingerprint(old_status.source_build_fingerprint());
}
return WriteSnapshotUpdateStatus(lock, status);
}
@@ -2838,7 +2848,7 @@
}
}
- SnapshotUpdateStatus status = {};
+ SnapshotUpdateStatus status = ReadSnapshotUpdateStatus(lock.get());
status.set_state(update_state);
status.set_compression_enabled(cow_creator.compression_enabled);
if (!WriteSnapshotUpdateStatus(lock.get(), status)) {
@@ -3264,9 +3274,10 @@
std::stringstream ss;
+ auto update_status = ReadSnapshotUpdateStatus(file.get());
+
ss << "Update state: " << ReadUpdateState(file.get()) << std::endl;
- ss << "Compression: " << ReadSnapshotUpdateStatus(file.get()).compression_enabled()
- << std::endl;
+ ss << "Compression: " << update_status.compression_enabled() << std::endl;
ss << "Current slot: " << device_->GetSlotSuffix() << std::endl;
ss << "Boot indicator: booting from " << GetCurrentSlot() << " slot" << std::endl;
ss << "Rollback indicator: "
@@ -3275,6 +3286,7 @@
ss << "Forward merge indicator: "
<< (access(GetForwardMergeIndicatorPath().c_str(), F_OK) == 0 ? "exists" : strerror(errno))
<< std::endl;
+ ss << "Source build fingerprint: " << update_status.source_build_fingerprint() << std::endl;
bool ok = true;
std::vector<std::string> snapshots;
@@ -3792,5 +3804,13 @@
return status.merge_failure_code();
}
+std::string SnapshotManager::ReadSourceBuildFingerprint() {
+ auto lock = LockExclusive();
+ if (!lock) return {};
+
+ SnapshotUpdateStatus status = ReadSnapshotUpdateStatus(lock.get());
+ return status.source_build_fingerprint();
+}
+
} // namespace snapshot
} // namespace android
diff --git a/fs_mgr/libsnapshot/snapshot_stats.cpp b/fs_mgr/libsnapshot/snapshot_stats.cpp
index 4a93d65..712eafb 100644
--- a/fs_mgr/libsnapshot/snapshot_stats.cpp
+++ b/fs_mgr/libsnapshot/snapshot_stats.cpp
@@ -91,7 +91,6 @@
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() {
@@ -138,6 +137,14 @@
return report_.merge_failure_code();
}
+void SnapshotMergeStats::set_source_build_fingerprint(const std::string& fingerprint) {
+ report_.set_source_build_fingerprint(fingerprint);
+}
+
+std::string SnapshotMergeStats::source_build_fingerprint() {
+ return report_.source_build_fingerprint();
+}
+
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 1a9eda5..a8d5b8a 100644
--- a/fs_mgr/libsnapshot/snapshot_stub.cpp
+++ b/fs_mgr/libsnapshot/snapshot_stub.cpp
@@ -136,7 +136,10 @@
void set_boot_complete_to_merge_start_time_ms(uint32_t) override {}
uint32_t boot_complete_to_merge_start_time_ms() override { return 0; }
void set_merge_failure_code(MergeFailureCode) override {}
- MergeFailureCode merge_failure_code() { return MergeFailureCode::Ok; }
+ MergeFailureCode merge_failure_code() override { return MergeFailureCode::Ok; }
+ void set_source_build_fingerprint(const std::string&) override {}
+ std::string source_build_fingerprint() override { return {}; }
+ bool WriteState() override { return false; }
};
ISnapshotMergeStats* SnapshotManagerStub::GetSnapshotMergeStatsInstance() {
@@ -170,4 +173,9 @@
return MergeFailureCode::Ok;
}
+std::string SnapshotManagerStub::ReadSourceBuildFingerprint() {
+ LOG(ERROR) << __FUNCTION__ << " should never be called.";
+ return {};
+}
+
} // namespace android::snapshot