From 6d0792551024693ae2779a4d9e6380f9b969d4fe Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Fri, 11 Aug 2023 15:34:35 +0000 Subject: [PATCH 1/2] Revert "Use apexservice to get the list of apexes" Revert submission 2685449-apexdata-dirs Reason for revert: b/295345486 performance regression. Reverted changes: /q/submissionid:2685449-apexdata-dirs Bug: b/295345486 Test: n/a Change-Id: I710a416398148b544635e32e6b8066fb0560171f --- Android.bp | 5 +---- vold_prepare_subdirs.cpp | 41 +++++++++++++--------------------------- 2 files changed, 14 insertions(+), 32 deletions(-) diff --git a/Android.bp b/Android.bp index 1240efc..7e41f22 100644 --- a/Android.bp +++ b/Android.bp @@ -239,10 +239,7 @@ cc_binary { cc_binary { name: "vold_prepare_subdirs", - defaults: [ - "vold_default_flags", - "libapexservice-deps", - ], + defaults: ["vold_default_flags"], srcs: [ "vold_prepare_subdirs.cpp", diff --git a/vold_prepare_subdirs.cpp b/vold_prepare_subdirs.cpp index e41e994..60e82f5 100644 --- a/vold_prepare_subdirs.cpp +++ b/vold_prepare_subdirs.cpp @@ -30,11 +30,7 @@ #include #include -#include #include -#include -#include -#include #include #include @@ -145,35 +141,24 @@ static bool rmrf_contents(const std::string& path) { } } -static android::base::Result> get_apex_list() { - auto sm = android::defaultServiceManager(); - auto binder = sm->waitForService(android::String16("apexservice")); - if (binder == nullptr) { - return android::base::Error() << "Failed to get apexservice"; - } - auto service = android::interface_cast(binder); - std::vector list; - auto status = service->getActivePackages(&list); - if (!status.isOk()) { - return android::base::Error() << status.exceptionMessage().c_str(); - } - std::vector names; - names.reserve(list.size()); - for (const auto& apex_info : list) { - names.push_back(apex_info.moduleName); - } - return names; -} - static bool prepare_apex_subdirs(struct selabel_handle* sehandle, const std::string& path) { if (!prepare_dir(sehandle, 0711, 0, 0, path + "/apexdata")) return false; - auto apex_list = get_apex_list(); - if (!apex_list.ok()) { - LOG(ERROR) << apex_list.error(); + auto dirp = std::unique_ptr(opendir("/apex"), closedir); + if (!dirp) { + PLOG(ERROR) << "Unable to open apex directory"; return false; } - for (const auto& name : *apex_list) { + struct dirent* entry; + while ((entry = readdir(dirp.get())) != nullptr) { + if (entry->d_type != DT_DIR) continue; + + const char* name = entry->d_name; + // skip any starting with "." + if (name[0] == '.') continue; + + if (strchr(name, '@') != NULL) continue; + if (!prepare_dir(sehandle, 0771, AID_ROOT, AID_SYSTEM, path + "/apexdata/" + name)) { return false; } From 64d727c5031cceb875b4d11000bcfc0c2efa2bea Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Sat, 12 Aug 2023 00:40:21 +0900 Subject: [PATCH 2/2] Use /data/misc/apexdata for the list of APEXes vold_prepare_subdirs should create apexdata directories for each APEX. Previously, it gets the list by scanning /apex directory. However, vold/vold_prepare_subdirs run in the bootstrap mount namespace, they can see only bootstrap apexes in /apex. The reason why it worked was that unintended side effects of how we managed /apex directory for both mount namespace. Instead, since apexdata directories are already populated by init in /data/misc/apexdata, we can use that directory for the same purpose. Bug: 295345486 Test: CtsPackageSettingHostTestCases Change-Id: I453cd59f54ccbb140f73b5e8576b36fa49f9bc59 --- vold_prepare_subdirs.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/vold_prepare_subdirs.cpp b/vold_prepare_subdirs.cpp index 60e82f5..e82a7c2 100644 --- a/vold_prepare_subdirs.cpp +++ b/vold_prepare_subdirs.cpp @@ -144,7 +144,12 @@ static bool rmrf_contents(const std::string& path) { static bool prepare_apex_subdirs(struct selabel_handle* sehandle, const std::string& path) { if (!prepare_dir(sehandle, 0711, 0, 0, path + "/apexdata")) return false; - auto dirp = std::unique_ptr(opendir("/apex"), closedir); + // Since vold/vold_prepare_subdirs run in the bootstrap mount namespace + // we can't get the full list of APEXes by scanning /apex directory. + // Instead, we can look up /data/misc/apexdata for the list of APEXes, + // which is populated during `perform_apex_config` in init. + // Note: `init_user0` should be invoked after `perform_apex_config`. + auto dirp = std::unique_ptr(opendir("/data/misc/apexdata"), closedir); if (!dirp) { PLOG(ERROR) << "Unable to open apex directory"; return false; @@ -157,8 +162,6 @@ static bool prepare_apex_subdirs(struct selabel_handle* sehandle, const std::str // skip any starting with "." if (name[0] == '.') continue; - if (strchr(name, '@') != NULL) continue; - if (!prepare_dir(sehandle, 0771, AID_ROOT, AID_SYSTEM, path + "/apexdata/" + name)) { return false; }