Loading fs_mgr/libsnapshot/include/libsnapshot/snapshot.h +4 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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); Loading fs_mgr/libsnapshot/snapshot.cpp +31 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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); Loading Loading @@ -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"; } Loading Loading @@ -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. * Loading Loading @@ -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; } } Loading init/first_stage_mount.cpp +1 −6 Original line number Diff line number Diff line Loading @@ -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 { Loading init/snapuserd_transition.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
fs_mgr/libsnapshot/include/libsnapshot/snapshot.h +4 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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); Loading
fs_mgr/libsnapshot/snapshot.cpp +31 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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); Loading Loading @@ -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"; } Loading Loading @@ -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. * Loading Loading @@ -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; } } Loading
init/first_stage_mount.cpp +1 −6 Original line number Diff line number Diff line Loading @@ -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 { Loading
init/snapuserd_transition.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -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); Loading