Merge "libprefetch: library to prefetch data using tracing." into main
diff --git a/fs_mgr/TEST_MAPPING b/fs_mgr/TEST_MAPPING
index 192232d..13af1e2 100644
--- a/fs_mgr/TEST_MAPPING
+++ b/fs_mgr/TEST_MAPPING
@@ -27,7 +27,9 @@
},
{
"name": "cow_api_test"
- },
+ }
+ ],
+ "postsubmit": [
{
"name": "snapuserd_test"
}
diff --git a/init/README.ueventd.md b/init/README.ueventd.md
index aac4acb..0e84c6f 100644
--- a/init/README.ueventd.md
+++ b/init/README.ueventd.md
@@ -76,17 +76,17 @@
When `/dev/null` is created, its mode will be set to `0666`, its user to `root` and its group to
`root`.
-The path can be modified using a ueventd.rc script and a `subsystem` section. There are three to set
-for a subsystem: the subsystem name, which device name to use, and which directory to place the
-device in. The section takes the below format of
+The path can be modified using a ueventd.rc script and a `subsystem` and/or `driver` section.
+There are three options to set for a subsystem or driver: the name, which device name to use,
+and which directory to place the device in. The section takes the below format of
subsystem <subsystem_name>
devname uevent_devname|uevent_devpath
[dirname <directory>]
-`subsystem_name` is used to match uevent `SUBSYSTEM` value
+`subsystem_name` is used to match the uevent `SUBSYSTEM` value.
-`devname` takes one of three options
+`devname` takes one of three options:
1. `uevent_devname` specifies that the name of the node will be the uevent `DEVNAME`
2. `uevent_devpath` specifies that the name of the node will be basename uevent `DEVPATH`
3. `sys_name` specifies that the name of the node will be the contents of `/sys/DEVPATH/name`
@@ -99,9 +99,13 @@
subsystem sound
devname uevent_devpath
dirname /dev/snd
-Indicates that all uevents with `SUBSYSTEM=sound` will create nodes as `/dev/snd/<basename uevent
+indicates that all uevents with `SUBSYSTEM=sound` will create nodes as `/dev/snd/<basename uevent
DEVPATH>`.
+The `driver` section has the exact same structure as a `subsystem` section, but
+will instead match the `DRIVER` value in a `bind`/`unbind` uevent. However, the
+`driver` section will be ignored for block devices.
+
## /sys
----
Ueventd by default takes no action for `/sys`, however it can be instructed to set permissions for
diff --git a/init/block_dev_initializer.cpp b/init/block_dev_initializer.cpp
index 7f83037..deb68e9 100644
--- a/init/block_dev_initializer.cpp
+++ b/init/block_dev_initializer.cpp
@@ -33,7 +33,8 @@
auto boot_devices = android::fs_mgr::GetBootDevices();
device_handler_ = std::make_unique<DeviceHandler>(
std::vector<Permissions>{}, std::vector<SysfsPermissions>{}, std::vector<Subsystem>{},
- std::move(boot_devices), android::fs_mgr::GetBootPartUuid(), false);
+ std::vector<Subsystem>{}, std::move(boot_devices), android::fs_mgr::GetBootPartUuid(),
+ false);
}
// If boot_part_uuid is specified, use it to set boot_devices
diff --git a/init/devices.cpp b/init/devices.cpp
index fafa58f..aeaa431 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -345,6 +345,26 @@
return FindSubsystemDevice(path, scsi_device_path, subsystem_paths);
}
+void DeviceHandler::TrackDeviceUevent(const Uevent& uevent) {
+ // No need to track any events if we won't bother handling any bind events
+ // later.
+ if (drivers_.size() == 0) return;
+
+ // Only track add, and not for block devices. We don't track remove because
+ // unbind events may arrive after remove events, so unbind will be the
+ // trigger to untrack those events.
+ if ((uevent.action != "add") || uevent.subsystem == "block" ||
+ (uevent.major < 0 || uevent.minor < 0)) {
+ return;
+ }
+
+ std::string path = sysfs_mount_point_ + uevent.path + "/device";
+ std::string device;
+ if (!Realpath(path, &device)) return;
+
+ tracked_uevents_.emplace_back(uevent, device);
+}
+
void DeviceHandler::FixupSysPermissions(const std::string& upath,
const std::string& subsystem) const {
// upaths omit the "/sys" that paths in this list
@@ -664,12 +684,53 @@
return true;
}
+void DeviceHandler::HandleBindInternal(std::string driver_name, std::string action,
+ const Uevent& uevent) {
+ if (uevent.subsystem == "block") {
+ LOG(FATAL) << "Tried to handle bind event for block device";
+ }
+
+ // Get tracked uevents for all devices that have this uevent's path as
+ // their canonical device path. Then handle those again if their driver
+ // is one of the ones we're interested in.
+ const auto driver = std::find(drivers_.cbegin(), drivers_.cend(), driver_name);
+ if (driver == drivers_.cend()) return;
+
+ std::string bind_path = sysfs_mount_point_ + uevent.path;
+ for (const TrackedUevent& tracked : tracked_uevents_) {
+ if (tracked.canonical_device_path != bind_path) continue;
+
+ LOG(VERBOSE) << "Propagating " << uevent.action << " as " << action << " for "
+ << uevent.path;
+
+ std::string devpath = driver->ParseDevPath(tracked.uevent);
+ mkdir_recursive(Dirname(devpath), 0755);
+ HandleDevice(action, devpath, false, tracked.uevent.major, tracked.uevent.minor,
+ std::vector<std::string>{});
+ }
+}
+
void DeviceHandler::HandleUevent(const Uevent& uevent) {
if (uevent.action == "add" || uevent.action == "change" || uevent.action == "bind" ||
uevent.action == "online") {
FixupSysPermissions(uevent.path, uevent.subsystem);
}
+ if (uevent.action == "bind") {
+ bound_drivers_[uevent.path] = uevent.driver;
+ HandleBindInternal(uevent.driver, "add", uevent);
+ return;
+ } else if (uevent.action == "unbind") {
+ if (bound_drivers_.count(uevent.path) == 0) return;
+ HandleBindInternal(bound_drivers_[uevent.path], "remove", uevent);
+
+ std::string sys_path = sysfs_mount_point_ + uevent.path;
+ std::erase_if(tracked_uevents_, [&sys_path](const TrackedUevent& tracked) {
+ return sys_path == tracked.canonical_device_path;
+ });
+ return;
+ }
+
// if it's not a /dev device, nothing to do
if (uevent.major < 0 || uevent.minor < 0) return;
@@ -677,6 +738,8 @@
std::vector<std::string> links;
bool block = false;
+ TrackDeviceUevent(uevent);
+
if (uevent.subsystem == "block") {
block = true;
devpath = "/dev/block/" + Basename(uevent.path);
@@ -725,10 +788,12 @@
DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions,
std::vector<SysfsPermissions> sysfs_permissions,
- std::vector<Subsystem> subsystems, std::set<std::string> boot_devices,
- std::string boot_part_uuid, bool skip_restorecon)
+ std::vector<Subsystem> drivers, std::vector<Subsystem> subsystems,
+ std::set<std::string> boot_devices, std::string boot_part_uuid,
+ bool skip_restorecon)
: dev_permissions_(std::move(dev_permissions)),
sysfs_permissions_(std::move(sysfs_permissions)),
+ drivers_(std::move(drivers)),
subsystems_(std::move(subsystems)),
boot_devices_(std::move(boot_devices)),
boot_part_uuid_(boot_part_uuid),
@@ -744,7 +809,8 @@
DeviceHandler::DeviceHandler()
: DeviceHandler(std::vector<Permissions>{}, std::vector<SysfsPermissions>{},
- std::vector<Subsystem>{}, std::set<std::string>{}, "", false) {}
+ std::vector<Subsystem>{}, std::vector<Subsystem>{}, std::set<std::string>{}, "",
+ false) {}
} // namespace init
} // namespace android
diff --git a/init/devices.h b/init/devices.h
index b8f8e54..69a2449 100644
--- a/init/devices.h
+++ b/init/devices.h
@@ -21,6 +21,7 @@
#include <sys/types.h>
#include <algorithm>
+#include <map>
#include <set>
#include <string>
#include <vector>
@@ -128,7 +129,7 @@
DeviceHandler();
DeviceHandler(std::vector<Permissions> dev_permissions,
- std::vector<SysfsPermissions> sysfs_permissions,
+ std::vector<SysfsPermissions> sysfs_permissions, std::vector<Subsystem> drivers,
std::vector<Subsystem> subsystems, std::set<std::string> boot_devices,
std::string boot_part_uuid, bool skip_restorecon);
virtual ~DeviceHandler() = default;
@@ -145,6 +146,11 @@
bool IsBootDevice(const Uevent& uevent) const;
private:
+ struct TrackedUevent {
+ Uevent uevent;
+ std::string canonical_device_path;
+ };
+
void ColdbootDone() override;
BlockDeviceInfo GetBlockDeviceInfo(const std::string& uevent_path) const;
bool FindSubsystemDevice(std::string path, std::string* device_path,
@@ -163,14 +169,21 @@
void FixupSysPermissions(const std::string& upath, const std::string& subsystem) const;
void HandleAshmemUevent(const Uevent& uevent);
+ void TrackDeviceUevent(const Uevent& uevent);
+ void HandleBindInternal(std::string driver_name, std::string action, const Uevent& uevent);
+
std::vector<Permissions> dev_permissions_;
std::vector<SysfsPermissions> sysfs_permissions_;
+ std::vector<Subsystem> drivers_;
std::vector<Subsystem> subsystems_;
std::set<std::string> boot_devices_;
std::string boot_part_uuid_;
bool found_boot_part_uuid_;
bool skip_restorecon_;
std::string sysfs_mount_point_;
+
+ std::vector<TrackedUevent> tracked_uevents_;
+ std::map<std::string, std::string> bound_drivers_;
};
// Exposed for testing
diff --git a/init/uevent.h b/init/uevent.h
index c8ca52a..e7ed226 100644
--- a/init/uevent.h
+++ b/init/uevent.h
@@ -26,6 +26,7 @@
std::string action;
std::string path;
std::string subsystem;
+ std::string driver;
std::string firmware;
std::string partition_name;
std::string partition_uuid;
diff --git a/init/uevent_listener.cpp b/init/uevent_listener.cpp
index 97f3de6..d329c17 100644
--- a/init/uevent_listener.cpp
+++ b/init/uevent_listener.cpp
@@ -36,6 +36,7 @@
uevent->action.clear();
uevent->path.clear();
uevent->subsystem.clear();
+ uevent->driver.clear();
uevent->firmware.clear();
uevent->partition_name.clear();
uevent->device_name.clear();
@@ -51,6 +52,9 @@
} else if (!strncmp(msg, "SUBSYSTEM=", 10)) {
msg += 10;
uevent->subsystem = msg;
+ } else if (!strncmp(msg, "DRIVER=", 7)) {
+ msg += 7;
+ uevent->driver = msg;
} else if (!strncmp(msg, "FIRMWARE=", 9)) {
msg += 9;
uevent->firmware = msg;
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 286e472..cb6b851 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -364,8 +364,8 @@
std::unique_ptr<DeviceHandler> device_handler = std::make_unique<DeviceHandler>(
std::move(ueventd_configuration.dev_permissions),
std::move(ueventd_configuration.sysfs_permissions),
- std::move(ueventd_configuration.subsystems), android::fs_mgr::GetBootDevices(),
- android::fs_mgr::GetBootPartUuid(), true);
+ std::move(ueventd_configuration.drivers), std::move(ueventd_configuration.subsystems),
+ android::fs_mgr::GetBootDevices(), android::fs_mgr::GetBootPartUuid(), true);
uevent_listener.RegenerateUevents([&](const Uevent& uevent) -> ListenerAction {
bool uuid_check_done = device_handler->CheckUeventForBootPartUuid(uevent);
return uuid_check_done ? ListenerAction::kStop : ListenerAction::kContinue;
diff --git a/init/ueventd_parser.cpp b/init/ueventd_parser.cpp
index 4395d88..097ef09 100644
--- a/init/ueventd_parser.cpp
+++ b/init/ueventd_parser.cpp
@@ -264,6 +264,8 @@
parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));
parser.AddSectionParser("subsystem",
std::make_unique<SubsystemParser>(&ueventd_configuration.subsystems));
+ parser.AddSectionParser("driver",
+ std::make_unique<SubsystemParser>(&ueventd_configuration.drivers));
using namespace std::placeholders;
parser.AddSingleLineParser(
diff --git a/init/ueventd_parser.h b/init/ueventd_parser.h
index 81f4e9d..ffe6072 100644
--- a/init/ueventd_parser.h
+++ b/init/ueventd_parser.h
@@ -27,6 +27,7 @@
struct UeventdConfiguration {
std::vector<Subsystem> subsystems;
+ std::vector<Subsystem> drivers;
std::vector<SysfsPermissions> sysfs_permissions;
std::vector<Permissions> dev_permissions;
std::vector<std::string> firmware_directories;
diff --git a/init/ueventd_parser_test.cpp b/init/ueventd_parser_test.cpp
index 41924e2..6d91039 100644
--- a/init/ueventd_parser_test.cpp
+++ b/init/ueventd_parser_test.cpp
@@ -106,7 +106,32 @@
{"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, Drivers) {
+ auto ueventd_file = R"(
+driver test_devname
+ devname uevent_devname
+
+driver test_devpath_no_dirname
+ devname uevent_devpath
+
+driver test_devname2
+ devname uevent_devname
+
+driver test_devpath_dirname
+ devname uevent_devpath
+ dirname /dev/graphics
+)";
+
+ auto drivers = std::vector<Subsystem>{
+ {"test_devname", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
+ {"test_devpath_no_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev"},
+ {"test_devname2", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
+ {"test_devpath_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev/graphics"}};
+
+ TestUeventdFile(ueventd_file, {{}, drivers, {}, {}, {}, {}, {}, {}});
}
TEST(ueventd_parser, Permissions) {
@@ -132,7 +157,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) {
@@ -148,7 +173,7 @@
"/more",
};
- TestUeventdFile(ueventd_file, {{}, {}, {}, firmware_directories, {}, {}});
+ TestUeventdFile(ueventd_file, {{}, {}, {}, {}, firmware_directories, {}, {}});
}
TEST(ueventd_parser, ExternalFirmwareHandlers) {
@@ -214,7 +239,7 @@
},
};
- TestUeventdFile(ueventd_file, {{}, {}, {}, {}, external_firmware_handlers, {}});
+ TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, external_firmware_handlers, {}});
}
TEST(ueventd_parser, ExternalFirmwareHandlersDuplicate) {
@@ -232,7 +257,7 @@
},
};
- TestUeventdFile(ueventd_file, {{}, {}, {}, {}, external_firmware_handlers, {}});
+ TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, external_firmware_handlers, {}});
}
TEST(ueventd_parser, ParallelRestoreconDirs) {
@@ -246,7 +271,7 @@
"/sys/devices",
};
- TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, parallel_restorecon_dirs});
+ TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, {}, parallel_restorecon_dirs});
}
TEST(ueventd_parser, UeventSocketRcvbufSize) {
@@ -255,7 +280,7 @@
uevent_socket_rcvbuf_size 8M
)";
- TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, {}, false, 8 * 1024 * 1024});
+ TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, {}, {}, false, 8 * 1024 * 1024});
}
TEST(ueventd_parser, EnabledDisabledLines) {
@@ -265,7 +290,7 @@
modalias_handling disabled
)";
- TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, {}, false, 0, true});
+ TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, {}, {}, false, 0, true});
auto ueventd_file2 = R"(
parallel_restorecon enabled
@@ -273,7 +298,7 @@
parallel_restorecon disabled
)";
- TestUeventdFile(ueventd_file2, {{}, {}, {}, {}, {}, {}, true, 0, false});
+ TestUeventdFile(ueventd_file2, {{}, {}, {}, {}, {}, {}, {}, true, 0, false});
}
TEST(ueventd_parser, AllTogether) {
@@ -286,6 +311,9 @@
subsystem test_devname
devname uevent_devname
+driver d_test_devpath
+ devname uevent_devpath
+
/dev/graphics/* 0660 root graphics
subsystem test_devpath_no_dirname
@@ -303,6 +331,10 @@
devname uevent_devpath
dirname /dev/graphics
+driver d_test_devname_dirname
+ devname uevent_devname
+ dirname /dev/sound
+
/dev/*/test 0660 root system
/sys/devices/virtual/*/input poll_delay 0660 root input no_fnm_pathname
firmware_directories /more
@@ -325,6 +357,10 @@
{"test_devname2", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
{"test_devpath_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev/graphics"}};
+ auto drivers = std::vector<Subsystem>{
+ {"d_test_devpath", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev"},
+ {"d_test_devname_dirname", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev/graphics"}};
+
auto permissions = std::vector<Permissions>{
{"/dev/rtc0", 0640, AID_SYSTEM, AID_SYSTEM, false},
{"/dev/graphics/*", 0660, AID_ROOT, AID_GRAPHICS, false},
@@ -356,7 +392,7 @@
size_t uevent_socket_rcvbuf_size = 6 * 1024 * 1024;
TestUeventdFile(ueventd_file,
- {subsystems, sysfs_permissions, permissions, firmware_directories,
+ {subsystems, drivers, sysfs_permissions, permissions, firmware_directories,
external_firmware_handlers, parallel_restorecon_dirs, true,
uevent_socket_rcvbuf_size, true});
}
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index 1039288..ec9b754 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -21,6 +21,17 @@
srcs: ["include/private/android_filesystem_config.h"],
}
+rust_bindgen {
+ name: "libandroid_ids",
+ crate_name: "android_ids",
+ source_stem: "bindings",
+ wrapper_src: "rust/aid_bindings.h",
+ header_libs: ["libcutils_headers"],
+ visibility: [
+ "//system/bpf/loader",
+ ],
+}
+
cc_defaults {
name: "libcutils_defaults",
cflags: [
diff --git a/libcutils/rust/aid_bindings.h b/libcutils/rust/aid_bindings.h
new file mode 100644
index 0000000..1b175a2
--- /dev/null
+++ b/libcutils/rust/aid_bindings.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <private/android_filesystem_config.h>
diff --git a/libprocessgroup/include/processgroup/processgroup.h b/libprocessgroup/include/processgroup/processgroup.h
index 6a026a7..d27b568 100644
--- a/libprocessgroup/include/processgroup/processgroup.h
+++ b/libprocessgroup/include/processgroup/processgroup.h
@@ -16,6 +16,7 @@
#pragma once
+#include <sys/cdefs.h>
#include <sys/types.h>
#include <initializer_list>
#include <span>
@@ -23,6 +24,8 @@
#include <string_view>
#include <vector>
+__BEGIN_DECLS
+
static constexpr std::string CGROUPV2_HIERARCHY_NAME = "cgroup2";
bool CgroupsAvailable();
@@ -36,6 +39,8 @@
bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector<std::string>& profiles);
bool SetUserProfiles(uid_t uid, const std::vector<std::string>& profiles);
+__END_DECLS
+
bool SetTaskProfiles(pid_t tid, std::initializer_list<std::string_view> profiles,
bool use_fd_cache = false);
bool SetProcessProfiles(uid_t uid, pid_t pid, std::initializer_list<std::string_view> profiles);
@@ -45,6 +50,7 @@
bool SetProcessProfiles(uid_t uid, pid_t pid, std::span<const std::string_view> profiles);
#endif
+__BEGIN_DECLS
#ifndef __ANDROID_VNDK__
@@ -90,3 +96,5 @@
bool isProfileValidForProcess(const std::string& profile_name, uid_t uid, pid_t pid);
#endif // __ANDROID_VNDK__
+
+__END_DECLS