Use apexservice to get the list of apexes
In this change, the logic to get the list of apexes is replaced with the query to apexservice, which is the source of truth. This dedups the manual scanning of /apex for the apex list, which should be internal to apexd. (Note how vold_prepare_subdirs filtered out directories with "@" character). This also makes vold_prepare_subdirs immune to the upcoming changes: /apex directory containing only bootstrap APEXes in the bootstrap NS. Until now, getting the list of apexes by scanning /apex was okay because of the accidental fact that /apex directory has directories for all the apexes, not only bootstrap apexes. Bug: 293949266 Bug: 293546778 Test: CtsPackageSettingHostTestCases Change-Id: I3fe373ca6f4c2281439bb2449845a1a14357131e
This commit is contained in:
parent
c2b3fefa01
commit
443a73b100
2 changed files with 32 additions and 14 deletions
|
@ -239,7 +239,10 @@ cc_binary {
|
|||
|
||||
cc_binary {
|
||||
name: "vold_prepare_subdirs",
|
||||
defaults: ["vold_default_flags"],
|
||||
defaults: [
|
||||
"vold_default_flags",
|
||||
"libapexservice-deps",
|
||||
],
|
||||
|
||||
srcs: [
|
||||
"vold_prepare_subdirs.cpp",
|
||||
|
|
|
@ -30,7 +30,11 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/result.h>
|
||||
#include <android-base/scopeguard.h>
|
||||
#include <android/apex/ApexInfo.h>
|
||||
#include <android/apex/IApexService.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
|
||||
#include <cutils/fs.h>
|
||||
#include <selinux/android.h>
|
||||
|
@ -141,24 +145,35 @@ static bool rmrf_contents(const std::string& path) {
|
|||
}
|
||||
}
|
||||
|
||||
static android::base::Result<std::vector<std::string>> 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<android::apex::IApexService>(binder);
|
||||
std::vector<android::apex::ApexInfo> list;
|
||||
auto status = service->getActivePackages(&list);
|
||||
if (!status.isOk()) {
|
||||
return android::base::Error() << status.exceptionMessage().c_str();
|
||||
}
|
||||
std::vector<std::string> 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 dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir("/apex"), closedir);
|
||||
if (!dirp) {
|
||||
PLOG(ERROR) << "Unable to open apex directory";
|
||||
auto apex_list = get_apex_list();
|
||||
if (!apex_list.ok()) {
|
||||
LOG(ERROR) << apex_list.error();
|
||||
return false;
|
||||
}
|
||||
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;
|
||||
|
||||
for (const auto& name : *apex_list) {
|
||||
if (!prepare_dir(sehandle, 0771, AID_ROOT, AID_SYSTEM, path + "/apexdata/" + name)) {
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue