libsnapshot: Remove invalid snapshot metadata

If there are snapshot metadata persisting in /metadata/ota/snapshots,
remove them before applying a new update. Make sure that
the snapshots are indeed invalid before removing them.

On a sidenote, add a comment in init.cpp related to
b/223076262.

Bug: 228250473
Test: 1: Apply OTA in recovery through adb sideload
2: Reboot
3: Apply OTA OTA again through update_device.py
4: Re-run Full OTA updates just from update_device.py

Signed-off-by: Akilesh Kailash <akailash@google.com>
Change-Id: I116bbafae09042b9c391ccd58c102704571c214e
This commit is contained in:
Akilesh Kailash 2022-04-12 21:59:05 +00:00
parent 4691a163c1
commit f86fca236f
3 changed files with 38 additions and 1 deletions

View file

@ -538,6 +538,9 @@ class SnapshotManager final : public ISnapshotManager {
// Unmap a COW and remove it from a MetadataBuilder.
void UnmapAndDeleteCowPartition(MetadataBuilder* current_metadata);
// Remove invalid snapshots if any
void RemoveInvalidSnapshots(LockedFile* lock);
// Unmap and remove all known snapshots.
bool RemoveAllSnapshots(LockedFile* lock);

View file

@ -218,7 +218,10 @@ bool SnapshotManager::TryCancelUpdate(bool* needs_merge) {
if (!file) return false;
UpdateState state = ReadUpdateState(file.get());
if (state == UpdateState::None) return true;
if (state == UpdateState::None) {
RemoveInvalidSnapshots(file.get());
return true;
}
if (state == UpdateState::Initiated) {
LOG(INFO) << "Update has been initiated, now canceling";
@ -1903,6 +1906,33 @@ bool SnapshotManager::GetSnapshotFlashingStatus(LockedFile* lock,
return true;
}
void SnapshotManager::RemoveInvalidSnapshots(LockedFile* lock) {
std::vector<std::string> snapshots;
// Remove the stale snapshot metadata
//
// We make sure that all the three cases
// are valid before removing the snapshot metadata:
//
// 1: dm state is active
// 2: Root fs is not mounted off as a snapshot device
// 3: Snapshot slot suffix should match current device slot
if (!ListSnapshots(lock, &snapshots, device_->GetSlotSuffix()) || snapshots.empty()) {
return;
}
// We indeed have some invalid snapshots
for (const auto& name : snapshots) {
if (dm_.GetState(name) == DmDeviceState::ACTIVE && !IsSnapshotDevice(name)) {
if (!DeleteSnapshot(lock, name)) {
LOG(ERROR) << "Failed to delete invalid snapshot: " << name;
} else {
LOG(INFO) << "Invalid snapshot: " << name << " deleted";
}
}
}
}
bool SnapshotManager::RemoveAllSnapshots(LockedFile* lock) {
std::vector<std::string> snapshots;
if (!ListSnapshots(lock, &snapshots)) {

View file

@ -795,6 +795,10 @@ int SecondStageMain(int argc, char** argv) {
InstallRebootSignalHandlers();
}
// No threads should be spin up until signalfd
// is registered. If the threads are indeed required,
// each of these threads _should_ make sure SIGCHLD signal
// is blocked. See b/223076262
boot_clock::time_point start_time = boot_clock::now();
trigger_shutdown = [](const std::string& command) { shutdown_state.TriggerShutdown(command); };