libsnapshot: Prepare removal of legacy snapshot
During OTA install, when vendor partition is on Android S, add a new flag in SnapshotUpdateStatus file to indicate that we need to support dm-snapshot based snapshot process. This will be used only during post OTA reboot. The primary change here is the OTA install path. Earlier, dm-snapshot based approach was used; with this change, since both "snapuserd" and "update-engine" resides on system partition, OTA installation will use the userspace snapshot approach. To maintain backward compatibility, the new flag "legacy_snapuserd" is used only after OTA reboot. This flag will make sure that update-engine will take the dm-snapshot based approach post reboot and for the entire duration of snapshot-merge. Additionally, during first-stage init if the vendor is on Android S, then "snapuserd" binary will continue to work based off dm-snapshot as none of this change will impact the mount process. Bug: 304829384 Test: OTA on Pixel th - OTA from Android S to TOT with vendor on S Change-Id: Idd9a60b09417cee141b2810e2d4b35e91c845a5c Signed-off-by: Akilesh Kailash <akailash@google.com>
This commit is contained in:
parent
4df565db4c
commit
25eabc44f5
5 changed files with 88 additions and 13 deletions
|
|
@ -212,6 +212,9 @@ message SnapshotUpdateStatus {
|
|||
|
||||
// io_uring support
|
||||
bool io_uring_enabled = 10;
|
||||
|
||||
// legacy dm-snapshot based snapuserd
|
||||
bool legacy_snapuserd = 11;
|
||||
}
|
||||
|
||||
// Next: 10
|
||||
|
|
|
|||
|
|
@ -829,6 +829,9 @@ class SnapshotManager final : public ISnapshotManager {
|
|||
// Set read-ahead size during OTA
|
||||
void SetReadAheadSize(const std::string& entry_block_device, off64_t size_kb);
|
||||
|
||||
// Returns true post OTA reboot if legacy snapuserd is required
|
||||
bool IsLegacySnapuserdPostReboot();
|
||||
|
||||
android::dm::IDeviceMapper& dm_;
|
||||
std::unique_ptr<IDeviceInfo> device_;
|
||||
std::string metadata_dir_;
|
||||
|
|
@ -839,6 +842,7 @@ class SnapshotManager final : public ISnapshotManager {
|
|||
std::unique_ptr<SnapuserdClient> snapuserd_client_;
|
||||
std::unique_ptr<LpMetadata> old_partition_metadata_;
|
||||
std::optional<bool> is_snapshot_userspace_;
|
||||
std::optional<bool> is_legacy_snapuserd_;
|
||||
};
|
||||
|
||||
} // namespace snapshot
|
||||
|
|
|
|||
|
|
@ -265,7 +265,6 @@ std::string SnapshotManager::ReadUpdateSourceSlotSuffix() {
|
|||
auto boot_file = GetSnapshotBootIndicatorPath();
|
||||
std::string contents;
|
||||
if (!android::base::ReadFileToString(boot_file, &contents)) {
|
||||
PLOG(WARNING) << "Cannot read " << boot_file;
|
||||
return {};
|
||||
}
|
||||
return contents;
|
||||
|
|
@ -2118,6 +2117,53 @@ bool SnapshotManager::UpdateUsesIouring(LockedFile* lock) {
|
|||
return update_status.io_uring_enabled();
|
||||
}
|
||||
|
||||
/*
|
||||
* Please see b/304829384 for more details.
|
||||
*
|
||||
* In Android S, we use dm-snapshot for mounting snapshots and snapshot-merge
|
||||
* process. If the vendor partition continues to be on Android S, then
|
||||
* "snapuserd" binary in first stage ramdisk will be from vendor partition.
|
||||
* Thus, we need to maintain backward compatibility.
|
||||
*
|
||||
* Now, We take a two step approach to maintain the backward compatibility:
|
||||
*
|
||||
* 1: During OTA installation, we will continue to use "user-space" snapshots
|
||||
* for OTA installation as both update-engine and snapuserd binary will be from system partition.
|
||||
* However, during installation, we mark "legacy_snapuserd" in
|
||||
* SnapshotUpdateStatus file to mark that this is a path to support backward compatibility.
|
||||
* Thus, this function will return "false" during OTA installation.
|
||||
*
|
||||
* 2: Post OTA reboot, there are two key steps:
|
||||
* a: During first stage init, "init" and "snapuserd" could be from vendor
|
||||
* partition. This could be from Android S. Thus, the snapshot mount path
|
||||
* will be based off dm-snapshot.
|
||||
*
|
||||
* b: Post selinux transition, "init" and "update-engine" will be "system"
|
||||
* partition. Now, since the snapshots are mounted off dm-snapshot,
|
||||
* update-engine interaction with "snapuserd" should work based off
|
||||
* dm-snapshots.
|
||||
*
|
||||
* TL;DR: update-engine will use the "system" snapuserd for installing new
|
||||
* updates (this is safe as there is no "vendor" snapuserd running during
|
||||
* installation). Post reboot, update-engine will use the legacy path when
|
||||
* communicating with "vendor" snapuserd that was started in first-stage
|
||||
* init. Hence, this function checks:
|
||||
* i: Are we in post OTA reboot
|
||||
* ii: Is the Vendor from Android 12
|
||||
* iii: If both (i) and (ii) are true, then use the dm-snapshot based
|
||||
* approach.
|
||||
*
|
||||
*/
|
||||
bool SnapshotManager::IsLegacySnapuserdPostReboot() {
|
||||
if (is_legacy_snapuserd_.has_value() && is_legacy_snapuserd_.value() == true) {
|
||||
auto slot = GetCurrentSlot();
|
||||
if (slot == Slot::Target) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SnapshotManager::UpdateUsesUserSnapshots() {
|
||||
// This and the following function is constantly
|
||||
// invoked during snapshot merge. We want to avoid
|
||||
|
|
@ -2129,7 +2175,12 @@ bool SnapshotManager::UpdateUsesUserSnapshots() {
|
|||
// during merge phase. Hence, once we know that
|
||||
// the value is read from disk the very first time,
|
||||
// it is safe to read successive checks from memory.
|
||||
|
||||
if (is_snapshot_userspace_.has_value()) {
|
||||
// Check if legacy snapuserd is running post OTA reboot
|
||||
if (IsLegacySnapuserdPostReboot()) {
|
||||
return false;
|
||||
}
|
||||
return is_snapshot_userspace_.value();
|
||||
}
|
||||
|
||||
|
|
@ -2140,13 +2191,16 @@ bool SnapshotManager::UpdateUsesUserSnapshots() {
|
|||
}
|
||||
|
||||
bool SnapshotManager::UpdateUsesUserSnapshots(LockedFile* lock) {
|
||||
// See UpdateUsesUserSnapshots()
|
||||
if (is_snapshot_userspace_.has_value()) {
|
||||
return is_snapshot_userspace_.value();
|
||||
if (!is_snapshot_userspace_.has_value()) {
|
||||
SnapshotUpdateStatus update_status = ReadSnapshotUpdateStatus(lock);
|
||||
is_snapshot_userspace_ = update_status.userspace_snapshots();
|
||||
is_legacy_snapuserd_ = update_status.legacy_snapuserd();
|
||||
}
|
||||
|
||||
if (IsLegacySnapuserdPostReboot()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SnapshotUpdateStatus update_status = ReadSnapshotUpdateStatus(lock);
|
||||
is_snapshot_userspace_ = update_status.userspace_snapshots();
|
||||
return is_snapshot_userspace_.value();
|
||||
}
|
||||
|
||||
|
|
@ -3210,6 +3264,8 @@ Return SnapshotManager::CreateUpdateSnapshots(const DeltaArchiveManifest& manife
|
|||
// Deduce supported features.
|
||||
bool userspace_snapshots = CanUseUserspaceSnapshots();
|
||||
bool legacy_compression = GetLegacyCompressionEnabledProperty();
|
||||
bool is_legacy_snapuserd = IsVendorFromAndroid12();
|
||||
|
||||
if (!vabc_disable_reason.empty()) {
|
||||
if (userspace_snapshots) {
|
||||
LOG(INFO) << "Userspace snapshots disabled: " << vabc_disable_reason;
|
||||
|
|
@ -3219,6 +3275,7 @@ Return SnapshotManager::CreateUpdateSnapshots(const DeltaArchiveManifest& manife
|
|||
}
|
||||
userspace_snapshots = false;
|
||||
legacy_compression = false;
|
||||
is_legacy_snapuserd = false;
|
||||
}
|
||||
|
||||
if (legacy_compression || userspace_snapshots) {
|
||||
|
|
@ -3231,6 +3288,8 @@ Return SnapshotManager::CreateUpdateSnapshots(const DeltaArchiveManifest& manife
|
|||
}
|
||||
}
|
||||
|
||||
LOG(INFO) << "userspace snapshots: " << userspace_snapshots
|
||||
<< " legacy_snapuserd: " << legacy_compression;
|
||||
const bool using_snapuserd = userspace_snapshots || legacy_compression;
|
||||
if (!using_snapuserd) {
|
||||
LOG(INFO) << "Using legacy Virtual A/B (dm-snapshot)";
|
||||
|
|
@ -3328,6 +3387,10 @@ Return SnapshotManager::CreateUpdateSnapshots(const DeltaArchiveManifest& manife
|
|||
status.set_io_uring_enabled(true);
|
||||
LOG(INFO) << "io_uring for snapshots enabled";
|
||||
}
|
||||
|
||||
if (is_legacy_snapuserd) {
|
||||
status.set_legacy_snapuserd(true);
|
||||
}
|
||||
} else if (legacy_compression) {
|
||||
LOG(INFO) << "Virtual A/B using legacy snapuserd";
|
||||
} else {
|
||||
|
|
@ -3335,6 +3398,7 @@ Return SnapshotManager::CreateUpdateSnapshots(const DeltaArchiveManifest& manife
|
|||
}
|
||||
|
||||
is_snapshot_userspace_.emplace(userspace_snapshots);
|
||||
is_legacy_snapuserd_.emplace(is_legacy_snapuserd);
|
||||
|
||||
if (!device()->IsTestDevice() && using_snapuserd) {
|
||||
// Terminate stale daemon if any
|
||||
|
|
|
|||
|
|
@ -230,11 +230,7 @@ bool GetUserspaceSnapshotsEnabledProperty() {
|
|||
return fetcher->GetBoolProperty("ro.virtual_ab.userspace.snapshots.enabled", false);
|
||||
}
|
||||
|
||||
bool CanUseUserspaceSnapshots() {
|
||||
if (!GetUserspaceSnapshotsEnabledProperty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsVendorFromAndroid12() {
|
||||
auto fetcher = IPropertyFetcher::GetInstance();
|
||||
|
||||
const std::string UNKNOWN = "unknown";
|
||||
|
|
@ -243,8 +239,15 @@ bool CanUseUserspaceSnapshots() {
|
|||
|
||||
// No user-space snapshots if vendor partition is on Android 12
|
||||
if (vendor_release.find("12") != std::string::npos) {
|
||||
LOG(INFO) << "Userspace snapshots disabled as vendor partition is on Android: "
|
||||
<< vendor_release;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CanUseUserspaceSnapshots() {
|
||||
if (!GetUserspaceSnapshotsEnabledProperty()) {
|
||||
LOG(INFO) << "Virtual A/B - Userspace snapshots disabled";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ bool GetXorCompressionEnabledProperty();
|
|||
|
||||
bool CanUseUserspaceSnapshots();
|
||||
bool IsDmSnapshotTestingEnabled();
|
||||
bool IsVendorFromAndroid12();
|
||||
|
||||
// Swap the suffix of a partition name.
|
||||
std::string GetOtherPartitionName(const std::string& name);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue