Merge cherrypicks of ['android-review.googlesource.com/3141899', 'android-review.googlesource.com/3155338'] into 24Q3-release.

Change-Id: I12068e95fbbcca8e45c927b6ad965d46a6127c68
This commit is contained in:
Android Build Coastguard Worker 2024-09-19 18:41:17 +00:00
commit 32bd7a7dd5
4 changed files with 70 additions and 10 deletions

View file

@ -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);

View file

@ -20,6 +20,7 @@
#include <sys/file.h>
#include <sys/types.h>
#include <sys/unistd.h>
#include <sys/xattr.h>
#include <filesystem>
#include <optional>
@ -88,7 +89,10 @@ 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;
static constexpr char kOtaFileContext[] = "u:object_r:ota_metadata_file:s0";
/*
* The readahead size is set to 32kb so that
* there is no significant memory pressure (/proc/pressure/memory) during boot.
@ -318,7 +322,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 +1461,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 +2130,34 @@ 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;
}
unique_fd fd(open(path.c_str(), O_PATH));
if (fd < 0) {
PLOG(ERROR) << "Failed to open file: " << path;
return false;
}
/*
* This function is invoked by first stage init and hence we need to
* explicitly set the correct selinux label for this file as update_engine
* will try to remove this file later on once the snapshot merge is
* complete.
*/
if (fsetxattr(fd.get(), XATTR_NAME_SELINUX, kOtaFileContext, strlen(kOtaFileContext) + 1, 0) <
0) {
PLOG(ERROR) << "fsetxattr for the path: " << path << " failed";
}
return true;
}
/*
* Please see b/304829384 for more details.
*
@ -2158,14 +2194,35 @@ 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) {
auto slot = GetCurrentSlot();
if (slot == Slot::Target) {
/*
If this marker is present, the daemon can handle userspace snapshots.
During post-OTA reboot, this implies that the vendor partition is
Android 13 or higher. If the snapshots were created on an
Android 12 vendor, this means the vendor partition has been updated.
*/
if (access(GetSnapuserdFromSystemPath().c_str(), F_OK) == 0) {
is_snapshot_userspace_ = true;
return false;
}
// If the marker isn't present and if the vendor is still in Android 12
if (is_legacy_snapuserd_.has_value() && is_legacy_snapuserd_.value() == true) {
return true;
}
}
return false;
}

View file

@ -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;
}
LaunchFirstStageSnapuserd();
}
sm->SetUeventRegenCallback([this](const std::string& device) -> bool {

View file

@ -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);