summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-08-25 14:45:41 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-08-25 14:45:41 +0000
commit7e8f98d291dd6416a9804eecca46fe12ba4ecf71 (patch)
tree0a1befe55405dc14b81d490473d53c9c22e0b02c
parent3ec5f057fb0fbc71717d50128445975d8509cc2b (diff)
parent92651d78547c49e206d0601b6e7ad5d1efedc30b (diff)
downloadcore-7e8f98d291dd6416a9804eecca46fe12ba4ecf71.tar.gz
Snap for 10716635 from 92651d78547c49e206d0601b6e7ad5d1efedc30b to mainline-neuralnetworks-releaseaml_neu_341010080aml_neu_341010000
Change-Id: I7a1d5106a4b75bdf2b16df9d10576ca346a51eb8
-rw-r--r--init/property_service.cpp99
-rw-r--r--libprocessgroup/task_profiles.cpp67
-rw-r--r--libprocessgroup/task_profiles.h12
-rw-r--r--libprocessgroup/task_profiles_test.cpp10
4 files changed, 103 insertions, 85 deletions
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 4242912ed..8da69822c 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -57,12 +57,12 @@
#include <android-base/result.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
-#include <private/android_filesystem_config.h>
#include <property_info_parser/property_info_parser.h>
#include <property_info_serializer/property_info_serializer.h>
#include <selinux/android.h>
#include <selinux/label.h>
#include <selinux/selinux.h>
+
#include "debug_ramdisk.h"
#include "epoll.h"
#include "init.h"
@@ -111,12 +111,12 @@ constexpr auto API_LEVEL_CURRENT = 10000;
static bool persistent_properties_loaded = false;
+static int property_set_fd = -1;
static int from_init_socket = -1;
static int init_socket = -1;
static bool accept_messages = false;
static std::mutex accept_messages_lock;
static std::thread property_service_thread;
-static std::thread property_service_for_system_thread;
static std::unique_ptr<PersistWriteThread> persist_write_thread;
@@ -394,37 +394,31 @@ static std::optional<uint32_t> PropertySet(const std::string& name, const std::s
return {PROP_ERROR_INVALID_VALUE};
}
- if (name == "sys.powerctl") {
- // No action here - NotifyPropertyChange will trigger the appropriate action, and since this
- // can come to the second thread, we mustn't call out to the __system_property_* functions
- // which support multiple readers but only one mutator.
- } else {
- prop_info* pi = (prop_info*)__system_property_find(name.c_str());
- if (pi != nullptr) {
- // ro.* properties are actually "write-once".
- if (StartsWith(name, "ro.")) {
- *error = "Read-only property was already set";
- return {PROP_ERROR_READ_ONLY_PROPERTY};
- }
+ prop_info* pi = (prop_info*)__system_property_find(name.c_str());
+ if (pi != nullptr) {
+ // ro.* properties are actually "write-once".
+ if (StartsWith(name, "ro.")) {
+ *error = "Read-only property was already set";
+ return {PROP_ERROR_READ_ONLY_PROPERTY};
+ }
- __system_property_update(pi, value.c_str(), valuelen);
- } else {
- int rc = __system_property_add(name.c_str(), name.size(), value.c_str(), valuelen);
- if (rc < 0) {
- *error = "__system_property_add failed";
- return {PROP_ERROR_SET_FAILED};
- }
+ __system_property_update(pi, value.c_str(), valuelen);
+ } else {
+ int rc = __system_property_add(name.c_str(), name.size(), value.c_str(), valuelen);
+ if (rc < 0) {
+ *error = "__system_property_add failed";
+ return {PROP_ERROR_SET_FAILED};
}
+ }
- // Don't write properties to disk until after we have read all default
- // properties to prevent them from being overwritten by default values.
- if (socket && persistent_properties_loaded && StartsWith(name, "persist.")) {
- if (persist_write_thread) {
- persist_write_thread->Write(name, value, std::move(*socket));
- return {};
- }
- WritePersistentProperty(name, value);
+ // Don't write properties to disk until after we have read all default
+ // properties to prevent them from being overwritten by default values.
+ if (socket && persistent_properties_loaded && StartsWith(name, "persist.")) {
+ if (persist_write_thread) {
+ persist_write_thread->Write(name, value, std::move(*socket));
+ return {};
}
+ WritePersistentProperty(name, value);
}
NotifyPropertyChange(name, value);
@@ -585,10 +579,10 @@ uint32_t HandlePropertySetNoSocket(const std::string& name, const std::string& v
return *ret;
}
-static void handle_property_set_fd(int fd) {
+static void handle_property_set_fd() {
static constexpr uint32_t kDefaultSocketTimeout = 2000; /* ms */
- int s = accept4(fd, nullptr, nullptr, SOCK_CLOEXEC);
+ int s = accept4(property_set_fd, nullptr, nullptr, SOCK_CLOEXEC);
if (s == -1) {
return;
}
@@ -1425,21 +1419,19 @@ static void HandleInitSocket() {
}
}
-static void PropertyServiceThread(int fd, bool listen_init) {
+static void PropertyServiceThread() {
Epoll epoll;
if (auto result = epoll.Open(); !result.ok()) {
LOG(FATAL) << result.error();
}
- if (auto result = epoll.RegisterHandler(fd, std::bind(handle_property_set_fd, fd));
+ if (auto result = epoll.RegisterHandler(property_set_fd, handle_property_set_fd);
!result.ok()) {
LOG(FATAL) << result.error();
}
- if (listen_init) {
- if (auto result = epoll.RegisterHandler(init_socket, HandleInitSocket); !result.ok()) {
- LOG(FATAL) << result.error();
- }
+ if (auto result = epoll.RegisterHandler(init_socket, HandleInitSocket); !result.ok()) {
+ LOG(FATAL) << result.error();
}
while (true) {
@@ -1490,23 +1482,6 @@ void PersistWriteThread::Write(std::string name, std::string value, SocketConnec
cv_.notify_all();
}
-void StartThread(const char* name, int mode, int gid, std::thread& t, bool listen_init) {
- int fd = -1;
- if (auto result = CreateSocket(name, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
- /*passcred=*/false, /*should_listen=*/false, mode, /*uid=*/0,
- /*gid=*/gid, /*socketcon=*/{});
- result.ok()) {
- fd = *result;
- } else {
- LOG(FATAL) << "start_property_service socket creation failed: " << result.error();
- }
-
- listen(fd, 8);
-
- auto new_thread = std::thread(PropertyServiceThread, fd, listen_init);
- t.swap(new_thread);
-}
-
void StartPropertyService(int* epoll_socket) {
InitPropertySet("ro.property_service.version", "2");
@@ -1518,9 +1493,19 @@ void StartPropertyService(int* epoll_socket) {
init_socket = sockets[1];
StartSendingMessages();
- StartThread(PROP_SERVICE_FOR_SYSTEM_NAME, 0660, AID_SYSTEM, property_service_for_system_thread,
- true);
- StartThread(PROP_SERVICE_NAME, 0666, 0, property_service_thread, false);
+ if (auto result = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
+ /*passcred=*/false, /*should_listen=*/false, 0666, /*uid=*/0,
+ /*gid=*/0, /*socketcon=*/{});
+ result.ok()) {
+ property_set_fd = *result;
+ } else {
+ LOG(FATAL) << "start_property_service socket creation failed: " << result.error();
+ }
+
+ listen(property_set_fd, 8);
+
+ auto new_thread = std::thread{PropertyServiceThread};
+ property_service_thread.swap(new_thread);
auto async_persist_writes =
android::base::GetBoolProperty("ro.property_service.async_persist_writes", false);
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index 44dba2a16..f51b07671 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -114,9 +114,26 @@ bool FdCacheHelper::IsAppDependentPath(const std::string& path) {
IProfileAttribute::~IProfileAttribute() = default;
-void ProfileAttribute::Reset(const CgroupController& controller, const std::string& file_name) {
+const std::string& ProfileAttribute::file_name() const {
+ if (controller()->version() == 2 && !file_v2_name_.empty()) return file_v2_name_;
+ return file_name_;
+}
+
+void ProfileAttribute::Reset(const CgroupController& controller, const std::string& file_name,
+ const std::string& file_v2_name) {
controller_ = controller;
file_name_ = file_name;
+ file_v2_name_ = file_v2_name;
+}
+
+bool ProfileAttribute::GetPathForProcess(uid_t uid, pid_t pid, std::string* path) const {
+ if (controller()->version() == 2) {
+ // all cgroup v2 attributes use the same process group hierarchy
+ *path = StringPrintf("%s/uid_%u/pid_%d/%s", controller()->path(), uid, pid,
+ file_name().c_str());
+ return true;
+ }
+ return GetPathForTask(pid, path);
}
bool ProfileAttribute::GetPathForTask(int tid, std::string* path) const {
@@ -129,12 +146,11 @@ bool ProfileAttribute::GetPathForTask(int tid, std::string* path) const {
return true;
}
- const std::string& file_name =
- controller()->version() == 2 && !file_v2_name_.empty() ? file_v2_name_ : file_name_;
if (subgroup.empty()) {
- *path = StringPrintf("%s/%s", controller()->path(), file_name.c_str());
+ *path = StringPrintf("%s/%s", controller()->path(), file_name().c_str());
} else {
- *path = StringPrintf("%s/%s/%s", controller()->path(), subgroup.c_str(), file_name.c_str());
+ *path = StringPrintf("%s/%s/%s", controller()->path(), subgroup.c_str(),
+ file_name().c_str());
}
return true;
}
@@ -144,9 +160,7 @@ bool ProfileAttribute::GetPathForUID(uid_t uid, std::string* path) const {
return true;
}
- const std::string& file_name =
- controller()->version() == 2 && !file_v2_name_.empty() ? file_v2_name_ : file_name_;
- *path = StringPrintf("%s/uid_%d/%s", controller()->path(), uid, file_name.c_str());
+ *path = StringPrintf("%s/uid_%u/%s", controller()->path(), uid, file_name().c_str());
return true;
}
@@ -205,18 +219,7 @@ bool SetTimerSlackAction::ExecuteForTask(int) const {
#endif
-bool SetAttributeAction::ExecuteForProcess(uid_t, pid_t pid) const {
- return ExecuteForTask(pid);
-}
-
-bool SetAttributeAction::ExecuteForTask(int tid) const {
- std::string path;
-
- if (!attribute_->GetPathForTask(tid, &path)) {
- LOG(ERROR) << "Failed to find cgroup for tid " << tid;
- return false;
- }
-
+bool SetAttributeAction::WriteValueToFile(const std::string& path) const {
if (!WriteStringToFile(value_, path)) {
if (access(path.c_str(), F_OK) < 0) {
if (optional_) {
@@ -236,6 +239,28 @@ bool SetAttributeAction::ExecuteForTask(int tid) const {
return true;
}
+bool SetAttributeAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
+ std::string path;
+
+ if (!attribute_->GetPathForProcess(uid, pid, &path)) {
+ LOG(ERROR) << "Failed to find cgroup for uid " << uid << " pid " << pid;
+ return false;
+ }
+
+ return WriteValueToFile(path);
+}
+
+bool SetAttributeAction::ExecuteForTask(int tid) const {
+ std::string path;
+
+ if (!attribute_->GetPathForTask(tid, &path)) {
+ LOG(ERROR) << "Failed to find cgroup for tid " << tid;
+ return false;
+ }
+
+ return WriteValueToFile(path);
+}
+
bool SetAttributeAction::ExecuteForUID(uid_t uid) const {
std::string path;
@@ -816,7 +841,7 @@ bool TaskProfiles::Load(const CgroupMap& cg_map, const std::string& file_name) {
attributes_[name] =
std::make_unique<ProfileAttribute>(controller, file_attr, file_v2_attr);
} else {
- iter->second->Reset(controller, file_attr);
+ iter->second->Reset(controller, file_attr, file_v2_attr);
}
} else {
LOG(WARNING) << "Controller " << controller_name << " is not found";
diff --git a/libprocessgroup/task_profiles.h b/libprocessgroup/task_profiles.h
index a62c5b0a9..4663f64e2 100644
--- a/libprocessgroup/task_profiles.h
+++ b/libprocessgroup/task_profiles.h
@@ -32,9 +32,11 @@
class IProfileAttribute {
public:
virtual ~IProfileAttribute() = 0;
- virtual void Reset(const CgroupController& controller, const std::string& file_name) = 0;
+ virtual void Reset(const CgroupController& controller, const std::string& file_name,
+ const std::string& file_v2_name) = 0;
virtual const CgroupController* controller() const = 0;
virtual const std::string& file_name() const = 0;
+ virtual bool GetPathForProcess(uid_t uid, pid_t pid, std::string* path) const = 0;
virtual bool GetPathForTask(int tid, std::string* path) const = 0;
virtual bool GetPathForUID(uid_t uid, std::string* path) const = 0;
};
@@ -50,9 +52,11 @@ class ProfileAttribute : public IProfileAttribute {
~ProfileAttribute() = default;
const CgroupController* controller() const override { return &controller_; }
- const std::string& file_name() const override { return file_name_; }
- void Reset(const CgroupController& controller, const std::string& file_name) override;
+ const std::string& file_name() const override;
+ void Reset(const CgroupController& controller, const std::string& file_name,
+ const std::string& file_v2_name) override;
+ bool GetPathForProcess(uid_t uid, pid_t pid, std::string* path) const override;
bool GetPathForTask(int tid, std::string* path) const override;
bool GetPathForUID(uid_t uid, std::string* path) const override;
@@ -131,6 +135,8 @@ class SetAttributeAction : public ProfileAction {
const IProfileAttribute* attribute_;
std::string value_;
bool optional_;
+
+ bool WriteValueToFile(const std::string& path) const;
};
// Set cgroup profile element
diff --git a/libprocessgroup/task_profiles_test.cpp b/libprocessgroup/task_profiles_test.cpp
index eadbe7697..99d819a7c 100644
--- a/libprocessgroup/task_profiles_test.cpp
+++ b/libprocessgroup/task_profiles_test.cpp
@@ -102,7 +102,8 @@ class ProfileAttributeMock : public IProfileAttribute {
public:
ProfileAttributeMock(const std::string& file_name) : file_name_(file_name) {}
~ProfileAttributeMock() override = default;
- void Reset(const CgroupController& controller, const std::string& file_name) override {
+ void Reset(const CgroupController& controller, const std::string& file_name,
+ const std::string& file_v2_name) override {
CHECK(false);
}
const CgroupController* controller() const override {
@@ -110,6 +111,9 @@ class ProfileAttributeMock : public IProfileAttribute {
return {};
}
const std::string& file_name() const override { return file_name_; }
+ bool GetPathForProcess(uid_t uid, pid_t pid, std::string* path) const override {
+ return GetPathForTask(pid, path);
+ }
bool GetPathForTask(int tid, std::string* path) const override {
#ifdef __ANDROID__
CHECK(CgroupGetControllerPath(CGROUPV2_CONTROLLER_NAME, path));
@@ -125,9 +129,7 @@ class ProfileAttributeMock : public IProfileAttribute {
return true;
};
- bool GetPathForUID(uid_t, std::string*) const override {
- return false;
- }
+ bool GetPathForUID(uid_t, std::string*) const override { return false; }
private:
const std::string file_name_;