From dc5a32797ebe9d41e354d33253a3fe237dfa88b0 Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Wed, 21 Nov 2018 17:37:57 +0900 Subject: [PATCH] Allow product partition to have vendor_overlay Most vendor_overlay files are product specific that are not allowed to be installed on system partition. To install those files on product partition, product/vendor_overlay is added to the vendor_overlay source directory list. If the same files are provided from both partitions, files on product partition will be used. Bug: 119850553 Test: Build and boot to check if the vendor_overlay works Change-Id: I1ae97cb5c9dd66d1da5c9eaa3133426d2ba77471 --- fs_mgr/fs_mgr_vendor_overlay.cpp | 66 ++++++++++++++++---------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/fs_mgr/fs_mgr_vendor_overlay.cpp b/fs_mgr/fs_mgr_vendor_overlay.cpp index e1815ffc6..830f0dd01 100644 --- a/fs_mgr/fs_mgr_vendor_overlay.cpp +++ b/fs_mgr/fs_mgr_vendor_overlay.cpp @@ -35,43 +35,42 @@ using namespace std::literals; namespace { -const auto kVendorOverlaySourceDir = "/system/vendor_overlay/"s; +// The order of the list means the priority to show the files in the directory. +// The last one has the highest priority. +const std::vector kVendorOverlaySourceDirs = { + "/system/vendor_overlay/", + "/product/vendor_overlay/", +}; const auto kVndkVersionPropertyName = "ro.vndk.version"s; const auto kVendorTopDir = "/vendor/"s; const auto kLowerdirOption = "lowerdir="s; -std::string fs_mgr_get_vendor_overlay_top_dir() { - // VNDK version is provided by the /vendor/default.prop - // To read the property, it must be called at the second init stage after the default - // properties are loaded. - std::string vndk_version = android::base::GetProperty(kVndkVersionPropertyName, ""); - if (vndk_version.empty()) { - return ""; - } - return kVendorOverlaySourceDir + vndk_version; -} +std::vector> fs_mgr_get_vendor_overlay_dirs( + const std::string& vndk_version) { + std::vector> vendor_overlay_dirs; + for (const auto& vendor_overlay_source : kVendorOverlaySourceDirs) { + const auto overlay_top = vendor_overlay_source + vndk_version; + std::unique_ptr vendor_overlay_top(opendir(overlay_top.c_str()), + closedir); + if (!vendor_overlay_top) continue; -std::vector fs_mgr_get_vendor_overlay_dirs(const std::string& overlay_top) { - std::vector vendor_overlay_dirs; - std::unique_ptr vendor_overlay_top(opendir(overlay_top.c_str()), - closedir); - if (!vendor_overlay_top) return vendor_overlay_dirs; + // Vendor overlay root for current vendor version found! + LINFO << "vendor overlay root: " << overlay_top; - // Vendor overlay root for current vendor version found! - LINFO << "vendor overlay root: " << overlay_top; - struct dirent* dp; - while ((dp = readdir(vendor_overlay_top.get())) != nullptr) { - if (dp->d_type != DT_DIR || dp->d_name[0] == '.') { - continue; + struct dirent* dp; + while ((dp = readdir(vendor_overlay_top.get())) != nullptr) { + if (dp->d_type != DT_DIR || dp->d_name[0] == '.') { + continue; + } + vendor_overlay_dirs.emplace_back(overlay_top, dp->d_name); } - vendor_overlay_dirs.push_back(dp->d_name); } - return vendor_overlay_dirs; } -bool fs_mgr_vendor_overlay_mount(const std::string& overlay_top, const std::string& mount_point) { - const auto vendor_mount_point = kVendorTopDir + mount_point; +bool fs_mgr_vendor_overlay_mount(const std::pair& mount_point) { + const auto [overlay_top, mount_dir] = mount_point; + const auto vendor_mount_point = kVendorTopDir + mount_dir; LINFO << "vendor overlay mount on " << vendor_mount_point; const auto target_context = fs_mgr_get_context(vendor_mount_point); @@ -79,7 +78,7 @@ bool fs_mgr_vendor_overlay_mount(const std::string& overlay_top, const std::stri PERROR << " failed: cannot find the target vendor mount point"; return false; } - const auto source_directory = overlay_top + "/" + mount_point; + const auto source_directory = overlay_top + "/" + mount_dir; const auto source_context = fs_mgr_get_context(source_directory); if (target_context != source_context) { LERROR << " failed: source and target contexts do not match (source:" << source_context @@ -112,22 +111,25 @@ bool fs_mgr_vendor_overlay_mount(const std::string& overlay_top, const std::stri // To read the properties, vendor overlay must be mounted at the second stage, right // after "property_load_boot_defaults()" is called. bool fs_mgr_vendor_overlay_mount_all() { - const auto overlay_top = fs_mgr_get_vendor_overlay_top_dir(); - if (overlay_top.empty()) { + // To read the property, it must be called at the second init stage after the default + // properties are loaded. + static const auto vndk_version = android::base::GetProperty(kVndkVersionPropertyName, ""); + if (vndk_version.empty()) { LINFO << "vendor overlay: vndk version not defined"; return false; } - const auto vendor_overlay_dirs = fs_mgr_get_vendor_overlay_dirs(overlay_top); + + const auto vendor_overlay_dirs = fs_mgr_get_vendor_overlay_dirs(vndk_version); if (vendor_overlay_dirs.empty()) return true; if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) { LINFO << "vendor overlay: kernel does not support overlayfs"; return false; } - // Mount each directory in /system/vendor_overlay/ on /vendor + // Mount each directory in /(system|product)/vendor_overlay/ on /vendor auto ret = true; for (const auto& vendor_overlay_dir : vendor_overlay_dirs) { - if (!fs_mgr_vendor_overlay_mount(overlay_top, vendor_overlay_dir)) { + if (!fs_mgr_vendor_overlay_mount(vendor_overlay_dir)) { ret = false; } }