libsnapshot: OTA upgrade when vendor partition is S

In Android S, snapuserd binary was on vendor partition.
When there is an OTA update from S -> T, it is possible
that vendor partitions are not updated. In that case,
successive OTA updates T1 -> T2 will continue to have
snapuserd from Android S as vendor partition wasn't updated
to T. All this means, we should disable user-space snapshots.

When installing OTA during runtime, check for property
ro.vendor.build.version.release_or_codename; if the property
is set to "12", then skip userspace-snapshots.

Bug: 227614163

Test: Simulate OTA test on Pixel 6 from T1 -> T2 by forcefully
setting the property to 12 and verify OTA is applied
successfully by falling back to dm-snapshot.

Signed-off-by: Akilesh Kailash <akailash@google.com>
Change-Id: I95f29145e5cd9ffb8d03d28ae414f0037b88be90
This commit is contained in:
Akilesh Kailash 2022-04-02 04:54:26 +00:00
parent 6948bbf62c
commit 9fc6ee050f
3 changed files with 27 additions and 6 deletions

View File

@ -3205,15 +3205,27 @@ Return SnapshotManager::CreateUpdateSnapshots(const DeltaArchiveManifest& manife
status.set_compression_enabled(cow_creator.compression_enabled);
if (cow_creator.compression_enabled) {
if (!device()->IsTestDevice()) {
bool userSnapshotsEnabled = IsUserspaceSnapshotsEnabled();
const std::string UNKNOWN = "unknown";
const std::string vendor_release = android::base::GetProperty(
"ro.vendor.build.version.release_or_codename", UNKNOWN);
// 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;
userSnapshotsEnabled = false;
}
// Userspace snapshots is enabled only if compression is enabled
status.set_userspace_snapshots(IsUserspaceSnapshotsEnabled());
if (IsUserspaceSnapshotsEnabled()) {
status.set_userspace_snapshots(userSnapshotsEnabled);
if (userSnapshotsEnabled) {
is_snapshot_userspace_ = true;
status.set_io_uring_enabled(IsIouringEnabled());
LOG(INFO) << "User-space snapshots enabled";
LOG(INFO) << "Userspace snapshots enabled";
} else {
is_snapshot_userspace_ = false;
LOG(INFO) << "User-space snapshots disabled";
LOG(INFO) << "Userspace snapshots disabled";
}
// Terminate stale daemon if any

View File

@ -932,7 +932,6 @@ void CowSnapuserdMetadataTest::ValidatePartialFilledArea() {
ASSERT_EQ(area_sz, 2);
size_t new_chunk = 263;
// Verify the partially filled area
void* buffer = snapuserd_->GetExceptionBuffer(1);
loff_t offset = 0;
@ -941,7 +940,6 @@ void CowSnapuserdMetadataTest::ValidatePartialFilledArea() {
de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);
ASSERT_EQ(de->old_chunk, i);
offset += sizeof(struct disk_exception);
new_chunk += 1;
}
de = reinterpret_cast<struct disk_exception*>((char*)buffer + offset);

View File

@ -34,6 +34,17 @@ namespace android {
namespace snapshot {
bool Daemon::IsUserspaceSnapshotsEnabled() {
const std::string UNKNOWN = "unknown";
const std::string vendor_release =
android::base::GetProperty("ro.vendor.build.version.release_or_codename", UNKNOWN);
// 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 false;
}
return android::base::GetBoolProperty("ro.virtual_ab.userspace.snapshots.enabled", false);
}