summaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
authorTom Cherry2018-08-01 15:12:20 -0500
committerTom Cherry2018-08-01 15:29:05 -0500
commit457e28f1292bbc1687038dfd15f4779ce3d8fd9e (patch)
treee1c4f3ab62e13ca49f9ee165849f6778146256fb /init
parent081b710b2ee7f726f1bef282333c397006b6b37f (diff)
downloadplatform-system-core-457e28f1292bbc1687038dfd15f4779ce3d8fd9e.tar.gz
platform-system-core-457e28f1292bbc1687038dfd15f4779ce3d8fd9e.tar.xz
platform-system-core-457e28f1292bbc1687038dfd15f4779ce3d8fd9e.zip
ueventd: require opt-in for modalias handling
Some devices have modules.alias and modules.dep for modprobe and other purposes but do not want to opt into ueventd auto loading their modules. Therefore we add a flag that can be added to ueventd configuration files to opt into this behavior. Bug: 111916071 Bug: 112048758 Test: check that modules are loaded with this opt-in Test: check that modules are not loaded without this opt-in Change-Id: Ifb281b273059b4671eea1ca5bc726c9e79f3adfb
Diffstat (limited to 'init')
-rw-r--r--init/devices.cpp6
-rw-r--r--init/devices.h8
-rw-r--r--init/firmware_handler.cpp11
-rw-r--r--init/firmware_handler.h14
-rw-r--r--init/first_stage_mount.cpp6
-rw-r--r--init/modalias_handler.cpp2
-rw-r--r--init/modalias_handler.h13
-rw-r--r--init/uevent_handler.h34
-rw-r--r--init/ueventd.cpp51
-rw-r--r--init/ueventd_parser.cpp20
-rw-r--r--init/ueventd_parser.h1
11 files changed, 122 insertions, 44 deletions
diff --git a/init/devices.cpp b/init/devices.cpp
index ed4a7398a..ba08180c3 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -372,7 +372,7 @@ void DeviceHandler::HandleDevice(const std::string& action, const std::string& d
372 } 372 }
373} 373}
374 374
375void DeviceHandler::HandleDeviceEvent(const Uevent& uevent) { 375void DeviceHandler::HandleUevent(const Uevent& uevent) {
376 if (uevent.action == "add" || uevent.action == "change" || uevent.action == "online") { 376 if (uevent.action == "add" || uevent.action == "change" || uevent.action == "online") {
377 FixupSysPermissions(uevent.path, uevent.subsystem); 377 FixupSysPermissions(uevent.path, uevent.subsystem);
378 } 378 }
@@ -418,6 +418,10 @@ void DeviceHandler::HandleDeviceEvent(const Uevent& uevent) {
418 HandleDevice(uevent.action, devpath, block, uevent.major, uevent.minor, links); 418 HandleDevice(uevent.action, devpath, block, uevent.major, uevent.minor, links);
419} 419}
420 420
421void DeviceHandler::ColdbootDone() {
422 skip_restorecon_ = true;
423}
424
421DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions, 425DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions,
422 std::vector<SysfsPermissions> sysfs_permissions, 426 std::vector<SysfsPermissions> sysfs_permissions,
423 std::vector<Subsystem> subsystems, std::set<std::string> boot_devices, 427 std::vector<Subsystem> subsystems, std::set<std::string> boot_devices,
diff --git a/init/devices.h b/init/devices.h
index 0be660f80..9d39eaace 100644
--- a/init/devices.h
+++ b/init/devices.h
@@ -29,6 +29,7 @@
29#include <selinux/label.h> 29#include <selinux/label.h>
30 30
31#include "uevent.h" 31#include "uevent.h"
32#include "uevent_handler.h"
32 33
33namespace android { 34namespace android {
34namespace init { 35namespace init {
@@ -105,7 +106,7 @@ class Subsystem {
105 std::string dir_name_ = "/dev"; 106 std::string dir_name_ = "/dev";
106}; 107};
107 108
108class DeviceHandler { 109class DeviceHandler : public UeventHandler {
109 public: 110 public:
110 friend class DeviceHandlerTester; 111 friend class DeviceHandlerTester;
111 112
@@ -113,11 +114,12 @@ class DeviceHandler {
113 DeviceHandler(std::vector<Permissions> dev_permissions, 114 DeviceHandler(std::vector<Permissions> dev_permissions,
114 std::vector<SysfsPermissions> sysfs_permissions, std::vector<Subsystem> subsystems, 115 std::vector<SysfsPermissions> sysfs_permissions, std::vector<Subsystem> subsystems,
115 std::set<std::string> boot_devices, bool skip_restorecon); 116 std::set<std::string> boot_devices, bool skip_restorecon);
117 virtual ~DeviceHandler() = default;
116 118
117 void HandleDeviceEvent(const Uevent& uevent); 119 void HandleUevent(const Uevent& uevent) override;
120 void ColdbootDone() override;
118 121
119 std::vector<std::string> GetBlockDeviceSymlinks(const Uevent& uevent) const; 122 std::vector<std::string> GetBlockDeviceSymlinks(const Uevent& uevent) const;
120 void set_skip_restorecon(bool value) { skip_restorecon_ = value; }
121 123
122 private: 124 private:
123 bool FindPlatformDevice(std::string path, std::string* platform_device_path) const; 125 bool FindPlatformDevice(std::string path, std::string* platform_device_path) const;
diff --git a/init/firmware_handler.cpp b/init/firmware_handler.cpp
index 28bda34a2..740e82c99 100644
--- a/init/firmware_handler.cpp
+++ b/init/firmware_handler.cpp
@@ -35,8 +35,6 @@ using android::base::WriteFully;
35namespace android { 35namespace android {
36namespace init { 36namespace init {
37 37
38std::vector<std::string> firmware_directories;
39
40static void LoadFirmware(const Uevent& uevent, const std::string& root, int fw_fd, size_t fw_size, 38static void LoadFirmware(const Uevent& uevent, const std::string& root, int fw_fd, size_t fw_size,
41 int loading_fd, int data_fd) { 39 int loading_fd, int data_fd) {
42 // Start transfer. 40 // Start transfer.
@@ -58,7 +56,10 @@ static bool IsBooting() {
58 return access("/dev/.booting", F_OK) == 0; 56 return access("/dev/.booting", F_OK) == 0;
59} 57}
60 58
61static void ProcessFirmwareEvent(const Uevent& uevent) { 59FirmwareHandler::FirmwareHandler(std::vector<std::string> firmware_directories)
60 : firmware_directories_(std::move(firmware_directories)) {}
61
62void FirmwareHandler::ProcessFirmwareEvent(const Uevent& uevent) {
62 int booting = IsBooting(); 63 int booting = IsBooting();
63 64
64 LOG(INFO) << "firmware: loading '" << uevent.firmware << "' for '" << uevent.path << "'"; 65 LOG(INFO) << "firmware: loading '" << uevent.firmware << "' for '" << uevent.path << "'";
@@ -80,7 +81,7 @@ static void ProcessFirmwareEvent(const Uevent& uevent) {
80 } 81 }
81 82
82try_loading_again: 83try_loading_again:
83 for (const auto& firmware_directory : firmware_directories) { 84 for (const auto& firmware_directory : firmware_directories_) {
84 std::string file = firmware_directory + uevent.firmware; 85 std::string file = firmware_directory + uevent.firmware;
85 unique_fd fw_fd(open(file.c_str(), O_RDONLY | O_CLOEXEC)); 86 unique_fd fw_fd(open(file.c_str(), O_RDONLY | O_CLOEXEC));
86 struct stat sb; 87 struct stat sb;
@@ -104,7 +105,7 @@ try_loading_again:
104 write(loading_fd, "-1", 2); 105 write(loading_fd, "-1", 2);
105} 106}
106 107
107void HandleFirmwareEvent(const Uevent& uevent) { 108void FirmwareHandler::HandleUevent(const Uevent& uevent) {
108 if (uevent.subsystem != "firmware" || uevent.action != "add") return; 109 if (uevent.subsystem != "firmware" || uevent.action != "add") return;
109 110
110 // Loading the firmware in a child means we can do that in parallel... 111 // Loading the firmware in a child means we can do that in parallel...
diff --git a/init/firmware_handler.h b/init/firmware_handler.h
index 6081511b5..399609693 100644
--- a/init/firmware_handler.h
+++ b/init/firmware_handler.h
@@ -21,13 +21,23 @@
21#include <vector> 21#include <vector>
22 22
23#include "uevent.h" 23#include "uevent.h"
24#include "uevent_handler.h"
24 25
25namespace android { 26namespace android {
26namespace init { 27namespace init {
27 28
28extern std::vector<std::string> firmware_directories; 29class FirmwareHandler : public UeventHandler {
30 public:
31 explicit FirmwareHandler(std::vector<std::string> firmware_directories);
32 virtual ~FirmwareHandler() = default;
29 33
30void HandleFirmwareEvent(const Uevent& uevent); 34 void HandleUevent(const Uevent& uevent) override;
35
36 private:
37 void ProcessFirmwareEvent(const Uevent& uevent);
38
39 std::vector<std::string> firmware_directories_;
40};
31 41
32} // namespace init 42} // namespace init
33} // namespace android 43} // namespace android
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 43075b268..41e8fff55 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -206,7 +206,7 @@ bool FirstStageMount::InitRequiredDevices() {
206 bool found = false; 206 bool found = false;
207 auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) { 207 auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) {
208 if (uevent.path == dm_path) { 208 if (uevent.path == dm_path) {
209 device_handler_->HandleDeviceEvent(uevent); 209 device_handler_->HandleUevent(uevent);
210 found = true; 210 found = true;
211 return ListenerAction::kStop; 211 return ListenerAction::kStop;
212 } 212 }
@@ -273,7 +273,7 @@ ListenerAction FirstStageMount::HandleBlockDevice(const std::string& name, const
273 lp_metadata_partition_ = links[0]; 273 lp_metadata_partition_ = links[0];
274 } 274 }
275 required_devices_partition_names_.erase(iter); 275 required_devices_partition_names_.erase(iter);
276 device_handler_->HandleDeviceEvent(uevent); 276 device_handler_->HandleUevent(uevent);
277 if (required_devices_partition_names_.empty()) { 277 if (required_devices_partition_names_.empty()) {
278 return ListenerAction::kStop; 278 return ListenerAction::kStop;
279 } else { 279 } else {
@@ -310,7 +310,7 @@ bool FirstStageMount::InitMappedDevice(const std::string& dm_device) {
310 auto verity_callback = [&device_name, &dm_device, this, &found](const Uevent& uevent) { 310 auto verity_callback = [&device_name, &dm_device, this, &found](const Uevent& uevent) {
311 if (uevent.device_name == device_name) { 311 if (uevent.device_name == device_name) {
312 LOG(VERBOSE) << "Creating device-mapper device : " << dm_device; 312 LOG(VERBOSE) << "Creating device-mapper device : " << dm_device;
313 device_handler_->HandleDeviceEvent(uevent); 313 device_handler_->HandleUevent(uevent);
314 found = true; 314 found = true;
315 return ListenerAction::kStop; 315 return ListenerAction::kStop;
316 } 316 }
diff --git a/init/modalias_handler.cpp b/init/modalias_handler.cpp
index 1734a7e0f..1e0db5731 100644
--- a/init/modalias_handler.cpp
+++ b/init/modalias_handler.cpp
@@ -139,7 +139,7 @@ Result<Success> ModaliasHandler::InsmodWithDeps(const std::string& module_name,
139 return Insmod(dependencies[0], args); 139 return Insmod(dependencies[0], args);
140} 140}
141 141
142void ModaliasHandler::HandleModaliasEvent(const Uevent& uevent) { 142void ModaliasHandler::HandleUevent(const Uevent& uevent) {
143 if (uevent.modalias.empty()) return; 143 if (uevent.modalias.empty()) return;
144 144
145 for (const auto& [alias, module] : module_aliases_) { 145 for (const auto& [alias, module] : module_aliases_) {
diff --git a/init/modalias_handler.h b/init/modalias_handler.h
index e79da3275..3247c86d4 100644
--- a/init/modalias_handler.h
+++ b/init/modalias_handler.h
@@ -16,22 +16,23 @@
16 16
17#pragma once 17#pragma once
18 18
19#include "result.h"
20#include "uevent.h"
21
22#include <string> 19#include <string>
23#include <unordered_map> 20#include <unordered_map>
24#include <vector> 21#include <vector>
25 22
23#include "result.h"
24#include "uevent.h"
25#include "uevent_handler.h"
26
26namespace android { 27namespace android {
27namespace init { 28namespace init {
28 29
29class ModaliasHandler { 30class ModaliasHandler : public UeventHandler {
30 public: 31 public:
31 ModaliasHandler(); 32 ModaliasHandler();
32 ~ModaliasHandler(){}; 33 virtual ~ModaliasHandler() = default;
33 34
34 void HandleModaliasEvent(const Uevent& uevent); 35 void HandleUevent(const Uevent& uevent) override;
35 36
36 private: 37 private:
37 Result<Success> InsmodWithDeps(const std::string& module_name, const std::string& args); 38 Result<Success> InsmodWithDeps(const std::string& module_name, const std::string& args);
diff --git a/init/uevent_handler.h b/init/uevent_handler.h
new file mode 100644
index 000000000..75d19902e
--- /dev/null
+++ b/init/uevent_handler.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include "uevent.h"
20
21namespace android {
22namespace init {
23
24class UeventHandler {
25 public:
26 virtual ~UeventHandler() = default;
27
28 virtual void HandleUevent(const Uevent& uevent) = 0;
29
30 virtual void ColdbootDone() {}
31};
32
33} // namespace init
34} // namespace android
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index e9d829b51..95be6af52 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -38,6 +38,7 @@
38#include "firmware_handler.h" 38#include "firmware_handler.h"
39#include "modalias_handler.h" 39#include "modalias_handler.h"
40#include "selinux.h" 40#include "selinux.h"
41#include "uevent_handler.h"
41#include "uevent_listener.h" 42#include "uevent_listener.h"
42#include "ueventd_parser.h" 43#include "ueventd_parser.h"
43#include "util.h" 44#include "util.h"
@@ -107,11 +108,10 @@ namespace init {
107 108
108class ColdBoot { 109class ColdBoot {
109 public: 110 public:
110 ColdBoot(UeventListener& uevent_listener, DeviceHandler& device_handler, 111 ColdBoot(UeventListener& uevent_listener,
111 ModaliasHandler& modalias_handler) 112 std::vector<std::unique_ptr<UeventHandler>>& uevent_handlers)
112 : uevent_listener_(uevent_listener), 113 : uevent_listener_(uevent_listener),
113 device_handler_(device_handler), 114 uevent_handlers_(uevent_handlers),
114 modalias_handler_(modalias_handler),
115 num_handler_subprocesses_(std::thread::hardware_concurrency() ?: 4) {} 115 num_handler_subprocesses_(std::thread::hardware_concurrency() ?: 4) {}
116 116
117 void Run(); 117 void Run();
@@ -124,8 +124,7 @@ class ColdBoot {
124 void WaitForSubProcesses(); 124 void WaitForSubProcesses();
125 125
126 UeventListener& uevent_listener_; 126 UeventListener& uevent_listener_;
127 DeviceHandler& device_handler_; 127 std::vector<std::unique_ptr<UeventHandler>>& uevent_handlers_;
128 ModaliasHandler& modalias_handler_;
129 128
130 unsigned int num_handler_subprocesses_; 129 unsigned int num_handler_subprocesses_;
131 std::vector<Uevent> uevent_queue_; 130 std::vector<Uevent> uevent_queue_;
@@ -136,16 +135,16 @@ class ColdBoot {
136void ColdBoot::UeventHandlerMain(unsigned int process_num, unsigned int total_processes) { 135void ColdBoot::UeventHandlerMain(unsigned int process_num, unsigned int total_processes) {
137 for (unsigned int i = process_num; i < uevent_queue_.size(); i += total_processes) { 136 for (unsigned int i = process_num; i < uevent_queue_.size(); i += total_processes) {
138 auto& uevent = uevent_queue_[i]; 137 auto& uevent = uevent_queue_[i];
139 device_handler_.HandleDeviceEvent(uevent); 138
140 modalias_handler_.HandleModaliasEvent(uevent); 139 for (auto& uevent_handler : uevent_handlers_) {
140 uevent_handler->HandleUevent(uevent);
141 }
141 } 142 }
142 _exit(EXIT_SUCCESS); 143 _exit(EXIT_SUCCESS);
143} 144}
144 145
145void ColdBoot::RegenerateUevents() { 146void ColdBoot::RegenerateUevents() {
146 uevent_listener_.RegenerateUevents([this](const Uevent& uevent) { 147 uevent_listener_.RegenerateUevents([this](const Uevent& uevent) {
147 HandleFirmwareEvent(uevent);
148
149 uevent_queue_.emplace_back(std::move(uevent)); 148 uevent_queue_.emplace_back(std::move(uevent));
150 return ListenerAction::kContinue; 149 return ListenerAction::kContinue;
151 }); 150 });
@@ -168,7 +167,6 @@ void ColdBoot::ForkSubProcesses() {
168 167
169void ColdBoot::DoRestoreCon() { 168void ColdBoot::DoRestoreCon() {
170 selinux_android_restorecon("/sys", SELINUX_ANDROID_RESTORECON_RECURSE); 169 selinux_android_restorecon("/sys", SELINUX_ANDROID_RESTORECON_RECURSE);
171 device_handler_.set_skip_restorecon(false);
172} 170}
173 171
174void ColdBoot::WaitForSubProcesses() { 172void ColdBoot::WaitForSubProcesses() {
@@ -234,8 +232,7 @@ int ueventd_main(int argc, char** argv) {
234 SelinuxSetupKernelLogging(); 232 SelinuxSetupKernelLogging();
235 SelabelInitialize(); 233 SelabelInitialize();
236 234
237 DeviceHandler device_handler; 235 std::vector<std::unique_ptr<UeventHandler>> uevent_handlers;
238 ModaliasHandler modalias_handler;
239 UeventListener uevent_listener; 236 UeventListener uevent_listener;
240 237
241 { 238 {
@@ -248,19 +245,27 @@ int ueventd_main(int argc, char** argv) {
248 ParseConfig({"/ueventd.rc", "/vendor/ueventd.rc", "/odm/ueventd.rc", 245 ParseConfig({"/ueventd.rc", "/vendor/ueventd.rc", "/odm/ueventd.rc",
249 "/ueventd." + hardware + ".rc"}); 246 "/ueventd." + hardware + ".rc"});
250 247
251 device_handler = DeviceHandler{std::move(ueventd_configuration.dev_permissions), 248 uevent_handlers.emplace_back(std::make_unique<DeviceHandler>(
252 std::move(ueventd_configuration.sysfs_permissions), 249 std::move(ueventd_configuration.dev_permissions),
253 std::move(ueventd_configuration.subsystems), 250 std::move(ueventd_configuration.sysfs_permissions),
254 fs_mgr_get_boot_devices(), true}; 251 std::move(ueventd_configuration.subsystems), fs_mgr_get_boot_devices(), true));
252 uevent_handlers.emplace_back(std::make_unique<FirmwareHandler>(
253 std::move(ueventd_configuration.firmware_directories)));
255 254
256 firmware_directories = ueventd_configuration.firmware_directories; 255 if (ueventd_configuration.enable_modalias_handling) {
256 uevent_handlers.emplace_back(std::make_unique<ModaliasHandler>());
257 }
257 } 258 }
258 259
259 if (access(COLDBOOT_DONE, F_OK) != 0) { 260 if (access(COLDBOOT_DONE, F_OK) != 0) {
260 ColdBoot cold_boot(uevent_listener, device_handler, modalias_handler); 261 ColdBoot cold_boot(uevent_listener, uevent_handlers);
261 cold_boot.Run(); 262 cold_boot.Run();
262 } 263 }
263 264
265 for (auto& uevent_handler : uevent_handlers) {
266 uevent_handler->ColdbootDone();
267 }
268
264 // We use waitpid() in ColdBoot, so we can't ignore SIGCHLD until now. 269 // We use waitpid() in ColdBoot, so we can't ignore SIGCHLD until now.
265 signal(SIGCHLD, SIG_IGN); 270 signal(SIGCHLD, SIG_IGN);
266 // Reap and pending children that exited between the last call to waitpid() and setting SIG_IGN 271 // Reap and pending children that exited between the last call to waitpid() and setting SIG_IGN
@@ -268,10 +273,10 @@ int ueventd_main(int argc, char** argv) {
268 while (waitpid(-1, nullptr, WNOHANG) > 0) { 273 while (waitpid(-1, nullptr, WNOHANG) > 0) {
269 } 274 }
270 275
271 uevent_listener.Poll([&device_handler, &modalias_handler](const Uevent& uevent) { 276 uevent_listener.Poll([&uevent_handlers](const Uevent& uevent) {
272 HandleFirmwareEvent(uevent); 277 for (auto& uevent_handler : uevent_handlers) {
273 modalias_handler.HandleModaliasEvent(uevent); 278 uevent_handler->HandleUevent(uevent);
274 device_handler.HandleDeviceEvent(uevent); 279 }
275 return ListenerAction::kContinue; 280 return ListenerAction::kContinue;
276 }); 281 });
277 282
diff --git a/init/ueventd_parser.cpp b/init/ueventd_parser.cpp
index 54b0d16aa..677938e10 100644
--- a/init/ueventd_parser.cpp
+++ b/init/ueventd_parser.cpp
@@ -84,6 +84,23 @@ Result<Success> ParseFirmwareDirectoriesLine(std::vector<std::string>&& args,
84 return Success(); 84 return Success();
85} 85}
86 86
87Result<Success> ParseModaliasHandlingLine(std::vector<std::string>&& args,
88 bool* enable_modalias_handling) {
89 if (args.size() != 2) {
90 return Error() << "modalias_handling lines take exactly one parameter";
91 }
92
93 if (args[1] == "enabled") {
94 *enable_modalias_handling = true;
95 } else if (args[1] == "disabled") {
96 *enable_modalias_handling = false;
97 } else {
98 return Error() << "modalias_handling takes either 'enabled' or 'disabled' as a parameter";
99 }
100
101 return Success();
102}
103
87class SubsystemParser : public SectionParser { 104class SubsystemParser : public SectionParser {
88 public: 105 public:
89 SubsystemParser(std::vector<Subsystem>* subsystems) : subsystems_(subsystems) {} 106 SubsystemParser(std::vector<Subsystem>* subsystems) : subsystems_(subsystems) {}
@@ -182,6 +199,9 @@ UeventdConfiguration ParseConfig(const std::vector<std::string>& configs) {
182 parser.AddSingleLineParser("firmware_directories", 199 parser.AddSingleLineParser("firmware_directories",
183 std::bind(ParseFirmwareDirectoriesLine, _1, 200 std::bind(ParseFirmwareDirectoriesLine, _1,
184 &ueventd_configuration.firmware_directories)); 201 &ueventd_configuration.firmware_directories));
202 parser.AddSingleLineParser("modalias_handling",
203 std::bind(ParseModaliasHandlingLine, _1,
204 &ueventd_configuration.enable_modalias_handling));
185 205
186 for (const auto& config : configs) { 206 for (const auto& config : configs) {
187 parser.ParseConfig(config); 207 parser.ParseConfig(config);
diff --git a/init/ueventd_parser.h b/init/ueventd_parser.h
index 343d58bfd..7d30edf4f 100644
--- a/init/ueventd_parser.h
+++ b/init/ueventd_parser.h
@@ -30,6 +30,7 @@ struct UeventdConfiguration {
30 std::vector<SysfsPermissions> sysfs_permissions; 30 std::vector<SysfsPermissions> sysfs_permissions;
31 std::vector<Permissions> dev_permissions; 31 std::vector<Permissions> dev_permissions;
32 std::vector<std::string> firmware_directories; 32 std::vector<std::string> firmware_directories;
33 bool enable_modalias_handling = false;
33}; 34};
34 35
35UeventdConfiguration ParseConfig(const std::vector<std::string>& configs); 36UeventdConfiguration ParseConfig(const std::vector<std::string>& configs);