libmodprobe: check blockedlist if load failed

check blockedlist if load failed and fix potential race condition

Test: Boot to home
Bug: 240210009
Signed-off-by: chungkai <chungkai@google.com>
Change-Id: I0ccc6c58897c03f5bb5f6349b5c3ec047b458505
This commit is contained in:
chungkai 2022-07-28 05:09:32 +00:00 committed by Chung-Kai (Michael) Mei
parent ef46fe4e2b
commit 8b451523a4

View file

@ -444,6 +444,7 @@ bool Modprobe::IsBlocklisted(const std::string& module_name) {
// until all modules are loaded.
bool Modprobe::LoadModulesParallel(int num_threads) {
bool ret = true;
int count = -1;
std::map<std::string, std::set<std::string>> mod_with_deps;
// Get dependencies
@ -471,18 +472,21 @@ bool Modprobe::LoadModulesParallel(int num_threads) {
}
}
while (!mod_with_deps.empty()) {
while (!mod_with_deps.empty() && count != module_loaded_.size()) {
std::vector<std::thread> threads;
std::vector<std::string> mods_path_to_load;
std::mutex vector_lock;
count = module_loaded_.size();
// Find independent modules
for (const auto& [it_mod, it_dep] : mod_with_deps) {
if (it_dep.size() == 1) {
if (module_options_[it_mod].find("load_sequential=1") != std::string::npos) {
LoadWithAliases(it_mod, true);
if (!LoadWithAliases(it_mod, true) && !IsBlocklisted(it_mod)) {
return false;
}
} else {
mods_path_to_load.emplace_back(*(it_dep.begin()));
mods_path_to_load.emplace_back(it_mod);
}
}
}
@ -491,12 +495,16 @@ bool Modprobe::LoadModulesParallel(int num_threads) {
auto thread_function = [&] {
std::unique_lock lk(vector_lock);
while (!mods_path_to_load.empty()) {
auto mod_path_to_load = std::move(mods_path_to_load.back());
auto ret_load = true;
auto mod_to_load = std::move(mods_path_to_load.back());
mods_path_to_load.pop_back();
lk.unlock();
ret &= Insmod(mod_path_to_load, "");
ret_load &= LoadWithAliases(mod_to_load, true);
lk.lock();
if (!ret_load && !IsBlocklisted(mod_to_load)) {
ret &= ret_load;
}
}
};
@ -508,6 +516,8 @@ bool Modprobe::LoadModulesParallel(int num_threads) {
thread.join();
}
if (!ret) return ret;
std::lock_guard guard(module_loaded_lock_);
// Remove loaded module form mod_with_deps and soft dependencies of other modules
for (const auto& module_loaded : module_loaded_) {