Merge "libsnapshot: Add a source build fingerprint to the update state." into sc-dev
This commit is contained in:
commit
d308a5ab84
9 changed files with 68 additions and 10 deletions
|
|
@ -191,6 +191,9 @@ message SnapshotUpdateStatus {
|
|||
|
||||
// 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 @@ message SnapshotMergeReport {
|
|||
|
||||
// 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ class MockSnapshotManager : public ISnapshotManager {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -35,13 +35,16 @@ class MockSnapshotMergeStats final : public ISnapshotMergeStats {
|
|||
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.
|
||||
|
|
|
|||
|
|
@ -177,6 +177,9 @@ class ISnapshotManager {
|
|||
// 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 @@ class SnapshotManager final : public ISnapshotManager {
|
|||
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,
|
||||
|
|
|
|||
|
|
@ -35,12 +35,14 @@ class ISnapshotMergeStats {
|
|||
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 @@ class ISnapshotMergeStats {
|
|||
};
|
||||
// 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 @@ class SnapshotMergeStats : public ISnapshotMergeStats {
|
|||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ class SnapshotManagerStub : public ISnapshotManager {
|
|||
ISnapshotMergeStats* GetSnapshotMergeStatsInstance() override;
|
||||
bool MapAllSnapshots(const std::chrono::milliseconds& timeout_ms) override;
|
||||
bool UnmapAllSnapshots() override;
|
||||
std::string ReadSourceBuildFingerprint() override;
|
||||
};
|
||||
|
||||
} // namespace android::snapshot
|
||||
|
|
|
|||
|
|
@ -716,7 +716,7 @@ bool SnapshotManager::InitiateMerge() {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ bool SnapshotManager::WriteUpdateState(LockedFile* lock, UpdateState state,
|
|||
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 @@ Return SnapshotManager::CreateUpdateSnapshots(const DeltaArchiveManifest& manife
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ bool SnapshotManager::Dump(std::ostream& os) {
|
|||
|
||||
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 @@ bool SnapshotManager::Dump(std::ostream& os) {
|
|||
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 @@ MergeFailureCode SnapshotManager::ReadMergeFailureCode() {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -91,7 +91,6 @@ void SnapshotMergeStats::set_state(android::snapshot::UpdateState state, bool us
|
|||
|
||||
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 @@ MergeFailureCode SnapshotMergeStats::merge_failure_code() {
|
|||
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,
|
||||
|
|
|
|||
|
|
@ -136,7 +136,10 @@ class SnapshotMergeStatsStub : public ISnapshotMergeStats {
|
|||
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 @@ auto SnapshotManagerStub::ReadMergeFailureCode() -> MergeFailureCode {
|
|||
return MergeFailureCode::Ok;
|
||||
}
|
||||
|
||||
std::string SnapshotManagerStub::ReadSourceBuildFingerprint() {
|
||||
LOG(ERROR) << __FUNCTION__ << " should never be called.";
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace android::snapshot
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue