Load boot image props.
This change does the following:
- Create /second_stage_resources empty dir at root.
- At runtime:
- At first stage init:
- mount tmpfs to /second_stage_resources.
- Copy /system/etc/ramdisk/build.prop to
/second_stage_resources/system/etc/ramdisk/build.prop
- At second stage init:
- Load prop from the above path
- umount /second_stage_resources
Test: getprop -Z
Test: getprop
Bug: 169169031
Change-Id: I18b16aa5fd42fa44686c858982a17791b2d43489
diff --git a/init/Android.mk b/init/Android.mk
index da94daf..7d7c827 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -80,6 +80,7 @@
$(TARGET_RAMDISK_OUT)/dev \
$(TARGET_RAMDISK_OUT)/mnt \
$(TARGET_RAMDISK_OUT)/proc \
+ $(TARGET_RAMDISK_OUT)/second_stage_resources \
$(TARGET_RAMDISK_OUT)/sys \
LOCAL_STATIC_LIBRARIES := \
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index 0215576..554f301 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -41,6 +41,7 @@
#include "first_stage_console.h"
#include "first_stage_mount.h"
#include "reboot_utils.h"
+#include "second_stage_resources.h"
#include "switch_root.h"
#include "util.h"
@@ -235,6 +236,11 @@
// /debug_ramdisk is used to preserve additional files from the debug ramdisk
CHECKCALL(mount("tmpfs", "/debug_ramdisk", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
"mode=0755,uid=0,gid=0"));
+
+ // /second_stage_resources is used to preserve files from first to second
+ // stage init
+ CHECKCALL(mount("tmpfs", kSecondStageRes, "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
+ "mode=0755,uid=0,gid=0"))
#undef CHECKCALL
SetStdioToDevNull(argv);
@@ -276,6 +282,20 @@
StartConsole();
}
+ if (access(kBootImageRamdiskProp, F_OK) == 0) {
+ std::string dest = GetRamdiskPropForSecondStage();
+ std::string dir = android::base::Dirname(dest);
+ std::error_code ec;
+ if (!fs::create_directories(dir, ec)) {
+ LOG(FATAL) << "Can't mkdir " << dir << ": " << ec.message();
+ }
+ if (!fs::copy_file(kBootImageRamdiskProp, dest, ec)) {
+ LOG(FATAL) << "Can't copy " << kBootImageRamdiskProp << " to " << dest << ": "
+ << ec.message();
+ }
+ LOG(INFO) << "Copied ramdisk prop to " << dest;
+ }
+
if (ForceNormalBoot(cmdline)) {
mkdir("/first_stage_ramdisk", 0755);
// SwitchRoot() must be called with a mount point as the target, so we bind mount the
diff --git a/init/init.cpp b/init/init.cpp
index 7d00538..ea04494 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -71,6 +71,7 @@
#include "proto_utils.h"
#include "reboot.h"
#include "reboot_utils.h"
+#include "second_stage_resources.h"
#include "security.h"
#include "selabel.h"
#include "selinux.h"
@@ -668,6 +669,12 @@
}
}
+static void UmountSecondStageRes() {
+ if (umount(kSecondStageRes) != 0) {
+ PLOG(ERROR) << "Failed to umount " << kSecondStageRes;
+ }
+}
+
static void MountExtraFilesystems() {
#define CHECKCALL(x) \
if ((x) != 0) PLOG(FATAL) << #x " failed.";
@@ -776,6 +783,9 @@
PropertyInit();
+ // Umount second stage resources after property service has read the .prop files.
+ UmountSecondStageRes();
+
// Umount the debug ramdisk after property service has read the .prop files when it means to.
if (load_debug_prop) {
UmountDebugRamdisk();
diff --git a/init/property_service.cpp b/init/property_service.cpp
index a1e0969..e4c9802 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -67,6 +67,7 @@
#include "persistent_properties.h"
#include "property_type.h"
#include "proto_utils.h"
+#include "second_stage_resources.h"
#include "selinux.h"
#include "subcontext.h"
#include "system/core/init/property_service.pb.h"
@@ -745,6 +746,15 @@
return true;
}
+static void LoadPropertiesFromSecondStageRes(std::map<std::string, std::string>* properties) {
+ std::string prop = GetRamdiskPropForSecondStage();
+ if (access(prop.c_str(), R_OK) != 0) {
+ CHECK(errno == ENOENT) << "Cannot access " << prop << ": " << strerror(errno);
+ return;
+ }
+ load_properties_from_file(prop.c_str(), nullptr, properties);
+}
+
// persist.sys.usb.config values can't be combined on build-time when property
// files are split into each partition.
// So we need to apply the same rule of build/make/tools/post_process_props.py
@@ -933,6 +943,7 @@
// Order matters here. The more the partition is specific to a product, the higher its
// precedence is.
+ LoadPropertiesFromSecondStageRes(&properties);
load_properties_from_file("/system/build.prop", nullptr, &properties);
load_properties_from_partition("system_ext", /* support_legacy_path_until */ 30);
// TODO(b/117892318): uncomment the following condition when vendor.imgs for aosp_* targets are
diff --git a/init/second_stage_resources.h b/init/second_stage_resources.h
new file mode 100644
index 0000000..544d16f
--- /dev/null
+++ b/init/second_stage_resources.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <string>
+
+namespace android {
+namespace init {
+
+constexpr const char kSecondStageRes[] = "/second_stage_resources";
+constexpr const char kBootImageRamdiskProp[] = "/system/etc/ramdisk/build.prop";
+
+inline std::string GetRamdiskPropForSecondStage() {
+ return std::string(kSecondStageRes) + kBootImageRamdiskProp;
+}
+
+} // namespace init
+} // namespace android
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 77fa94e..2bceb75 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -78,7 +78,7 @@
# create some directories (some are mount points) and symlinks
LOCAL_POST_INSTALL_CMD := mkdir -p $(addprefix $(TARGET_ROOT_OUT)/, \
dev proc sys system data data_mirror odm oem acct config storage mnt apex debug_ramdisk \
- linkerconfig $(BOARD_ROOT_EXTRA_FOLDERS)); \
+ linkerconfig second_stage_resources $(BOARD_ROOT_EXTRA_FOLDERS)); \
ln -sf /system/bin $(TARGET_ROOT_OUT)/bin; \
ln -sf /system/etc $(TARGET_ROOT_OUT)/etc; \
ln -sf /data/user_de/0/com.android.shell/files/bugreports $(TARGET_ROOT_OUT)/bugreports; \