summaryrefslogtreecommitdiff
path: root/init/firmware_handler.cpp
diff options
context:
space:
mode:
authorSuchang Woo <suchang.woo@samsung.com>2021-04-06 11:22:49 +0900
committerDavid Anderson <dvander@google.com>2021-04-16 13:35:10 -0700
commit22fdd0ae13c566527cedc7caf5c96f0a4e5536d4 (patch)
tree4e01496e2e1dfc8379337932172de962cd444e79 /init/firmware_handler.cpp
parent78e26beb0278bc4b1ec185bf4ab4c041a4e53ac5 (diff)
ueventd: Allow pattern matching to find external firmware handler
Only the exact same devpath uevent can launch external handler specified in ueventd.rc. So, you should specify all possible devpaths, even firmware with different filenames on the same device. Pattern mactching can be used to simplify this. Test: atest CtsInitTestCases Signed-off-by: Suchang Woo <suchang.woo@samsung.com> Change-Id: If3b7a2cabb8055bf4b768d928f0fc0012da3c177
Diffstat (limited to 'init/firmware_handler.cpp')
-rw-r--r--init/firmware_handler.cpp33
1 files changed, 32 insertions, 1 deletions
diff --git a/init/firmware_handler.cpp b/init/firmware_handler.cpp
index ba7e6bd63..bdc292275 100644
--- a/init/firmware_handler.cpp
+++ b/init/firmware_handler.cpp
@@ -17,6 +17,7 @@
#include "firmware_handler.h"
#include <fcntl.h>
+#include <fnmatch.h>
#include <glob.h>
#include <pwd.h>
#include <signal.h>
@@ -46,6 +47,20 @@ using android::base::WriteFully;
namespace android {
namespace init {
+namespace {
+bool PrefixMatch(const std::string& pattern, const std::string& path) {
+ return android::base::StartsWith(path, pattern);
+}
+
+bool FnMatch(const std::string& pattern, const std::string& path) {
+ return fnmatch(pattern.c_str(), path.c_str(), 0) == 0;
+}
+
+bool EqualMatch(const std::string& pattern, const std::string& path) {
+ return pattern == path;
+}
+} // namespace
+
static void LoadFirmware(const std::string& firmware, const std::string& root, int fw_fd,
size_t fw_size, int loading_fd, int data_fd) {
// Start transfer.
@@ -66,6 +81,22 @@ static bool IsBooting() {
return access("/dev/.booting", F_OK) == 0;
}
+ExternalFirmwareHandler::ExternalFirmwareHandler(std::string devpath, uid_t uid,
+ std::string handler_path)
+ : devpath(std::move(devpath)), uid(uid), handler_path(std::move(handler_path)) {
+ auto wildcard_position = this->devpath.find('*');
+ if (wildcard_position != std::string::npos) {
+ if (wildcard_position == this->devpath.length() - 1) {
+ this->devpath.pop_back();
+ match = std::bind(PrefixMatch, this->devpath, std::placeholders::_1);
+ } else {
+ match = std::bind(FnMatch, this->devpath, std::placeholders::_1);
+ }
+ } else {
+ match = std::bind(EqualMatch, this->devpath, std::placeholders::_1);
+ }
+}
+
FirmwareHandler::FirmwareHandler(std::vector<std::string> firmware_directories,
std::vector<ExternalFirmwareHandler> external_firmware_handlers)
: firmware_directories_(std::move(firmware_directories)),
@@ -160,7 +191,7 @@ Result<std::string> FirmwareHandler::RunExternalHandler(const std::string& handl
std::string FirmwareHandler::GetFirmwarePath(const Uevent& uevent) const {
for (const auto& external_handler : external_firmware_handlers_) {
- if (external_handler.devpath == uevent.path) {
+ if (external_handler.match(uevent.path)) {
LOG(INFO) << "Launching external firmware handler '" << external_handler.handler_path
<< "' for devpath: '" << uevent.path << "' firmware: '" << uevent.firmware
<< "'";