Merge "ueventd: Allow pattern matching to find external firmware handler" am: 4a3ab034c6
am: dd7da900a0
Original change: https://android-review.googlesource.com/c/platform/system/core/+/1664121 Change-Id: I71409f873b15ed2e22ee41da2c93375f87d89a8a
This commit is contained in:
commit
1875508cdf
3 changed files with 54 additions and 3 deletions
|
@ -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
|
||||
<< "'";
|
||||
|
|
|
@ -30,11 +30,13 @@ namespace android {
|
|||
namespace init {
|
||||
|
||||
struct ExternalFirmwareHandler {
|
||||
ExternalFirmwareHandler(std::string devpath, uid_t uid, std::string handler_path)
|
||||
: devpath(std::move(devpath)), uid(uid), handler_path(std::move(handler_path)) {}
|
||||
ExternalFirmwareHandler(std::string devpath, uid_t uid, std::string handler_path);
|
||||
|
||||
std::string devpath;
|
||||
uid_t uid;
|
||||
std::string handler_path;
|
||||
|
||||
std::function<bool(const std::string&)> match;
|
||||
};
|
||||
|
||||
class FirmwareHandler : public UeventHandler {
|
||||
|
|
|
@ -154,6 +154,9 @@ TEST(ueventd_parser, ExternalFirmwareHandlers) {
|
|||
external_firmware_handler devpath root handler_path
|
||||
external_firmware_handler /devices/path/firmware/something001.bin system /vendor/bin/firmware_handler.sh
|
||||
external_firmware_handler /devices/path/firmware/something002.bin radio "/vendor/bin/firmware_handler.sh --has --arguments"
|
||||
external_firmware_handler /devices/path/firmware/* root "/vendor/bin/firmware_handler.sh"
|
||||
external_firmware_handler /devices/path/firmware/something* system "/vendor/bin/firmware_handler.sh"
|
||||
external_firmware_handler /devices/path/*/firmware/something*.bin radio "/vendor/bin/firmware_handler.sh"
|
||||
)";
|
||||
|
||||
auto external_firmware_handlers = std::vector<ExternalFirmwareHandler>{
|
||||
|
@ -172,6 +175,21 @@ external_firmware_handler /devices/path/firmware/something002.bin radio "/vendor
|
|||
AID_RADIO,
|
||||
"/vendor/bin/firmware_handler.sh --has --arguments",
|
||||
},
|
||||
{
|
||||
"/devices/path/firmware/",
|
||||
AID_ROOT,
|
||||
"/vendor/bin/firmware_handler.sh",
|
||||
},
|
||||
{
|
||||
"/devices/path/firmware/something",
|
||||
AID_SYSTEM,
|
||||
"/vendor/bin/firmware_handler.sh",
|
||||
},
|
||||
{
|
||||
"/devices/path/*/firmware/something*.bin",
|
||||
AID_RADIO,
|
||||
"/vendor/bin/firmware_handler.sh",
|
||||
},
|
||||
};
|
||||
|
||||
TestUeventdFile(ueventd_file, {{}, {}, {}, {}, external_firmware_handlers});
|
||||
|
|
Loading…
Reference in a new issue