Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 70431b1f authored by Tom Cherry's avatar Tom Cherry Committed by Gerrit Code Review
Browse files

Merge "ueventd: parallelize uevent handling"

parents 9b537f24 c583305e
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -175,7 +175,7 @@ void DeviceHandler::FixupSysPermissions(const std::string& upath,
        if (s.MatchWithSubsystem(path, subsystem)) s.SetPermissions(path);
    }

    if (access(path.c_str(), F_OK) == 0) {
    if (!skip_restorecon_ && access(path.c_str(), F_OK) == 0) {
        LOG(VERBOSE) << "restorecon_recursive: " << path;
        if (selinux_android_restorecon(path.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE) != 0) {
            PLOG(ERROR) << "selinux_android_restorecon(" << path << ") failed";
@@ -467,12 +467,13 @@ void DeviceHandler::HandleDeviceEvent(const Uevent& uevent) {

DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions,
                             std::vector<SysfsPermissions> sysfs_permissions,
                             std::vector<Subsystem> subsystems)
                             std::vector<Subsystem> subsystems, bool skip_restorecon)
    : dev_permissions_(std::move(dev_permissions)),
      sysfs_permissions_(std::move(sysfs_permissions)),
      subsystems_(std::move(subsystems)),
      sehandle_(selinux_android_file_context_handle()) {}
      sehandle_(selinux_android_file_context_handle()),
      skip_restorecon_(skip_restorecon) {}

DeviceHandler::DeviceHandler()
    : DeviceHandler(std::vector<Permissions>{}, std::vector<SysfsPermissions>{},
                    std::vector<Subsystem>{}) {}
                    std::vector<Subsystem>{}, false) {}
+10 −5
Original line number Diff line number Diff line
@@ -114,14 +114,21 @@ class DeviceHandler {
    DeviceHandler();
    DeviceHandler(std::vector<Permissions> dev_permissions,
                  std::vector<SysfsPermissions> sysfs_permissions,
                  std::vector<Subsystem> subsystems);
                  std::vector<Subsystem> subsystems, bool skip_restorecon);
    ~DeviceHandler(){};

    void HandleDeviceEvent(const Uevent& uevent);

    void FixupSysPermissions(const std::string& upath, const std::string& subsystem) const;

    void HandlePlatformDeviceEvent(const Uevent& uevent);
    void HandleBlockDeviceEvent(const Uevent& uevent) const;
    void HandleGenericDeviceEvent(const Uevent& uevent) const;

    std::vector<std::string> GetBlockDeviceSymlinks(const Uevent& uevent) const;
    void set_skip_restorecon(bool value) { skip_restorecon_ = value; }

  private:
    void FixupSysPermissions(const std::string& upath, const std::string& subsystem) const;
    std::tuple<mode_t, uid_t, gid_t> GetDevicePermissions(
        const std::string& path, const std::vector<std::string>& links) const;
    void MakeDevice(const std::string& path, int block, int major, int minor,
@@ -129,15 +136,13 @@ class DeviceHandler {
    std::vector<std::string> GetCharacterDeviceSymlinks(const Uevent& uevent) const;
    void HandleDevice(const std::string& action, const std::string& devpath, int block, int major,
                      int minor, const std::vector<std::string>& links) const;
    void HandlePlatformDeviceEvent(const Uevent& uevent);
    void HandleBlockDeviceEvent(const Uevent& uevent) const;
    void HandleGenericDeviceEvent(const Uevent& uevent) const;

    std::vector<Permissions> dev_permissions_;
    std::vector<SysfsPermissions> sysfs_permissions_;
    std::vector<Subsystem> subsystems_;
    PlatformDeviceList platform_devices_;
    selabel_handle* sehandle_;
    bool skip_restorecon_;
};

// Exposed for testing
+22 −6
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <fcntl.h>
#include <sys/sendfile.h>
#include <sys/wait.h>
#include <unistd.h>

#include <string>
@@ -103,14 +104,29 @@ void HandleFirmwareEvent(const Uevent& uevent) {
    if (uevent.subsystem != "firmware" || uevent.action != "add") return;

    // Loading the firmware in a child means we can do that in parallel...
    // (We ignore SIGCHLD rather than wait for our children.)
    // We double fork instead of waiting for these processes.
    pid_t pid = fork();
    if (pid == -1) {
        PLOG(ERROR) << "could not fork to process firmware event for " << uevent.firmware;
        return;
    }

    if (pid == 0) {
        pid = fork();
        if (pid == -1) {
            PLOG(ERROR) << "could not fork a sceond time to process firmware event for "
                        << uevent.firmware;
            _exit(EXIT_FAILURE);
        }
        if (pid == 0) {
            Timer t;
            ProcessFirmwareEvent(uevent);
            LOG(INFO) << "loading " << uevent.path << " took " << t;
            _exit(EXIT_SUCCESS);
    } else if (pid == -1) {
        PLOG(ERROR) << "could not fork to process firmware event for " << uevent.firmware;
        }

        _exit(EXIT_SUCCESS);
    }

    waitpid(pid, nullptr, 0);
}
+1 −1
Original line number Diff line number Diff line
@@ -165,7 +165,7 @@ RegenerationAction UeventListener::RegenerateUeventsForPath(const std::string& p
    return RegenerateUeventsForDir(d.get(), callback);
}

static const char* kRegenerationPaths[] = {"/sys/class", "/sys/block", "/sys/devices"};
const char* kRegenerationPaths[] = {"/sys/class", "/sys/block", "/sys/devices"};

void UeventListener::RegenerateUevents(RegenerateCallback callback) const {
    for (const auto path : kRegenerationPaths) {
+2 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ enum class RegenerationAction {
using RegenerateCallback = std::function<RegenerationAction(const Uevent&)>;
using PollCallback = std::function<void(const Uevent&)>;

extern const char* kRegenerationPaths[3];

class UeventListener {
  public:
    UeventListener();
Loading