ueventd: Wait for runtime apex before running external firmware handler
External firmware handlers cannot run until com.android.runtime.apex is activated. However, it may be possible to request firmware from the kernel before apex activation. Waiting for runtime apex is required before running an external firmware handler. Test: atest CtsInitTestCases Change-Id: Id63b7f29084d3cecb901049162d3e5cd0055566f Signed-off-by: Suchang Woo <suchang.woo@samsung.com>
This commit is contained in:
parent
155bba8b0c
commit
7d8c25b0c9
1 changed files with 34 additions and 0 deletions
|
@ -33,6 +33,7 @@
|
|||
#include <android-base/chrono_utils.h>
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <android-base/scopeguard.h>
|
||||
#include <android-base/strings.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
|
@ -43,6 +44,7 @@ using android::base::Split;
|
|||
using android::base::Timer;
|
||||
using android::base::Trim;
|
||||
using android::base::unique_fd;
|
||||
using android::base::WaitForProperty;
|
||||
using android::base::WriteFully;
|
||||
|
||||
namespace android {
|
||||
|
@ -82,6 +84,33 @@ static bool IsBooting() {
|
|||
return access("/dev/.booting", F_OK) == 0;
|
||||
}
|
||||
|
||||
static bool IsApexActivated() {
|
||||
static bool apex_activated = []() {
|
||||
// Wait for com.android.runtime.apex activation
|
||||
// Property name and value must be kept in sync with system/apexd/apex/apex_constants.h
|
||||
// 60s is the default firmware sysfs fallback timeout. (/sys/class/firmware/timeout)
|
||||
if (!WaitForProperty("apexd.status", "activated", 60s)) {
|
||||
LOG(ERROR) << "Apexd activation wait timeout";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}();
|
||||
|
||||
return apex_activated;
|
||||
}
|
||||
|
||||
static bool NeedsRerunExternalHandler() {
|
||||
static bool first = true;
|
||||
|
||||
// Rerun external handler only on the first try and when apex is activated
|
||||
if (first) {
|
||||
first = false;
|
||||
return IsApexActivated();
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
ExternalFirmwareHandler::ExternalFirmwareHandler(std::string devpath, uid_t uid, gid_t gid,
|
||||
std::string handler_path)
|
||||
: devpath(std::move(devpath)), uid(uid), gid(gid), handler_path(std::move(handler_path)) {
|
||||
|
@ -210,6 +239,11 @@ std::string FirmwareHandler::GetFirmwarePath(const Uevent& uevent) const {
|
|||
|
||||
auto result = RunExternalHandler(external_handler.handler_path, external_handler.uid,
|
||||
external_handler.gid, uevent);
|
||||
if (!result.ok() && NeedsRerunExternalHandler()) {
|
||||
auto res = RunExternalHandler(external_handler.handler_path, external_handler.uid,
|
||||
external_handler.gid, uevent);
|
||||
result = std::move(res);
|
||||
}
|
||||
if (!result.ok()) {
|
||||
LOG(ERROR) << "Using default firmware; External firmware handler failed: "
|
||||
<< result.error();
|
||||
|
|
Loading…
Reference in a new issue