diff options
author | Jooyung Han <jooyung@google.com> | 2020-09-21 09:57:48 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-09-21 09:57:48 +0000 |
commit | fb16db72d227d373b0ef8cc04c7efb6091f6cc68 (patch) | |
tree | fc21546830650c084339a9892ea0aee2569408f7 /init/firmware_handler.cpp | |
parent | e7260d542f81720af828f22f31eaa10b51690f51 (diff) | |
parent | 1f7596f16a12b5b9b18c1aaf118aa15c86357dbb (diff) |
Merge "ueventd: scans /apex/*/firmware for firmwares" am: 62ccfa0c61 am: ed8016598a am: d77ba4d7dd am: c7b123050d am: 1f7596f16a
Original change: https://android-review.googlesource.com/c/platform/system/core/+/1429856
Change-Id: Iefc7fb40d5d4e00136c9498ca819b2441a71f8e1
Diffstat (limited to 'init/firmware_handler.cpp')
-rw-r--r-- | init/firmware_handler.cpp | 46 |
1 files changed, 39 insertions, 7 deletions
diff --git a/init/firmware_handler.cpp b/init/firmware_handler.cpp index dff7b6948d..b50b4efa16 100644 --- a/init/firmware_handler.cpp +++ b/init/firmware_handler.cpp @@ -17,6 +17,7 @@ #include "firmware_handler.h" #include <fcntl.h> +#include <glob.h> #include <pwd.h> #include <signal.h> #include <stdlib.h> @@ -30,6 +31,7 @@ #include <android-base/chrono_utils.h> #include <android-base/file.h> #include <android-base/logging.h> +#include <android-base/scopeguard.h> #include <android-base/strings.h> #include <android-base/unique_fd.h> @@ -203,25 +205,28 @@ void FirmwareHandler::ProcessFirmwareEvent(const std::string& root, } std::vector<std::string> attempted_paths_and_errors; - - int booting = IsBooting(); -try_loading_again: - attempted_paths_and_errors.clear(); - for (const auto& firmware_directory : firmware_directories_) { + auto TryLoadFirmware = [&](const std::string& firmware_directory) { std::string file = firmware_directory + firmware; unique_fd fw_fd(open(file.c_str(), O_RDONLY | O_CLOEXEC)); if (fw_fd == -1) { attempted_paths_and_errors.emplace_back("firmware: attempted " + file + ", open failed: " + strerror(errno)); - continue; + return false; } struct stat sb; if (fstat(fw_fd, &sb) == -1) { attempted_paths_and_errors.emplace_back("firmware: attempted " + file + ", fstat failed: " + strerror(errno)); - continue; + return false; } LoadFirmware(firmware, root, fw_fd, sb.st_size, loading_fd, data_fd); + return true; + }; + + int booting = IsBooting(); +try_loading_again: + attempted_paths_and_errors.clear(); + if (ForEachFirmwareDirectory(TryLoadFirmware)) { return; } @@ -242,6 +247,33 @@ try_loading_again: write(loading_fd, "-1", 2); } +bool FirmwareHandler::ForEachFirmwareDirectory( + std::function<bool(const std::string&)> handler) const { + for (const std::string& firmware_directory : firmware_directories_) { + if (std::invoke(handler, firmware_directory)) { + return true; + } + } + + glob_t glob_result; + glob("/apex/*/firmware/", GLOB_MARK, nullptr, &glob_result); + auto free_glob = android::base::make_scope_guard(std::bind(&globfree, &glob_result)); + for (size_t i = 0; i < glob_result.gl_pathc; i++) { + char* apex_firmware_directory = glob_result.gl_pathv[i]; + // Filter-out /apex/<name>@<ver> paths. The paths are bind-mounted to + // /apex/<name> paths, so unless we filter them out, we will look into the + // same apex twice. + if (strchr(apex_firmware_directory, '@')) { + continue; + } + if (std::invoke(handler, apex_firmware_directory)) { + return true; + } + } + + return false; +} + void FirmwareHandler::HandleUevent(const Uevent& uevent) { if (uevent.subsystem != "firmware" || uevent.action != "add") return; |