Copy snapuserd to first_stage_ramdisk
Certain binaries, such as snapuserd, are only available under /system/bin. To make them accessible by first stage init, we copy /system/bin/snapuserd to /first_stage_ramdisk/system/bin/snapuserd . Test: th Bug: 219841787 Change-Id: I913425a82905c745a05ac32d488f08506dc264ff
This commit is contained in:
parent
1821237a1e
commit
22929da287
2 changed files with 39 additions and 4 deletions
|
@ -27,6 +27,7 @@
|
|||
#include <sys/utsname.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -107,6 +108,39 @@ bool ForceNormalBoot(const std::string& cmdline, const std::string& bootconfig)
|
|||
cmdline.find("androidboot.force_normal_boot=1") != std::string::npos;
|
||||
}
|
||||
|
||||
static void Copy(const char* src, const char* dst) {
|
||||
if (link(src, dst) == 0) {
|
||||
LOG(INFO) << "hard linking " << src << " to " << dst << " succeeded";
|
||||
return;
|
||||
}
|
||||
PLOG(FATAL) << "hard linking " << src << " to " << dst << " failed, falling back to copy.";
|
||||
}
|
||||
|
||||
// Move e2fsck before switching root, so that it is available at the same path
|
||||
// after switching root.
|
||||
void PrepareSwitchRoot() {
|
||||
constexpr const char* src = "/system/bin/snapuserd";
|
||||
constexpr const char* dst = "/first_stage_ramdisk/system/bin/snapuserd";
|
||||
|
||||
if (access(dst, X_OK) == 0) {
|
||||
LOG(INFO) << dst << " already exists and it can be executed";
|
||||
return;
|
||||
}
|
||||
|
||||
if (access(src, F_OK) != 0) {
|
||||
PLOG(INFO) << "Not moving " << src << " because it cannot be accessed";
|
||||
return;
|
||||
}
|
||||
|
||||
auto dst_dir = android::base::Dirname(dst);
|
||||
std::error_code ec;
|
||||
if (access(dst_dir.c_str(), F_OK) != 0) {
|
||||
if (!fs::create_directories(dst_dir, ec)) {
|
||||
LOG(FATAL) << "Cannot create " << dst_dir << ": " << ec.message();
|
||||
}
|
||||
}
|
||||
Copy(src, dst);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::string GetModuleLoadList(bool recovery, const std::string& dir_path) {
|
||||
|
@ -304,12 +338,11 @@ int FirstStageMain(int argc, char** argv) {
|
|||
<< module_elapse_time.count() << " ms";
|
||||
}
|
||||
|
||||
|
||||
bool created_devices = false;
|
||||
if (want_console == FirstStageConsoleParam::CONSOLE_ON_FAILURE) {
|
||||
if (!IsRecoveryMode()) {
|
||||
created_devices = DoCreateDevices();
|
||||
if (!created_devices){
|
||||
if (!created_devices) {
|
||||
LOG(ERROR) << "Failed to create device nodes early";
|
||||
}
|
||||
}
|
||||
|
@ -352,10 +385,11 @@ int FirstStageMain(int argc, char** argv) {
|
|||
|
||||
if (ForceNormalBoot(cmdline, bootconfig)) {
|
||||
mkdir("/first_stage_ramdisk", 0755);
|
||||
PrepareSwitchRoot();
|
||||
// SwitchRoot() must be called with a mount point as the target, so we bind mount the
|
||||
// target directory to itself here.
|
||||
if (mount("/first_stage_ramdisk", "/first_stage_ramdisk", nullptr, MS_BIND, nullptr) != 0) {
|
||||
LOG(FATAL) << "Could not bind mount /first_stage_ramdisk to itself";
|
||||
PLOG(FATAL) << "Could not bind mount /first_stage_ramdisk to itself";
|
||||
}
|
||||
SwitchRoot("/first_stage_ramdisk");
|
||||
}
|
||||
|
|
|
@ -78,7 +78,8 @@ void SwitchRoot(const std::string& new_root) {
|
|||
auto new_mount_path = new_root + mount_path;
|
||||
mkdir(new_mount_path.c_str(), 0755);
|
||||
if (mount(mount_path.c_str(), new_mount_path.c_str(), nullptr, MS_MOVE, nullptr) != 0) {
|
||||
PLOG(FATAL) << "Unable to move mount at '" << mount_path << "'";
|
||||
PLOG(FATAL) << "Unable to move mount at '" << mount_path << "' to "
|
||||
<< "'" << new_mount_path << "'";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue