diff options
author | chungkai <chungkai@google.com> | 2022-07-28 05:09:32 +0000 |
---|---|---|
committer | Chung-Kai (Michael) Mei <chungkai@google.com> | 2022-08-06 04:48:55 +0000 |
commit | 8b451523a428ccbcd220e038f7e5a564dada756d (patch) | |
tree | 370a535da1679ddfe0de40a99afec572b903a9c5 /libmodprobe | |
parent | ef46fe4e2b5f1909b9e9a4ae66f70a859211d1d6 (diff) | |
download | core-8b451523a428ccbcd220e038f7e5a564dada756d.tar.gz |
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
Diffstat (limited to 'libmodprobe')
-rw-r--r-- | libmodprobe/libmodprobe.cpp | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/libmodprobe/libmodprobe.cpp b/libmodprobe/libmodprobe.cpp index b2ace3435..e071c96d9 100644 --- a/libmodprobe/libmodprobe.cpp +++ b/libmodprobe/libmodprobe.cpp @@ -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_) { |