canned fs_config accepts multiple lines having the same path
Previously, each file/dir in a filesystem had to have exactly one matching entry in the canned fs_config file. With this change, the config file can have multiple entries for the same path. e.g. /lib/libfoo.so 1000 1000 0644 /lib/libfoo.so 1000 2000 0644 capabilities=0x30 In this case, the last matching entry is chosen and used. This is to make it possible to customize system-provided (and thus generic) fs_config file with a user-provided (and thus context-specific) one. Bug: 209971551 Test: m Change-Id: I43902fed08db1b4968d02c75fac0a47976fff72a
This commit is contained in:
parent
d8602917f0
commit
4bd3687422
1 changed files with 20 additions and 11 deletions
|
@ -21,7 +21,6 @@
|
|||
#include <android-base/strings.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fnmatch.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
@ -67,10 +66,10 @@ int load_canned_fs_config(const char* fn) {
|
|||
}
|
||||
|
||||
// Historical: remove the leading '/' if exists.
|
||||
std::string path = tokens[0].front() == '/' ? std::string(tokens[0], 1) : tokens[0];
|
||||
std::string path(tokens[0].front() == '/' ? std::string(tokens[0], 1) : tokens[0]);
|
||||
|
||||
Entry e{
|
||||
.path = path,
|
||||
.path = std::move(path),
|
||||
.uid = static_cast<unsigned int>(atoi(tokens[1].c_str())),
|
||||
.gid = static_cast<unsigned int>(atoi(tokens[2].c_str())),
|
||||
// mode is in octal
|
||||
|
@ -93,8 +92,15 @@ int load_canned_fs_config(const char* fn) {
|
|||
canned_data.emplace_back(std::move(e));
|
||||
}
|
||||
|
||||
std::sort(canned_data.begin(), canned_data.end(),
|
||||
[](const Entry& a, const Entry& b) -> bool { return a.path < b.path; });
|
||||
// Note: we used to sort the entries by path names. This was to improve the lookup performance
|
||||
// by doing binary search. However, this is no longer the case. The lookup performance is not
|
||||
// critical because this tool runs on the host, not on the device. Now, there can be multiple
|
||||
// entries for the same path. Then the one that comes the last wins. This is to allow overriding
|
||||
// platform provided fs_config with a user provided fs_config by appending the latter to the
|
||||
// former.
|
||||
//
|
||||
// To implement the strategy, reverse the entries order, and search from the top.
|
||||
std::reverse(canned_data.begin(), canned_data.end());
|
||||
|
||||
std::cout << "loaded " << canned_data.size() << " fs_config entries" << std::endl;
|
||||
return 0;
|
||||
|
@ -105,12 +111,15 @@ void canned_fs_config(const char* path, [[maybe_unused]] int dir,
|
|||
unsigned* mode, uint64_t* capabilities) {
|
||||
if (path != nullptr && path[0] == '/') path++; // canned paths lack the leading '/'
|
||||
|
||||
const Entry* found = static_cast<Entry*>(
|
||||
bsearch(path, &canned_data[0], canned_data.size(), sizeof(Entry),
|
||||
[](const void* a, const void* b) -> int {
|
||||
return strcmp(static_cast<const char*>(a),
|
||||
static_cast<const Entry*>(b)->path.c_str());
|
||||
}));
|
||||
const Entry* found = nullptr;
|
||||
// canned_data is already reversed. First match wins.
|
||||
for (const auto& entry : canned_data) {
|
||||
if (path == entry.path) {
|
||||
found = &entry;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (found == nullptr) {
|
||||
std::cerr << "failed to find " << path << " in canned fs_config" << std::endl;
|
||||
|
|
Loading…
Reference in a new issue