summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Cherry <tomcherry@google.com>2018-12-06 13:29:30 -0800
committerTom Cherry <tomcherry@google.com>2018-12-06 13:35:52 -0800
commite29101077c9fae5dbb9563d046ea37272e7f0b8f (patch)
tree1196e955a767980cc0fc45f420a807dd134fd65b
parent215d1d510ea1d1f076716ab9303f87cbcd8bcacc (diff)
downloadsystem_core-e29101077c9fae5dbb9563d046ea37272e7f0b8f.tar.gz
system_core-e29101077c9fae5dbb9563d046ea37272e7f0b8f.tar.bz2
system_core-e29101077c9fae5dbb9563d046ea37272e7f0b8f.zip
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
-rw-r--r--init/first_stage_mount.cpp4
-rw-r--r--init/uevent_listener.cpp5
-rw-r--r--init/uevent_listener.h2
-rw-r--r--init/ueventd.cpp41
-rw-r--r--init/ueventd_parser.cpp23
-rw-r--r--init/ueventd_parser.h1
-rw-r--r--init/ueventd_parser_test.cpp19
-rw-r--r--rootdir/ueventd.rc1
8 files changed, 67 insertions, 29 deletions
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index c1246567a..6ae112342 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -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_) {
diff --git a/init/uevent_listener.cpp b/init/uevent_listener.cpp
index d6765b7a1..62cd2be3a 100644
--- a/init/uevent_listener.cpp
+++ b/init/uevent_listener.cpp
@@ -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";
}
diff --git a/init/uevent_listener.h b/init/uevent_listener.h
index 5b453fe65..aea094e77 100644
--- a/init/uevent_listener.h
+++ b/init/uevent_listener.h
@@ -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,
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 66491ddfd..7545d53b8 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -233,29 +233,26 @@ 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"});
-
- uevent_handlers.emplace_back(std::make_unique<DeviceHandler>(
- std::move(ueventd_configuration.dev_permissions),
- std::move(ueventd_configuration.sysfs_permissions),
- std::move(ueventd_configuration.subsystems), fs_mgr_get_boot_devices(), true));
- uevent_handlers.emplace_back(std::make_unique<FirmwareHandler>(
- std::move(ueventd_configuration.firmware_directories)));
-
- if (ueventd_configuration.enable_modalias_handling) {
- uevent_handlers.emplace_back(std::make_unique<ModaliasHandler>());
- }
+
+ // 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"});
+
+ uevent_handlers.emplace_back(std::make_unique<DeviceHandler>(
+ std::move(ueventd_configuration.dev_permissions),
+ std::move(ueventd_configuration.sysfs_permissions),
+ std::move(ueventd_configuration.subsystems), fs_mgr_get_boot_devices(), true));
+ uevent_handlers.emplace_back(std::make_unique<FirmwareHandler>(
+ std::move(ueventd_configuration.firmware_directories)));
+
+ 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);
diff --git a/init/ueventd_parser.cpp b/init/ueventd_parser.cpp
index 677938e10..aac3fe5c1 100644
--- a/init/ueventd_parser.cpp
+++ b/init/ueventd_parser.cpp
@@ -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);
diff --git a/init/ueventd_parser.h b/init/ueventd_parser.h
index 7d30edf4f..d476decc9 100644
--- a/init/ueventd_parser.h
+++ b/init/ueventd_parser.h
@@ -31,6 +31,7 @@ struct UeventdConfiguration {
std::vector<Permissions> dev_permissions;
std::vector<std::string> firmware_directories;
bool enable_modalias_handling = false;
+ size_t uevent_socket_rcvbuf_size = 0;
};
UeventdConfiguration ParseConfig(const std::vector<std::string>& configs);
diff --git a/init/ueventd_parser_test.cpp b/init/ueventd_parser_test.cpp
index c3af341c6..9c1cedf8b 100644
--- a/init/ueventd_parser_test.cpp
+++ b/init/ueventd_parser_test.cpp
@@ -138,6 +138,15 @@ firmware_directories /more
TestUeventdFile(ueventd_file, {{}, {}, {}, firmware_directories});
}
+TEST(ueventd_parser, UeventSocketRcvbufSize) {
+ auto ueventd_file = R"(
+uevent_socket_rcvbuf_size 8k
+uevent_socket_rcvbuf_size 8M
+)";
+
+ TestUeventdFile(ueventd_file, {{}, {}, {}, {}, false, 8 * 1024 * 1024});
+}
+
TEST(ueventd_parser, AllTogether) {
auto ueventd_file = R"(
@@ -169,6 +178,8 @@ subsystem test_devpath_dirname
/sys/devices/virtual/*/input poll_delay 0660 root input
firmware_directories /more
+uevent_socket_rcvbuf_size 6M
+
#ending comment
)";
@@ -197,8 +208,10 @@ firmware_directories /more
"/more",
};
- TestUeventdFile(ueventd_file,
- {subsystems, sysfs_permissions, permissions, firmware_directories});
+ size_t uevent_socket_rcvbuf_size = 6 * 1024 * 1024;
+
+ TestUeventdFile(ueventd_file, {subsystems, sysfs_permissions, permissions, firmware_directories,
+ false, uevent_socket_rcvbuf_size});
}
// All of these lines are ill-formed, so test that there is 0 output.
@@ -213,6 +226,8 @@ firmware_directories #no directory listed
/sys/devices/platform/trusty.* trusty_version 0440 baduidbad log
/sys/devices/platform/trusty.* trusty_version 0440 root baduidbad
+uevent_socket_rcvbuf_size blah
+
subsystem #no name
)";
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index d47506c44..a9658a46a 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -1,4 +1,5 @@
firmware_directories /etc/firmware/ /odm/firmware/ /vendor/firmware/ /firmware/image/
+uevent_socket_rcvbuf_size 16M
subsystem adf
devname uevent_devname