From 80281894999ea9440124cfcfbfebdec97d69f8ef Mon Sep 17 00:00:00 2001 From: Bowgo Tsai Date: Tue, 12 Dec 2017 00:47:43 +0800 Subject: [PATCH] first stage mount: support mount points like /vendor/abc Current syntax of the fstab in device tree (fstab_dt) assumes the node name is the mount point, which doesn't allow subdir: vendor { <== using "vendor/abc" leads to syntax error in device tree compatible = "android,vendor"; dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor"; type = "ext4"; mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; fsmgr_flags = "wait"; }; This CL adds a new field "mnt_point" in the fstab_dt configuration: vendor_abc { compatible = "android,vendor_abc"; dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/abc"; type = "ext4"; mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; mnt_point = "/vendor/abc"; <== new field fsmgr_flags = "wait"; }; The new field is optional and will fallback to using node name as mount point if it is absent. Note that this CL also sorts fstab_dt by mount point, because /vendor needs to be mounted first, which contains a directory /vendor/abc, before /vendor/abc can be mounted. Bug: 69955336 Test: first stage mount /vendor/abc on a device Change-Id: Ie2e519f9801f211a7a221622f32c82bedd00353f --- fs_mgr/Android.bp | 3 +++ fs_mgr/fs_mgr_fstab.cpp | 50 ++++++++++++++++++++++++++++------------- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp index ed165ed79..f23150d1c 100644 --- a/fs_mgr/Android.bp +++ b/fs_mgr/Android.bp @@ -25,6 +25,9 @@ cc_defaults { "-Werror", "-Wno-unused-variable", ], + cppflags: [ + "-std=gnu++1z", + ], } cc_library_static { diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp index 2c18a6d87..34afed1a4 100644 --- a/fs_mgr/fs_mgr_fstab.cpp +++ b/fs_mgr/fs_mgr_fstab.cpp @@ -23,6 +23,10 @@ #include #include +#include +#include +#include + #include #include #include @@ -397,16 +401,17 @@ static bool is_dt_fstab_compatible() { } static std::string read_fstab_from_dt() { - std::string fstab; if (!is_dt_compatible() || !is_dt_fstab_compatible()) { - return fstab; + return {}; } std::string fstabdir_name = get_android_dt_dir() + "/fstab"; std::unique_ptr fstabdir(opendir(fstabdir_name.c_str()), closedir); - if (!fstabdir) return fstab; + if (!fstabdir) return {}; dirent* dp; + // Each element in fstab_dt_entries is . + std::vector> fstab_dt_entries; while ((dp = readdir(fstabdir.get())) != NULL) { // skip over name, compatible and . if (dp->d_type != DT_DIR || dp->d_name[0] == '.') continue; @@ -427,41 +432,54 @@ static std::string read_fstab_from_dt() { file_name = android::base::StringPrintf("%s/%s/dev", fstabdir_name.c_str(), dp->d_name); if (!read_dt_file(file_name, &value)) { LERROR << "dt_fstab: Failed to find device for partition " << dp->d_name; - fstab.clear(); - break; + return {}; } fstab_entry.push_back(value); - fstab_entry.push_back(android::base::StringPrintf("/%s", dp->d_name)); + + std::string mount_point; + file_name = + android::base::StringPrintf("%s/%s/mnt_point", fstabdir_name.c_str(), dp->d_name); + if (read_dt_file(file_name, &value)) { + LINFO << "dt_fstab: Using a specified mount point " << value << " for " << dp->d_name; + mount_point = value; + } else { + mount_point = android::base::StringPrintf("/%s", dp->d_name); + } + fstab_entry.push_back(mount_point); file_name = android::base::StringPrintf("%s/%s/type", fstabdir_name.c_str(), dp->d_name); if (!read_dt_file(file_name, &value)) { LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name; - fstab.clear(); - break; + return {}; } fstab_entry.push_back(value); file_name = android::base::StringPrintf("%s/%s/mnt_flags", fstabdir_name.c_str(), dp->d_name); if (!read_dt_file(file_name, &value)) { LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name; - fstab.clear(); - break; + return {}; } fstab_entry.push_back(value); file_name = android::base::StringPrintf("%s/%s/fsmgr_flags", fstabdir_name.c_str(), dp->d_name); if (!read_dt_file(file_name, &value)) { LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name; - fstab.clear(); - break; + return {}; } fstab_entry.push_back(value); - - fstab += android::base::Join(fstab_entry, " "); - fstab += '\n'; + // Adds a fstab_entry to fstab_dt_entries, to be sorted by mount_point later. + fstab_dt_entries.emplace_back(mount_point, android::base::Join(fstab_entry, " ")); } - return fstab; + // Sort fstab_dt entries, to ensure /vendor is mounted before /vendor/abc is attempted. + std::sort(fstab_dt_entries.begin(), fstab_dt_entries.end(), + [](const auto& a, const auto& b) { return a.first < b.first; }); + + std::string fstab_result; + for (const auto& [_, dt_entry] : fstab_dt_entries) { + fstab_result += dt_entry + "\n"; + } + return fstab_result; } bool is_dt_compatible() {