init: Unify duplicated get_android_dt_dir with libfs_mgr
init and libfs_mgr both defines get_android_dt_dir() with subtle
differences. Merge the two implementations into libfs_mgr to reduce code
duplication (in terms of source code and code gen)
Note:
init's implementation checks the kernel cmdline first and then the
kernel bootconfig, while libfs_mgr's order is the opposite.
Realistically I don't think this order matter much though. If any, we
should prioritize bootconfig over kernel cmdline most of the time.
Bug: 293695109
Test: Presubmit
Merged-In: Ic8d2c965c62f9e873ccdaf77d67c7708f25a7b56
Change-Id: Ic8d2c965c62f9e873ccdaf77d67c7708f25a7b56
diff --git a/fs_mgr/libfstab/boot_config.cpp b/fs_mgr/libfstab/boot_config.cpp
index 8fb28c6..fee4015 100644
--- a/fs_mgr/libfstab/boot_config.cpp
+++ b/fs_mgr/libfstab/boot_config.cpp
@@ -27,6 +27,33 @@
#include "fstab_priv.h"
#include "logging_macros.h"
+namespace android {
+namespace fs_mgr {
+
+const std::string& GetAndroidDtDir() {
+ // Set once and saves time for subsequent calls to this function
+ static const std::string kAndroidDtDir = [] {
+ std::string android_dt_dir;
+ if ((fs_mgr_get_boot_config_from_bootconfig_source("android_dt_dir", &android_dt_dir) ||
+ fs_mgr_get_boot_config_from_kernel_cmdline("android_dt_dir", &android_dt_dir)) &&
+ !android_dt_dir.empty()) {
+ // Ensure the returned path ends with a /
+ if (android_dt_dir.back() != '/') {
+ android_dt_dir.push_back('/');
+ }
+ } else {
+ // Fall back to the standard procfs-based path
+ android_dt_dir = "/proc/device-tree/firmware/android/";
+ }
+ LINFO << "Using Android DT directory " << android_dt_dir;
+ return android_dt_dir;
+ }();
+ return kAndroidDtDir;
+}
+
+} // namespace fs_mgr
+} // namespace android
+
std::vector<std::pair<std::string, std::string>> fs_mgr_parse_cmdline(const std::string& cmdline) {
static constexpr char quote = '"';
@@ -145,7 +172,7 @@
// firstly, check the device tree
if (is_dt_compatible()) {
- std::string file_name = get_android_dt_dir() + "/" + key;
+ std::string file_name = android::fs_mgr::GetAndroidDtDir() + key;
if (android::base::ReadFileToString(file_name, out_val)) {
if (!out_val->empty()) {
out_val->pop_back(); // Trims the trailing '\0' out.
diff --git a/fs_mgr/libfstab/fstab.cpp b/fs_mgr/libfstab/fstab.cpp
index 5b5c3d2..86ba031 100644
--- a/fs_mgr/libfstab/fstab.cpp
+++ b/fs_mgr/libfstab/fstab.cpp
@@ -51,7 +51,6 @@
namespace fs_mgr {
namespace {
-constexpr char kDefaultAndroidDtDir[] = "/proc/device-tree/firmware/android";
constexpr char kProcMountsPath[] = "/proc/mounts";
struct FlagList {
@@ -337,25 +336,14 @@
return true;
}
-std::string InitAndroidDtDir() {
- std::string android_dt_dir;
- // The platform may specify a custom Android DT path in kernel cmdline
- if (!fs_mgr_get_boot_config_from_bootconfig_source("android_dt_dir", &android_dt_dir) &&
- !fs_mgr_get_boot_config_from_kernel_cmdline("android_dt_dir", &android_dt_dir)) {
- // Fall back to the standard procfs-based path
- android_dt_dir = kDefaultAndroidDtDir;
- }
- return android_dt_dir;
-}
-
bool IsDtFstabCompatible() {
std::string dt_value;
- std::string file_name = get_android_dt_dir() + "/fstab/compatible";
+ std::string file_name = GetAndroidDtDir() + "fstab/compatible";
if (ReadDtFile(file_name, &dt_value) && dt_value == "android,fstab") {
// If there's no status property or its set to "ok" or "okay", then we use the DT fstab.
std::string status_value;
- std::string status_file_name = get_android_dt_dir() + "/fstab/status";
+ std::string status_file_name = GetAndroidDtDir() + "fstab/status";
return !ReadDtFile(status_file_name, &status_value) || status_value == "ok" ||
status_value == "okay";
}
@@ -368,7 +356,7 @@
return {};
}
- std::string fstabdir_name = get_android_dt_dir() + "/fstab";
+ std::string fstabdir_name = GetAndroidDtDir() + "fstab";
std::unique_ptr<DIR, int (*)(DIR*)> fstabdir(opendir(fstabdir_name.c_str()), closedir);
if (!fstabdir) return {};
@@ -876,7 +864,7 @@
std::set<std::string> GetBootDevices() {
// First check bootconfig, then kernel commandline, then the device tree
- std::string dt_file_name = get_android_dt_dir() + "/boot_devices";
+ std::string dt_file_name = GetAndroidDtDir() + "boot_devices";
std::string value;
if (fs_mgr_get_boot_config_from_bootconfig_source("boot_devices", &value) ||
fs_mgr_get_boot_config_from_bootconfig_source("boot_device", &value)) {
@@ -948,15 +936,8 @@
} // namespace fs_mgr
} // namespace android
-// FIXME: The same logic is duplicated in system/core/init/
-const std::string& get_android_dt_dir() {
- // Set once and saves time for subsequent calls to this function
- static const std::string kAndroidDtDir = android::fs_mgr::InitAndroidDtDir();
- return kAndroidDtDir;
-}
-
bool is_dt_compatible() {
- std::string file_name = get_android_dt_dir() + "/compatible";
+ std::string file_name = android::fs_mgr::GetAndroidDtDir() + "compatible";
std::string dt_value;
if (android::fs_mgr::ReadDtFile(file_name, &dt_value)) {
if (dt_value == "android,firmware") {
diff --git a/fs_mgr/libfstab/fstab_priv.h b/fs_mgr/libfstab/fstab_priv.h
index fb12b9f..5d226f8 100644
--- a/fs_mgr/libfstab/fstab_priv.h
+++ b/fs_mgr/libfstab/fstab_priv.h
@@ -36,7 +36,6 @@
bool fs_mgr_get_boot_config_from_bootconfig_source(const std::string& key, std::string* out_val);
bool fs_mgr_update_for_slotselect(android::fs_mgr::Fstab* fstab);
-const std::string& get_android_dt_dir();
bool is_dt_compatible();
namespace android {
diff --git a/fs_mgr/libfstab/include/fstab/fstab.h b/fs_mgr/libfstab/include/fstab/fstab.h
index e0683ac..0a45fe8 100644
--- a/fs_mgr/libfstab/include/fstab/fstab.h
+++ b/fs_mgr/libfstab/include/fstab/fstab.h
@@ -124,5 +124,9 @@
// expected name.
std::string GetVerityDeviceName(const FstabEntry& entry);
+// Returns the Android Device Tree directory as specified in the kernel bootconfig or cmdline.
+// If the platform does not configure a custom DT path, returns the standard one (based in procfs).
+const std::string& GetAndroidDtDir();
+
} // namespace fs_mgr
} // namespace android
diff --git a/init/Android.bp b/init/Android.bp
index ee34215..d4852d6 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -539,6 +539,7 @@
"libprotobuf-cpp-lite",
],
static_libs: [
+ "libfs_mgr",
"libhidl-gen-utils",
],
}
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 8da6982..0e82022 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -57,6 +57,7 @@
#include <android-base/result.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
+#include <fs_mgr.h>
#include <property_info_parser/property_info_parser.h>
#include <property_info_serializer/property_info_serializer.h>
#include <selinux/android.h>
@@ -1317,7 +1318,8 @@
return;
}
- std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(get_android_dt_dir().c_str()), closedir);
+ std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(android::fs_mgr::GetAndroidDtDir().c_str()),
+ closedir);
if (!dir) return;
std::string dt_file;
@@ -1328,7 +1330,7 @@
continue;
}
- std::string file_name = get_android_dt_dir() + dp->d_name;
+ std::string file_name = android::fs_mgr::GetAndroidDtDir() + dp->d_name;
android::base::ReadFileToString(file_name, &dt_file);
std::replace(dt_file.begin(), dt_file.end(), ',', '.');
diff --git a/init/util.cpp b/init/util.cpp
index d0478e8..61d59a4 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -42,6 +42,10 @@
#include <cutils/sockets.h>
#include <selinux/android.h>
+#if defined(__ANDROID__)
+#include <fs_mgr.h>
+#endif
+
#ifdef INIT_FULL_SOURCES
#include <android/api-level.h>
#include <sys/system_properties.h>
@@ -60,8 +64,6 @@
namespace android {
namespace init {
-const std::string kDefaultAndroidDtDir("/proc/device-tree/firmware/android/");
-
const std::string kDataDirPrefix("/data/");
void (*trigger_shutdown)(const std::string& command) = nullptr;
@@ -375,45 +377,18 @@
return dst;
}
-static std::string init_android_dt_dir() {
- // Use the standard procfs-based path by default
- std::string android_dt_dir = kDefaultAndroidDtDir;
- // The platform may specify a custom Android DT path in kernel cmdline
- ImportKernelCmdline([&](const std::string& key, const std::string& value) {
- if (key == "androidboot.android_dt_dir") {
- android_dt_dir = value;
- }
- });
- // ..Or bootconfig
- if (android_dt_dir == kDefaultAndroidDtDir) {
- ImportBootconfig([&](const std::string& key, const std::string& value) {
- if (key == "androidboot.android_dt_dir") {
- android_dt_dir = value;
- }
- });
- }
-
- LOG(INFO) << "Using Android DT directory " << android_dt_dir;
- return android_dt_dir;
-}
-
-// FIXME: The same logic is duplicated in system/core/fs_mgr/
-const std::string& get_android_dt_dir() {
- // Set once and saves time for subsequent calls to this function
- static const std::string kAndroidDtDir = init_android_dt_dir();
- return kAndroidDtDir;
-}
-
// Reads the content of device tree file under the platform's Android DT directory.
// Returns true if the read is success, false otherwise.
bool read_android_dt_file(const std::string& sub_path, std::string* dt_content) {
- const std::string file_name = get_android_dt_dir() + sub_path;
+#if defined(__ANDROID__)
+ const std::string file_name = android::fs_mgr::GetAndroidDtDir() + sub_path;
if (android::base::ReadFileToString(file_name, dt_content)) {
if (!dt_content->empty()) {
dt_content->pop_back(); // Trims the trailing '\0' out.
return true;
}
}
+#endif
return false;
}
diff --git a/init/util.h b/init/util.h
index 3f0a4e0..1c00a3e 100644
--- a/init/util.h
+++ b/init/util.h
@@ -60,9 +60,6 @@
bool is_dir(const char* pathname);
Result<std::string> ExpandProps(const std::string& src);
-// Returns the platform's Android DT directory as specified in the kernel cmdline.
-// If the platform does not configure a custom DT path, returns the standard one (based in procfs).
-const std::string& get_android_dt_dir();
// Reads or compares the content of device tree file under the platform's Android DT directory.
bool read_android_dt_file(const std::string& sub_path, std::string* dt_content);
bool is_android_dt_value_expected(const std::string& sub_path, const std::string& expected_content);