diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-08-25 14:45:41 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-08-25 14:45:41 +0000 |
commit | 7e8f98d291dd6416a9804eecca46fe12ba4ecf71 (patch) | |
tree | 0a1befe55405dc14b81d490473d53c9c22e0b02c | |
parent | 3ec5f057fb0fbc71717d50128445975d8509cc2b (diff) | |
parent | 92651d78547c49e206d0601b6e7ad5d1efedc30b (diff) | |
download | core-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.cpp | 99 | ||||
-rw-r--r-- | libprocessgroup/task_profiles.cpp | 67 | ||||
-rw-r--r-- | libprocessgroup/task_profiles.h | 12 | ||||
-rw-r--r-- | libprocessgroup/task_profiles_test.cpp | 10 |
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_; |