Merge "Fixing flakiness in libfs_avb_internal_test"
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 4634283..24804d0 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -51,6 +51,7 @@
#include <android-base/test_utils.h>
#include <android-base/unique_fd.h>
#include <cutils/sockets.h>
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <libminijail.h>
@@ -65,6 +66,7 @@
using android::base::SendFileDescriptors;
using android::base::unique_fd;
+using ::testing::HasSubstr;
#if defined(__LP64__)
#define ARCH_SUFFIX "64"
@@ -307,6 +309,19 @@
*output = std::move(result);
}
+class LogcatCollector {
+ public:
+ LogcatCollector() { system("logcat -c"); }
+
+ void Collect(std::string* output) {
+ FILE* cmd_stdout = popen("logcat -d '*:S DEBUG'", "r");
+ ASSERT_NE(cmd_stdout, nullptr);
+ unique_fd tmp_fd(TEMP_FAILURE_RETRY(dup(fileno(cmd_stdout))));
+ ConsumeFd(std::move(tmp_fd), output);
+ pclose(cmd_stdout);
+ }
+};
+
TEST_F(CrasherTest, smoke) {
int intercept_result;
unique_fd output_fd;
@@ -441,6 +456,7 @@
}
GwpAsanTestParameters params = GetParam();
+ LogcatCollector logcat_collector;
int intercept_result;
unique_fd output_fd;
@@ -460,17 +476,18 @@
ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
- std::string result;
- ConsumeFd(std::move(output_fd), &result);
+ std::vector<std::string> log_sources(2);
+ ConsumeFd(std::move(output_fd), &log_sources[0]);
+ logcat_collector.Collect(&log_sources[1]);
- ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 2 \(SEGV_ACCERR\))");
- ASSERT_MATCH(result, R"(Cause: \[GWP-ASan\]: )" + params.cause_needle);
- if (params.free_before_access) {
- ASSERT_MATCH(result, R"(deallocated by thread .*
- #00 pc)");
+ for (const auto& result : log_sources) {
+ ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 2 \(SEGV_ACCERR\))");
+ ASSERT_MATCH(result, R"(Cause: \[GWP-ASan\]: )" + params.cause_needle);
+ if (params.free_before_access) {
+ ASSERT_MATCH(result, R"(deallocated by thread .*\n.*#00 pc)");
+ }
+ ASSERT_MATCH(result, R"((^|\s)allocated by thread .*\n.*#00 pc)");
}
- ASSERT_MATCH(result, R"(allocated by thread .*
- #00 pc)");
}
struct SizeParamCrasherTest : CrasherTest, testing::WithParamInterface<size_t> {};
@@ -488,6 +505,8 @@
return;
}
+ LogcatCollector logcat_collector;
+
int intercept_result;
unique_fd output_fd;
StartProcess([&]() {
@@ -504,16 +523,17 @@
ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
- std::string result;
- ConsumeFd(std::move(output_fd), &result);
+ std::vector<std::string> log_sources(2);
+ ConsumeFd(std::move(output_fd), &log_sources[0]);
+ logcat_collector.Collect(&log_sources[1]);
- ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\))");
- ASSERT_MATCH(result, R"(Cause: \[MTE\]: Use After Free, 0 bytes into a )" +
- std::to_string(GetParam()) + R"(-byte allocation)");
- ASSERT_MATCH(result, R"(deallocated by thread .*
- #00 pc)");
- ASSERT_MATCH(result, R"(allocated by thread .*
- #00 pc)");
+ for (const auto& result : log_sources) {
+ ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\))");
+ ASSERT_MATCH(result, R"(Cause: \[MTE\]: Use After Free, 0 bytes into a )" +
+ std::to_string(GetParam()) + R"(-byte allocation)");
+ ASSERT_MATCH(result, R"(deallocated by thread .*?\n.*#00 pc)");
+ ASSERT_MATCH(result, R"((^|\s)allocated by thread .*?\n.*#00 pc)");
+ }
#else
GTEST_SKIP() << "Requires aarch64";
#endif
@@ -557,6 +577,7 @@
GTEST_SKIP() << "Requires MTE";
}
+ LogcatCollector logcat_collector;
int intercept_result;
unique_fd output_fd;
StartProcess([&]() {
@@ -572,14 +593,16 @@
ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
- std::string result;
- ConsumeFd(std::move(output_fd), &result);
+ std::vector<std::string> log_sources(2);
+ ConsumeFd(std::move(output_fd), &log_sources[0]);
+ logcat_collector.Collect(&log_sources[1]);
- ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\))");
- ASSERT_MATCH(result, R"(Cause: \[MTE\]: Buffer Overflow, 0 bytes right of a )" +
- std::to_string(GetParam()) + R"(-byte allocation)");
- ASSERT_MATCH(result, R"(allocated by thread .*
- #00 pc)");
+ for (const auto& result : log_sources) {
+ ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\))");
+ ASSERT_MATCH(result, R"(Cause: \[MTE\]: Buffer Overflow, 0 bytes right of a )" +
+ std::to_string(GetParam()) + R"(-byte allocation)");
+ ASSERT_MATCH(result, R"((^|\s)allocated by thread .*?\n.*#00 pc)");
+ }
#else
GTEST_SKIP() << "Requires aarch64";
#endif
@@ -612,7 +635,7 @@
ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 9 \(SEGV_MTESERR\))");
ASSERT_MATCH(result, R"(Cause: \[MTE\]: Buffer Underflow, 4 bytes left of a )" +
std::to_string(GetParam()) + R"(-byte allocation)");
- ASSERT_MATCH(result, R"(allocated by thread .*
+ ASSERT_MATCH(result, R"((^|\s)allocated by thread .*
#00 pc)");
#else
GTEST_SKIP() << "Requires aarch64";
@@ -625,6 +648,8 @@
GTEST_SKIP() << "Requires MTE";
}
+ LogcatCollector logcat_collector;
+
int intercept_result;
unique_fd output_fd;
StartProcess([]() {
@@ -657,17 +682,23 @@
ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
- std::string result;
- ConsumeFd(std::move(output_fd), &result);
+ std::vector<std::string> log_sources(2);
+ ConsumeFd(std::move(output_fd), &log_sources[0]);
+ logcat_collector.Collect(&log_sources[1]);
- ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\))");
- ASSERT_MATCH(
- result,
- R"(Note: multiple potential causes for this crash were detected, listing them in decreasing order of probability.)");
-
- // Adjacent untracked allocations may cause us to see the wrong underflow here (or only
- // overflows), so we can't match explicitly for an underflow message.
- ASSERT_MATCH(result, R"(Cause: \[MTE\]: Buffer Overflow, 0 bytes right of a 16-byte allocation)");
+ for (const auto& result : log_sources) {
+ ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\))");
+ ASSERT_THAT(result, HasSubstr("Note: multiple potential causes for this crash were detected, "
+ "listing them in decreasing order of probability."));
+ // Adjacent untracked allocations may cause us to see the wrong underflow here (or only
+ // overflows), so we can't match explicitly for an underflow message.
+ ASSERT_MATCH(result,
+ R"(Cause: \[MTE\]: Buffer Overflow, 0 bytes right of a 16-byte allocation)");
+ // Ensure there's at least two allocation traces (one for each cause).
+ ASSERT_MATCH(
+ result,
+ R"((^|\s)allocated by thread .*?\n.*#00 pc(.|\n)*?(^|\s)allocated by thread .*?\n.*#00 pc)");
+ }
#else
GTEST_SKIP() << "Requires aarch64";
#endif
diff --git a/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp b/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
index b780b22..a932d48 100644
--- a/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
+++ b/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
@@ -272,14 +272,14 @@
if (tombstone.causes_size() > 1) {
CBS("");
- CBS("Note: multiple potential causes for this crash were detected, listing them in decreasing "
+ CBL("Note: multiple potential causes for this crash were detected, listing them in decreasing "
"order of probability.");
}
for (const Cause& cause : tombstone.causes()) {
if (tombstone.causes_size() > 1) {
CBS("");
- CBS("Cause: %s", cause.human_readable().c_str());
+ CBL("Cause: %s", cause.human_readable().c_str());
}
if (cause.has_memory_error() && cause.memory_error().has_heap()) {
@@ -287,14 +287,14 @@
if (heap_object.deallocation_backtrace_size() != 0) {
CBS("");
- CBS("deallocated by thread %" PRIu64 ":", heap_object.deallocation_tid());
- print_backtrace(callback, tombstone, heap_object.deallocation_backtrace(), false);
+ CBL("deallocated by thread %" PRIu64 ":", heap_object.deallocation_tid());
+ print_backtrace(callback, tombstone, heap_object.deallocation_backtrace(), true);
}
if (heap_object.allocation_backtrace_size() != 0) {
CBS("");
- CBS("allocated by thread %" PRIu64 ":", heap_object.allocation_tid());
- print_backtrace(callback, tombstone, heap_object.allocation_backtrace(), false);
+ CBL("allocated by thread %" PRIu64 ":", heap_object.allocation_tid());
+ print_backtrace(callback, tombstone, heap_object.allocation_backtrace(), true);
}
}
}
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index e5319a5..6a49fdf 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -166,6 +166,11 @@
"vbmeta_system.sig",
"vbmeta_system",
true, ImageType::BootCritical },
+ { "vbmeta_vendor",
+ "vbmeta_vendor.img",
+ "vbmeta_vendor.sig",
+ "vbmeta_vendor",
+ true, ImageType::BootCritical },
{ "vendor", "vendor.img", "vendor.sig", "vendor", true, ImageType::Normal },
{ "vendor_boot",
"vendor_boot.img", "vendor_boot.sig",
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 08ead7a..af71fe6 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -2266,6 +2266,26 @@
return LP_METADATA_DEFAULT_PARTITION_NAME;
}
+bool fs_mgr_create_canonical_mount_point(const std::string& mount_point) {
+ auto saved_errno = errno;
+ auto ok = true;
+ auto created_mount_point = !mkdir(mount_point.c_str(), 0755);
+ std::string real_mount_point;
+ if (!Realpath(mount_point, &real_mount_point)) {
+ ok = false;
+ PERROR << "failed to realpath(" << mount_point << ")";
+ } else if (mount_point != real_mount_point) {
+ ok = false;
+ LERROR << "mount point is not canonical: realpath(" << mount_point << ") -> "
+ << real_mount_point;
+ }
+ if (!ok && created_mount_point) {
+ rmdir(mount_point.c_str());
+ }
+ errno = saved_errno;
+ return ok;
+}
+
bool fs_mgr_mount_overlayfs_fstab_entry(const FstabEntry& entry) {
auto overlayfs_valid_result = fs_mgr_overlayfs_valid();
if (overlayfs_valid_result == OverlayfsValidResult::kNotSupported) {
@@ -2298,18 +2318,7 @@
}
#endif // ALLOW_ADBD_DISABLE_VERITY == 0
- // Create the mount point in case it doesn't exist.
- mkdir(entry.mount_point.c_str(), 0755);
-
- // Ensure that mount point exists and doesn't contain symbolic link or /../.
- std::string mount_point;
- if (!Realpath(entry.mount_point, &mount_point)) {
- PERROR << __FUNCTION__ << "(): failed to realpath " << entry.mount_point;
- return false;
- }
- if (entry.mount_point != mount_point) {
- LERROR << __FUNCTION__ << "(): mount point must be a canonicalized path: realpath "
- << entry.mount_point << " = " << mount_point;
+ if (!fs_mgr_create_canonical_mount_point(entry.mount_point)) {
return false;
}
diff --git a/fs_mgr/fs_mgr_remount.cpp b/fs_mgr/fs_mgr_remount.cpp
index e685070..5411aca 100644
--- a/fs_mgr/fs_mgr_remount.cpp
+++ b/fs_mgr/fs_mgr_remount.cpp
@@ -420,7 +420,8 @@
break;
}
// Find overlayfs mount point?
- if ((mount_point == "/") && (rentry.mount_point == "/system")) {
+ if ((mount_point == "/" && rentry.mount_point == "/system") ||
+ (mount_point == "/system" && rentry.mount_point == "/")) {
blk_device = rentry.blk_device;
mount_point = "/system";
found = true;
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index b8ebd63..4d3ecc9 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -132,6 +132,10 @@
// empty string
std::string fs_mgr_find_bow_device(const std::string& block_device);
+// Creates mount point if not already existed, and checks that mount point is a
+// canonical path that doesn't contain any symbolic link or /../.
+bool fs_mgr_create_canonical_mount_point(const std::string& mount_point);
+
// Like fs_mgr_do_mount_one() but for overlayfs fstab entries.
// Unlike fs_mgr_overlayfs, mount overlayfs without upperdir and workdir, so the
// filesystem cannot be remount read-write.
diff --git a/init/README.ueventd.md b/init/README.ueventd.md
index 76f5193..2401da3 100644
--- a/init/README.ueventd.md
+++ b/init/README.ueventd.md
@@ -163,3 +163,13 @@
from enabling the parallelization option:
parallel_restorecon enabled
+
+Do parallel restorecon to speed up boot process, subdirectories under `/sys`
+can be sliced by ueventd.rc, and run on multiple process.
+ parallel_restorecon_dir <directory>
+
+For example
+ parallel_restorecon_dir /sys
+ parallel_restorecon_dir /sys/devices
+ parallel_restorecon_dir /sys/devices/platform
+ parallel_restorecon_dir /sys/devices/platform/soc
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 546ea8e..f5c10bb 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -420,6 +420,10 @@
*end = begin + 1;
}
+ if (!fs_mgr_create_canonical_mount_point(begin->mount_point)) {
+ return false;
+ }
+
if (begin->fs_mgr_flags.logical) {
if (!fs_mgr_update_logical_partition(&(*begin))) {
return false;
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 331255b..68c6b51 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -115,11 +115,13 @@
public:
ColdBoot(UeventListener& uevent_listener,
std::vector<std::unique_ptr<UeventHandler>>& uevent_handlers,
- bool enable_parallel_restorecon)
+ bool enable_parallel_restorecon,
+ std::vector<std::string> parallel_restorecon_queue)
: uevent_listener_(uevent_listener),
uevent_handlers_(uevent_handlers),
num_handler_subprocesses_(std::thread::hardware_concurrency() ?: 4),
- enable_parallel_restorecon_(enable_parallel_restorecon) {}
+ enable_parallel_restorecon_(enable_parallel_restorecon),
+ parallel_restorecon_queue_(parallel_restorecon_queue) {}
void Run();
@@ -142,6 +144,8 @@
std::set<pid_t> subprocess_pids_;
std::vector<std::string> restorecon_queue_;
+
+ std::vector<std::string> parallel_restorecon_queue_;
};
void ColdBoot::UeventHandlerMain(unsigned int process_num, unsigned int total_processes) {
@@ -155,17 +159,34 @@
}
void ColdBoot::RestoreConHandler(unsigned int process_num, unsigned int total_processes) {
+ android::base::Timer t_process;
+
for (unsigned int i = process_num; i < restorecon_queue_.size(); i += total_processes) {
+ android::base::Timer t;
auto& dir = restorecon_queue_[i];
selinux_android_restorecon(dir.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE);
+
+ //Mark a dir restorecon operation for 50ms,
+ //Maybe you can add this dir to the ueventd.rc script to parallel processing
+ if (t.duration() > 50ms) {
+ LOG(INFO) << "took " << t.duration().count() <<"ms restorecon '"
+ << dir.c_str() << "' on process '" << process_num <<"'";
+ }
}
+
+ //Calculate process restorecon time
+ LOG(VERBOSE) << "took " << t_process.duration().count() << "ms on process '"
+ << process_num << "'";
}
void ColdBoot::GenerateRestoreCon(const std::string& directory) {
std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(directory.c_str()), &closedir);
- if (!dir) return;
+ if (!dir) {
+ PLOG(WARNING) << "opendir " << directory.c_str();
+ return;
+ }
struct dirent* dent;
while ((dent = readdir(dir.get())) != NULL) {
@@ -176,7 +197,10 @@
if (S_ISDIR(st.st_mode)) {
std::string fullpath = directory + "/" + dent->d_name;
- if (fullpath != "/sys/devices") {
+ auto parallel_restorecon =
+ std::find(parallel_restorecon_queue_.begin(),
+ parallel_restorecon_queue_.end(), fullpath);
+ if (parallel_restorecon == parallel_restorecon_queue_.end()) {
restorecon_queue_.emplace_back(fullpath);
}
}
@@ -248,11 +272,16 @@
RegenerateUevents();
if (enable_parallel_restorecon_) {
- selinux_android_restorecon("/sys", 0);
- selinux_android_restorecon("/sys/devices", 0);
- GenerateRestoreCon("/sys");
- // takes long time for /sys/devices, parallelize it
- GenerateRestoreCon("/sys/devices");
+ if (parallel_restorecon_queue_.empty()) {
+ parallel_restorecon_queue_.emplace_back("/sys");
+ // takes long time for /sys/devices, parallelize it
+ parallel_restorecon_queue_.emplace_back("/sys/devices");
+ LOG(INFO) << "Parallel processing directory is not set, set the default";
+ }
+ for (const auto& dir : parallel_restorecon_queue_) {
+ selinux_android_restorecon(dir.c_str(), 0);
+ GenerateRestoreCon(dir);
+ }
}
ForkSubProcesses();
@@ -268,14 +297,27 @@
}
static UeventdConfiguration GetConfiguration() {
- // TODO: Remove these legacy paths once Android S is no longer supported.
+ auto hardware = android::base::GetProperty("ro.hardware", "");
+ std::vector<std::string> legacy_paths{"/vendor/ueventd.rc", "/odm/ueventd.rc",
+ "/ueventd." + hardware + ".rc"};
+
+ std::vector<std::string> canonical{"/system/etc/ueventd.rc"};
+
if (android::base::GetIntProperty("ro.product.first_api_level", 10000) <= __ANDROID_API_S__) {
- auto hardware = android::base::GetProperty("ro.hardware", "");
- return ParseConfig({"/system/etc/ueventd.rc", "/vendor/ueventd.rc", "/odm/ueventd.rc",
- "/ueventd." + hardware + ".rc"});
+ // TODO: Remove these legacy paths once Android S is no longer supported.
+ canonical.insert(canonical.end(), legacy_paths.begin(), legacy_paths.end());
+ } else {
+ // Warn if newer device is using legacy paths.
+ for (const auto& path : legacy_paths) {
+ if (access(path.c_str(), F_OK) == 0) {
+ LOG(FATAL_WITHOUT_ABORT)
+ << "Legacy ueventd configuration file detected and will not be parsed: "
+ << path;
+ }
+ }
}
- return ParseConfig({"/system/etc/ueventd.rc"});
+ return ParseConfig(canonical);
}
int ueventd_main(int argc, char** argv) {
@@ -313,7 +355,8 @@
if (!android::base::GetBoolProperty(kColdBootDoneProp, false)) {
ColdBoot cold_boot(uevent_listener, uevent_handlers,
- ueventd_configuration.enable_parallel_restorecon);
+ ueventd_configuration.enable_parallel_restorecon,
+ ueventd_configuration.parallel_restorecon_dirs);
cold_boot.Run();
}
diff --git a/init/ueventd_parser.cpp b/init/ueventd_parser.cpp
index 9a14406..d34672e 100644
--- a/init/ueventd_parser.cpp
+++ b/init/ueventd_parser.cpp
@@ -151,6 +151,17 @@
return {};
}
+Result<void> ParseParallelRestoreconDirsLine(std::vector<std::string>&& args,
+ std::vector<std::string>* parallel_restorecon_dirs) {
+ if (args.size() != 2) {
+ return Error() << "parallel_restorecon_dir lines must have exactly 2 parameters";
+ }
+
+ std::move(std::next(args.begin()), args.end(), std::back_inserter(*parallel_restorecon_dirs));
+
+ return {};
+}
+
Result<void> ParseUeventSocketRcvbufSizeLine(std::vector<std::string>&& args,
size_t* uevent_socket_rcvbuf_size) {
if (args.size() != 2) {
@@ -268,6 +279,9 @@
parser.AddSingleLineParser("uevent_socket_rcvbuf_size",
std::bind(ParseUeventSocketRcvbufSizeLine, _1,
&ueventd_configuration.uevent_socket_rcvbuf_size));
+ parser.AddSingleLineParser("parallel_restorecon_dir",
+ std::bind(ParseParallelRestoreconDirsLine, _1,
+ &ueventd_configuration.parallel_restorecon_dirs));
parser.AddSingleLineParser("parallel_restorecon",
std::bind(ParseEnabledDisabledLine, _1,
&ueventd_configuration.enable_parallel_restorecon));
diff --git a/init/ueventd_parser.h b/init/ueventd_parser.h
index eaafa5a..81f4e9d 100644
--- a/init/ueventd_parser.h
+++ b/init/ueventd_parser.h
@@ -31,6 +31,7 @@
std::vector<Permissions> dev_permissions;
std::vector<std::string> firmware_directories;
std::vector<ExternalFirmwareHandler> external_firmware_handlers;
+ std::vector<std::string> parallel_restorecon_dirs;
bool enable_modalias_handling = false;
size_t uevent_socket_rcvbuf_size = 0;
bool enable_parallel_restorecon = false;
diff --git a/init/ueventd_parser_test.cpp b/init/ueventd_parser_test.cpp
index d77cb03..41924e2 100644
--- a/init/ueventd_parser_test.cpp
+++ b/init/ueventd_parser_test.cpp
@@ -77,6 +77,7 @@
EXPECT_EQ(expected.firmware_directories, result.firmware_directories);
TestVector(expected.external_firmware_handlers, result.external_firmware_handlers,
TestExternalFirmwareHandler);
+ EXPECT_EQ(expected.parallel_restorecon_dirs, result.parallel_restorecon_dirs);
}
TEST(ueventd_parser, EmptyFile) {
@@ -105,7 +106,7 @@
{"test_devname2", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
{"test_devpath_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev/graphics"}};
- TestUeventdFile(ueventd_file, {subsystems, {}, {}, {}, {}});
+ TestUeventdFile(ueventd_file, {subsystems, {}, {}, {}, {}, {}});
}
TEST(ueventd_parser, Permissions) {
@@ -131,7 +132,7 @@
{"/sys/devices/virtual/*/input", "poll_delay", 0660, AID_ROOT, AID_INPUT, true},
};
- TestUeventdFile(ueventd_file, {{}, sysfs_permissions, permissions, {}, {}});
+ TestUeventdFile(ueventd_file, {{}, sysfs_permissions, permissions, {}, {}, {}});
}
TEST(ueventd_parser, FirmwareDirectories) {
@@ -147,7 +148,7 @@
"/more",
};
- TestUeventdFile(ueventd_file, {{}, {}, {}, firmware_directories, {}});
+ TestUeventdFile(ueventd_file, {{}, {}, {}, firmware_directories, {}, {}});
}
TEST(ueventd_parser, ExternalFirmwareHandlers) {
@@ -213,7 +214,7 @@
},
};
- TestUeventdFile(ueventd_file, {{}, {}, {}, {}, external_firmware_handlers});
+ TestUeventdFile(ueventd_file, {{}, {}, {}, {}, external_firmware_handlers, {}});
}
TEST(ueventd_parser, ExternalFirmwareHandlersDuplicate) {
@@ -231,7 +232,21 @@
},
};
- TestUeventdFile(ueventd_file, {{}, {}, {}, {}, external_firmware_handlers});
+ TestUeventdFile(ueventd_file, {{}, {}, {}, {}, external_firmware_handlers, {}});
+}
+
+TEST(ueventd_parser, ParallelRestoreconDirs) {
+ auto ueventd_file = R"(
+parallel_restorecon_dir /sys
+parallel_restorecon_dir /sys/devices
+)";
+
+ auto parallel_restorecon_dirs = std::vector<std::string>{
+ "/sys",
+ "/sys/devices",
+ };
+
+ TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, parallel_restorecon_dirs});
}
TEST(ueventd_parser, UeventSocketRcvbufSize) {
@@ -240,7 +255,7 @@
uevent_socket_rcvbuf_size 8M
)";
- TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, false, 8 * 1024 * 1024});
+ TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, {}, false, 8 * 1024 * 1024});
}
TEST(ueventd_parser, EnabledDisabledLines) {
@@ -250,7 +265,7 @@
modalias_handling disabled
)";
- TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, false, 0, true});
+ TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, {}, false, 0, true});
auto ueventd_file2 = R"(
parallel_restorecon enabled
@@ -258,7 +273,7 @@
parallel_restorecon disabled
)";
- TestUeventdFile(ueventd_file2, {{}, {}, {}, {}, {}, true, 0, false});
+ TestUeventdFile(ueventd_file2, {{}, {}, {}, {}, {}, {}, true, 0, false});
}
TEST(ueventd_parser, AllTogether) {
@@ -298,6 +313,9 @@
modalias_handling enabled
parallel_restorecon enabled
+parallel_restorecon_dir /sys
+parallel_restorecon_dir /sys/devices
+
#ending comment
)";
@@ -330,11 +348,17 @@
{"/devices/path/firmware/firmware001.bin", AID_ROOT, AID_ROOT, "/vendor/bin/touch.sh"},
};
+ auto parallel_restorecon_dirs = std::vector<std::string>{
+ "/sys",
+ "/sys/devices",
+ };
+
size_t uevent_socket_rcvbuf_size = 6 * 1024 * 1024;
TestUeventdFile(ueventd_file,
{subsystems, sysfs_permissions, permissions, firmware_directories,
- external_firmware_handlers, true, uevent_socket_rcvbuf_size, true});
+ external_firmware_handlers, parallel_restorecon_dirs, true,
+ uevent_socket_rcvbuf_size, true});
}
// All of these lines are ill-formed, so test that there is 0 output.
@@ -366,6 +390,9 @@
external_firmware_handler blah blah
external_firmware_handler blah blah blah blah
+parallel_restorecon_dir
+parallel_restorecon_dir /sys /sys/devices
+
)";
TestUeventdFile(ueventd_file, {});