Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1bbf8f04 authored by Akilesh Kailash's avatar Akilesh Kailash
Browse files

libsnapshot: Check if the vendor is updated from Android S for GRF



In a GRF config, if Vendor partition is updated from Android 12; post
OTA reboot, first stage init will communicate to daemon to check if the
daemon can support socket handoff. If that succeeds, then it is a signal
that the vendor has been updated from Android 12. Use a marker in
/metadata to signal that the vendor was updated. If the marker is present,
then post OTA reboot, userspace snapshot will be used.

Bug: 333854394
Test: OTA
Android U (system) + S (vendor) -> Android V (system) + V (Vendor)

Change-Id: Ie38c4379010789a84e5b44529b407f9f82135271
Signed-off-by: default avatarAkilesh Kailash <akailash@google.com>
parent 116a7133
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -335,6 +335,9 @@ class SnapshotManager final : public ISnapshotManager {
    // after loading selinux policy.
    bool PrepareSnapuserdArgsForSelinux(std::vector<std::string>* snapuserd_argv);

    // If snapuserd from first stage init was started from system partition.
    bool MarkSnapuserdFromSystem();

    // Detach dm-user devices from the first stage snapuserd. Load
    // new dm-user tables after loading selinux policy.
    bool DetachFirstStageSnapuserdForSelinux();
@@ -670,6 +673,7 @@ class SnapshotManager final : public ISnapshotManager {
    std::string GetForwardMergeIndicatorPath();
    std::string GetOldPartitionMetadataPath();
    std::string GetBootSnapshotsWithoutSlotSwitchPath();
    std::string GetSnapuserdFromSystemPath();

    const LpMetadata* ReadOldPartitionMetadata(LockedFile* lock);

+31 −1
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ static constexpr char kBootSnapshotsWithoutSlotSwitch[] =
        "/metadata/ota/snapshot-boot-without-slot-switch";
static constexpr char kBootIndicatorPath[] = "/metadata/ota/snapshot-boot";
static constexpr char kRollbackIndicatorPath[] = "/metadata/ota/rollback-indicator";
static constexpr char kSnapuserdFromSystem[] = "/metadata/ota/snapuserd-from-system";
static constexpr auto kUpdateStateCheckInterval = 2s;
/*
 * The readahead size is set to 32kb so that
@@ -318,7 +319,7 @@ bool SnapshotManager::RemoveAllUpdateState(LockedFile* lock, const std::function
    std::vector<std::string> files = {
            GetSnapshotBootIndicatorPath(),          GetRollbackIndicatorPath(),
            GetForwardMergeIndicatorPath(),          GetOldPartitionMetadataPath(),
            GetBootSnapshotsWithoutSlotSwitchPath(),
            GetBootSnapshotsWithoutSlotSwitchPath(), GetSnapuserdFromSystemPath(),
    };
    for (const auto& file : files) {
        RemoveFileIfExists(file);
@@ -1457,6 +1458,10 @@ std::string SnapshotManager::GetRollbackIndicatorPath() {
    return metadata_dir_ + "/" + android::base::Basename(kRollbackIndicatorPath);
}

std::string SnapshotManager::GetSnapuserdFromSystemPath() {
    return metadata_dir_ + "/" + android::base::Basename(kSnapuserdFromSystem);
}

std::string SnapshotManager::GetForwardMergeIndicatorPath() {
    return metadata_dir_ + "/allow-forward-merge";
}
@@ -2122,6 +2127,16 @@ bool SnapshotManager::UpdateUsesODirect(LockedFile* lock) {
    return update_status.o_direct();
}

bool SnapshotManager::MarkSnapuserdFromSystem() {
    auto path = GetSnapuserdFromSystemPath();

    if (!android::base::WriteStringToFile("1", path)) {
        PLOG(ERROR) << "Unable to write to vendor update path: " << path;
        return false;
    }
    return true;
}

/*
 * Please see b/304829384 for more details.
 *
@@ -2158,11 +2173,26 @@ bool SnapshotManager::UpdateUsesODirect(LockedFile* lock) {
 *         iii: If both (i) and (ii) are true, then use the dm-snapshot based
 *         approach.
 *
 * 3: Post OTA reboot, if the vendor partition was updated from Android 12 to
 * any other release post Android 12, then snapuserd binary will be "system"
 * partition as post Android 12, init_boot will contain a copy of snapuserd
 * binary. Thus, during first stage init, if init is able to communicate to
 * daemon, that gives us a signal that the binary is from "system" copy. Hence,
 * there is no need to fallback to legacy dm-snapshot. Thus, init will use a
 * marker in /metadata to signal that the snapuserd binary from first stage init
 * can handle userspace snapshots.
 *
 */
bool SnapshotManager::IsLegacySnapuserdPostReboot() {
    if (is_legacy_snapuserd_.has_value() && is_legacy_snapuserd_.value() == true) {
        auto slot = GetCurrentSlot();
        if (slot == Slot::Target) {
            // If this marker is present, then daemon can handle userspace
            // snapshots; also, it indicates that the vendor partition was
            // updated from Android 12.
            if (access(GetSnapuserdFromSystemPath().c_str(), F_OK) == 0) {
                return false;
            }
            return true;
        }
    }
+1 −6
Original line number Diff line number Diff line
@@ -395,12 +395,7 @@ bool FirstStageMountVBootV2::CreateSnapshotPartitions(SnapshotManager* sm) {

    use_snapuserd_ = sm->IsSnapuserdRequired();
    if (use_snapuserd_) {
        if (sm->UpdateUsesUserSnapshots()) {
        LaunchFirstStageSnapuserd();
        } else {
            LOG(FATAL) << "legacy virtual-ab is no longer supported";
            return false;
        }
    }

    sm->SetUeventRegenCallback([this](const std::string& device) -> bool {
+4 −0
Original line number Diff line number Diff line
@@ -100,6 +100,10 @@ void LaunchFirstStageSnapuserd() {
    }
    if (client->SupportsSecondStageSocketHandoff()) {
        setenv(kSnapuserdFirstStageInfoVar, "socket", 1);
        auto sm = SnapshotManager::NewForFirstStageMount();
        if (!sm->MarkSnapuserdFromSystem()) {
            LOG(ERROR) << "Failed to update MarkSnapuserdFromSystem";
        }
    }

    setenv(kSnapuserdFirstStagePidVar, std::to_string(pid).c_str(), 1);