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

Commit e2910107 authored by Tom Cherry's avatar Tom Cherry
Browse files

ueventd: allow configuring SO_RCVBUF(FORCE) for the ueventd socket

Some configurations won't allow ueventd to have CAP_NET_ADMIN, so the
new default size of 16M is not possible for those.  Those
configurations also won't need such a large buffer size, so this
change allows devices to customize the SO_RCVBUF(FORCE) size for the
uevent socket.

This is done by adding the line 'uevent_socket_rcvbuf_size <size>' to
your device's ueventd.rc file.  <size> is specified as a byte count,
for example '16M' is 16MiB.

The last parsed uevent_socket_rcvbuf_size line is the one that is
used.

Bug: 120485624
Test: boot sailfish
Test: ueventd unit tests
Change-Id: If8123b92ca8a9b089ad50318caada2f21bc94707
parent 215d1d51
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -132,7 +132,9 @@ static bool IsRecoveryMode() {
// Class Definitions
// -----------------
FirstStageMount::FirstStageMount()
    : need_dm_verity_(false), fstab_(fs_mgr_read_fstab_dt(), fs_mgr_free_fstab) {
    : need_dm_verity_(false),
      fstab_(fs_mgr_read_fstab_dt(), fs_mgr_free_fstab),
      uevent_listener_(16 * 1024 * 1024) {
    // Stores fstab_->recs[] into mount_fstab_recs_ (vector<fstab_rec*>)
    // for easier manipulation later, e.g., range-base for loop.
    if (fstab_) {
+2 −3
Original line number Diff line number Diff line
@@ -86,9 +86,8 @@ static void ParseEvent(const char* msg, Uevent* uevent) {
    }
}

UeventListener::UeventListener() {
    // is 16MB enough? udev uses 128MB!
    device_fd_.reset(uevent_open_socket(16 * 1024 * 1024, true));
UeventListener::UeventListener(size_t uevent_socket_rcvbuf_size) {
    device_fd_.reset(uevent_open_socket(uevent_socket_rcvbuf_size, true));
    if (device_fd_ == -1) {
        LOG(FATAL) << "Could not open uevent socket";
    }
+1 −1
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ using ListenerCallback = std::function<ListenerAction(const Uevent&)>;

class UeventListener {
  public:
    UeventListener();
    UeventListener(size_t uevent_socket_rcvbuf_size);

    void RegenerateUevents(const ListenerCallback& callback) const;
    ListenerAction RegenerateUeventsForPath(const std::string& path,
+19 −22
Original line number Diff line number Diff line
@@ -233,17 +233,14 @@ int ueventd_main(int argc, char** argv) {
    SelabelInitialize();

    std::vector<std::unique_ptr<UeventHandler>> uevent_handlers;
    UeventListener uevent_listener;

    {
    // Keep the current product name base configuration so we remain backwards compatible and
    // allow it to override everything.
    // TODO: cleanup platform ueventd.rc to remove vendor specific device node entries (b/34968103)
    auto hardware = android::base::GetProperty("ro.hardware", "");

        auto ueventd_configuration =
                ParseConfig({"/ueventd.rc", "/vendor/ueventd.rc", "/odm/ueventd.rc",
                             "/ueventd." + hardware + ".rc"});
    auto ueventd_configuration = ParseConfig({"/ueventd.rc", "/vendor/ueventd.rc",
                                              "/odm/ueventd.rc", "/ueventd." + hardware + ".rc"});

    uevent_handlers.emplace_back(std::make_unique<DeviceHandler>(
            std::move(ueventd_configuration.dev_permissions),
@@ -255,7 +252,7 @@ int ueventd_main(int argc, char** argv) {
    if (ueventd_configuration.enable_modalias_handling) {
        uevent_handlers.emplace_back(std::make_unique<ModaliasHandler>());
    }
    }
    UeventListener uevent_listener(ueventd_configuration.uevent_socket_rcvbuf_size);

    if (access(COLDBOOT_DONE, F_OK) != 0) {
        ColdBoot cold_boot(uevent_listener, uevent_handlers);
+23 −0
Original line number Diff line number Diff line
@@ -19,9 +19,13 @@
#include <grp.h>
#include <pwd.h>

#include <android-base/parseint.h>

#include "keyword_map.h"
#include "parser.h"

using android::base::ParseByteCount;

namespace android {
namespace init {

@@ -101,6 +105,22 @@ Result<Success> ParseModaliasHandlingLine(std::vector<std::string>&& args,
    return Success();
}

Result<Success> ParseUeventSocketRcvbufSizeLine(std::vector<std::string>&& args,
                                                size_t* uevent_socket_rcvbuf_size) {
    if (args.size() != 2) {
        return Error() << "uevent_socket_rcvbuf_size lines take exactly one parameter";
    }

    size_t parsed_size;
    if (!ParseByteCount(args[1], &parsed_size)) {
        return Error() << "could not parse size '" << args[1] << "' for uevent_socket_rcvbuf_line";
    }

    *uevent_socket_rcvbuf_size = parsed_size;

    return Success();
}

class SubsystemParser : public SectionParser {
  public:
    SubsystemParser(std::vector<Subsystem>* subsystems) : subsystems_(subsystems) {}
@@ -202,6 +222,9 @@ UeventdConfiguration ParseConfig(const std::vector<std::string>& configs) {
    parser.AddSingleLineParser("modalias_handling",
                               std::bind(ParseModaliasHandlingLine, _1,
                                         &ueventd_configuration.enable_modalias_handling));
    parser.AddSingleLineParser("uevent_socket_rcvbuf_size",
                               std::bind(ParseUeventSocketRcvbufSizeLine, _1,
                                         &ueventd_configuration.uevent_socket_rcvbuf_size));

    for (const auto& config : configs) {
        parser.ParseConfig(config);
Loading