Skip to content

Commit

Permalink
libsnapshot: Add a source build fingerprint to the update state.
Browse files Browse the repository at this point in the history
Bug: 188909957
Test: manual test
Change-Id: I9aa155eee25dd49f48baede4f0a2e4ab2ab76980
Merged-In: I9aa155eee25dd49f48baede4f0a2e4ab2ab76980
  • Loading branch information
dvandercorp committed Jul 1, 2021
1 parent bfa4e30 commit e00a567
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 10 deletions.
6 changes: 6 additions & 0 deletions fs_mgr/libsnapshot/android/snapshot/snapshot.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
1 change: 1 addition & 0 deletions fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 9 additions & 1 deletion fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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);

Expand Down
1 change: 1 addition & 0 deletions fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
34 changes: 27 additions & 7 deletions fs_mgr/libsnapshot/snapshot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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: "
Expand All @@ -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;
Expand Down Expand Up @@ -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
9 changes: 8 additions & 1 deletion fs_mgr/libsnapshot/snapshot_stats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 9 additions & 1 deletion fs_mgr/libsnapshot/snapshot_stub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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

0 comments on commit e00a567

Please sign in to comment.