libprocessgroup: Use pid_t consistently for TIDs
Test: m Change-Id: I6e95870e6c5855bfe03be3be8f7a8884147bc15d
This commit is contained in:
parent
d6fb2259f6
commit
1c007996b3
7 changed files with 54 additions and 51 deletions
|
@ -104,7 +104,7 @@ std::string CgroupController::GetProcsFilePath(const std::string& rel_path, uid_
|
|||
return proc_path.append(CGROUP_PROCS_FILE);
|
||||
}
|
||||
|
||||
bool CgroupController::GetTaskGroup(int tid, std::string* group) const {
|
||||
bool CgroupController::GetTaskGroup(pid_t tid, std::string* group) const {
|
||||
std::string file_name = StringPrintf("/proc/%d/cgroup", tid);
|
||||
std::string content;
|
||||
if (!android::base::ReadFileToString(file_name, &content)) {
|
||||
|
|
|
@ -43,7 +43,8 @@ class CgroupController {
|
|||
|
||||
std::string GetTasksFilePath(const std::string& path) const;
|
||||
std::string GetProcsFilePath(const std::string& path, uid_t uid, pid_t pid) const;
|
||||
bool GetTaskGroup(int tid, std::string* group) const;
|
||||
bool GetTaskGroup(pid_t tid, std::string* group) const;
|
||||
|
||||
private:
|
||||
enum ControllerState {
|
||||
UNKNOWN = 0,
|
||||
|
|
|
@ -33,19 +33,20 @@ bool CgroupsAvailable();
|
|||
bool CgroupGetControllerPath(const std::string& cgroup_name, std::string* path);
|
||||
bool CgroupGetControllerFromPath(const std::string& path, std::string* cgroup_name);
|
||||
bool CgroupGetAttributePath(const std::string& attr_name, std::string* path);
|
||||
bool CgroupGetAttributePathForTask(const std::string& attr_name, int tid, std::string* path);
|
||||
bool CgroupGetAttributePathForTask(const std::string& attr_name, pid_t tid, std::string* path);
|
||||
|
||||
bool SetTaskProfiles(int tid, const std::vector<std::string>& profiles, bool use_fd_cache = false);
|
||||
bool SetTaskProfiles(pid_t tid, const std::vector<std::string>& profiles,
|
||||
bool use_fd_cache = false);
|
||||
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(int tid, std::initializer_list<std::string_view> profiles,
|
||||
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);
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
bool SetTaskProfiles(int tid, std::span<const std::string_view> profiles,
|
||||
bool SetTaskProfiles(pid_t tid, std::span<const std::string_view> profiles,
|
||||
bool use_fd_cache = false);
|
||||
bool SetProcessProfiles(uid_t uid, pid_t pid, std::span<const std::string_view> profiles);
|
||||
#endif
|
||||
|
@ -91,7 +92,7 @@ void removeAllEmptyProcessGroups(void);
|
|||
|
||||
// Provides the path for an attribute in a specific process group
|
||||
// Returns false in case of error, true in case of success
|
||||
bool getAttributePathForTask(const std::string& attr_name, int tid, std::string* path);
|
||||
bool getAttributePathForTask(const std::string& attr_name, pid_t tid, std::string* path);
|
||||
|
||||
// Check if a profile can be applied without failing.
|
||||
// Returns true if it can be applied without failing, false otherwise
|
||||
|
|
|
@ -147,7 +147,7 @@ bool CgroupGetAttributePath(const std::string& attr_name, std::string* path) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CgroupGetAttributePathForTask(const std::string& attr_name, int tid, std::string* path) {
|
||||
bool CgroupGetAttributePathForTask(const std::string& attr_name, pid_t tid, std::string* path) {
|
||||
const TaskProfiles& tp = TaskProfiles::GetInstance();
|
||||
const IProfileAttribute* attr = tp.GetAttribute(attr_name);
|
||||
|
||||
|
@ -198,17 +198,18 @@ bool SetProcessProfilesCached(uid_t uid, pid_t pid, const std::vector<std::strin
|
|||
uid, pid, std::span<const std::string>(profiles), true);
|
||||
}
|
||||
|
||||
bool SetTaskProfiles(int tid, const std::vector<std::string>& profiles, bool use_fd_cache) {
|
||||
bool SetTaskProfiles(pid_t tid, const std::vector<std::string>& profiles, bool use_fd_cache) {
|
||||
return TaskProfiles::GetInstance().SetTaskProfiles(tid, std::span<const std::string>(profiles),
|
||||
use_fd_cache);
|
||||
}
|
||||
|
||||
bool SetTaskProfiles(int tid, std::initializer_list<std::string_view> profiles, bool use_fd_cache) {
|
||||
bool SetTaskProfiles(pid_t tid, std::initializer_list<std::string_view> profiles,
|
||||
bool use_fd_cache) {
|
||||
return TaskProfiles::GetInstance().SetTaskProfiles(
|
||||
tid, std::span<const std::string_view>(profiles), use_fd_cache);
|
||||
}
|
||||
|
||||
bool SetTaskProfiles(int tid, std::span<const std::string_view> profiles, bool use_fd_cache) {
|
||||
bool SetTaskProfiles(pid_t tid, std::span<const std::string_view> profiles, bool use_fd_cache) {
|
||||
return TaskProfiles::GetInstance().SetTaskProfiles(tid, profiles, use_fd_cache);
|
||||
}
|
||||
|
||||
|
@ -712,7 +713,7 @@ int createProcessGroup(uid_t uid, pid_t initialPid, bool memControl) {
|
|||
return createProcessGroupInternal(uid, initialPid, cgroup, true);
|
||||
}
|
||||
|
||||
static bool SetProcessGroupValue(int tid, const std::string& attr_name, int64_t value) {
|
||||
static bool SetProcessGroupValue(pid_t tid, const std::string& attr_name, int64_t value) {
|
||||
if (!isMemoryCgroupSupported()) {
|
||||
LOG(ERROR) << "Memcg is not mounted.";
|
||||
return false;
|
||||
|
@ -743,7 +744,7 @@ bool setProcessGroupLimit(uid_t, pid_t pid, int64_t limit_in_bytes) {
|
|||
return SetProcessGroupValue(pid, "MemLimit", limit_in_bytes);
|
||||
}
|
||||
|
||||
bool getAttributePathForTask(const std::string& attr_name, int tid, std::string* path) {
|
||||
bool getAttributePathForTask(const std::string& attr_name, pid_t tid, std::string* path) {
|
||||
return CgroupGetAttributePathForTask(attr_name, tid, path);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ static inline SchedPolicy _policy(SchedPolicy p) {
|
|||
|
||||
#if defined(__ANDROID__)
|
||||
|
||||
int set_cpuset_policy(int tid, SchedPolicy policy) {
|
||||
int set_cpuset_policy(pid_t tid, SchedPolicy policy) {
|
||||
if (tid == 0) {
|
||||
tid = GetThreadId();
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ int set_cpuset_policy(int tid, SchedPolicy policy) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int set_sched_policy(int tid, SchedPolicy policy) {
|
||||
int set_sched_policy(pid_t tid, SchedPolicy policy) {
|
||||
if (tid == 0) {
|
||||
tid = GetThreadId();
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ bool schedboost_enabled() {
|
|||
return enabled;
|
||||
}
|
||||
|
||||
static int getCGroupSubsys(int tid, const char* subsys, std::string& subgroup) {
|
||||
static int getCGroupSubsys(pid_t tid, const char* subsys, std::string& subgroup) {
|
||||
auto controller = CgroupMap::GetInstance().FindController(subsys);
|
||||
|
||||
if (!controller.IsUsable()) return -1;
|
||||
|
@ -185,7 +185,7 @@ static int get_sched_policy_from_group(const std::string& group, SchedPolicy* po
|
|||
return 0;
|
||||
}
|
||||
|
||||
int get_sched_policy(int tid, SchedPolicy* policy) {
|
||||
int get_sched_policy(pid_t tid, SchedPolicy* policy) {
|
||||
if (tid == 0) {
|
||||
tid = GetThreadId();
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ bool ProfileAttribute::GetPathForProcess(uid_t uid, pid_t pid, std::string* path
|
|||
return GetPathForTask(pid, path);
|
||||
}
|
||||
|
||||
bool ProfileAttribute::GetPathForTask(int tid, std::string* path) const {
|
||||
bool ProfileAttribute::GetPathForTask(pid_t tid, std::string* path) const {
|
||||
std::string subgroup;
|
||||
if (!controller()->GetTaskGroup(tid, &subgroup)) {
|
||||
return false;
|
||||
|
@ -179,13 +179,13 @@ bool SetClampsAction::ExecuteForTask(int) const {
|
|||
// To avoid issues in sdk_mac build
|
||||
#if defined(__ANDROID__)
|
||||
|
||||
bool SetTimerSlackAction::IsTimerSlackSupported(int tid) {
|
||||
bool SetTimerSlackAction::IsTimerSlackSupported(pid_t tid) {
|
||||
auto file = StringPrintf("/proc/%d/timerslack_ns", tid);
|
||||
|
||||
return (access(file.c_str(), W_OK) == 0);
|
||||
}
|
||||
|
||||
bool SetTimerSlackAction::ExecuteForTask(int tid) const {
|
||||
bool SetTimerSlackAction::ExecuteForTask(pid_t tid) const {
|
||||
static bool sys_supports_timerslack = IsTimerSlackSupported(tid);
|
||||
|
||||
// v4.6+ kernels support the /proc/<tid>/timerslack_ns interface.
|
||||
|
@ -250,7 +250,7 @@ bool SetAttributeAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
|
|||
return WriteValueToFile(path);
|
||||
}
|
||||
|
||||
bool SetAttributeAction::ExecuteForTask(int tid) const {
|
||||
bool SetAttributeAction::ExecuteForTask(pid_t tid) const {
|
||||
std::string path;
|
||||
|
||||
if (!attribute_->GetPathForTask(tid, &path)) {
|
||||
|
@ -288,7 +288,7 @@ bool SetAttributeAction::IsValidForProcess(uid_t, pid_t pid) const {
|
|||
return IsValidForTask(pid);
|
||||
}
|
||||
|
||||
bool SetAttributeAction::IsValidForTask(int tid) const {
|
||||
bool SetAttributeAction::IsValidForTask(pid_t tid) const {
|
||||
std::string path;
|
||||
|
||||
if (!attribute_->GetPathForTask(tid, &path)) {
|
||||
|
@ -316,7 +316,7 @@ SetCgroupAction::SetCgroupAction(const CgroupController& c, const std::string& p
|
|||
FdCacheHelper::Init(controller_.GetProcsFilePath(path_, 0, 0), fd_[ProfileAction::RCT_PROCESS]);
|
||||
}
|
||||
|
||||
bool SetCgroupAction::AddTidToCgroup(int tid, int fd, ResourceCacheType cache_type) const {
|
||||
bool SetCgroupAction::AddTidToCgroup(pid_t tid, int fd, ResourceCacheType cache_type) const {
|
||||
if (tid <= 0) {
|
||||
return true;
|
||||
}
|
||||
|
@ -401,7 +401,7 @@ bool SetCgroupAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SetCgroupAction::ExecuteForTask(int tid) const {
|
||||
bool SetCgroupAction::ExecuteForTask(pid_t tid) const {
|
||||
CacheUseResult result = UseCachedFd(ProfileAction::RCT_TASK, tid);
|
||||
if (result != ProfileAction::UNUSED) {
|
||||
return result == ProfileAction::SUCCESS;
|
||||
|
@ -590,7 +590,7 @@ bool WriteFileAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool WriteFileAction::ExecuteForTask(int tid) const {
|
||||
bool WriteFileAction::ExecuteForTask(pid_t tid) const {
|
||||
return WriteValueToFile(value_, ProfileAction::RCT_TASK, getuid(), tid, logfailures_);
|
||||
}
|
||||
|
||||
|
@ -655,7 +655,7 @@ bool ApplyProfileAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ApplyProfileAction::ExecuteForTask(int tid) const {
|
||||
bool ApplyProfileAction::ExecuteForTask(pid_t tid) const {
|
||||
for (const auto& profile : profiles_) {
|
||||
profile->ExecuteForTask(tid);
|
||||
}
|
||||
|
@ -683,7 +683,7 @@ bool ApplyProfileAction::IsValidForProcess(uid_t uid, pid_t pid) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ApplyProfileAction::IsValidForTask(int tid) const {
|
||||
bool ApplyProfileAction::IsValidForTask(pid_t tid) const {
|
||||
for (const auto& profile : profiles_) {
|
||||
if (!profile->IsValidForTask(tid)) {
|
||||
return false;
|
||||
|
@ -707,7 +707,7 @@ bool TaskProfile::ExecuteForProcess(uid_t uid, pid_t pid) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TaskProfile::ExecuteForTask(int tid) const {
|
||||
bool TaskProfile::ExecuteForTask(pid_t tid) const {
|
||||
if (tid == 0) {
|
||||
tid = GetThreadId();
|
||||
}
|
||||
|
@ -761,7 +761,7 @@ bool TaskProfile::IsValidForProcess(uid_t uid, pid_t pid) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TaskProfile::IsValidForTask(int tid) const {
|
||||
bool TaskProfile::IsValidForTask(pid_t tid) const {
|
||||
for (const auto& element : elements_) {
|
||||
if (!element->IsValidForTask(tid)) return false;
|
||||
}
|
||||
|
@ -1043,7 +1043,7 @@ bool TaskProfiles::SetProcessProfiles(uid_t uid, pid_t pid, std::span<const T> p
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
bool TaskProfiles::SetTaskProfiles(int tid, std::span<const T> profiles, bool use_fd_cache) {
|
||||
bool TaskProfiles::SetTaskProfiles(pid_t tid, std::span<const T> profiles, bool use_fd_cache) {
|
||||
bool success = true;
|
||||
for (const auto& name : profiles) {
|
||||
TaskProfile* profile = GetProfile(name);
|
||||
|
@ -1069,9 +1069,9 @@ template bool TaskProfiles::SetProcessProfiles(uid_t uid, pid_t pid,
|
|||
template bool TaskProfiles::SetProcessProfiles(uid_t uid, pid_t pid,
|
||||
std::span<const std::string_view> profiles,
|
||||
bool use_fd_cache);
|
||||
template bool TaskProfiles::SetTaskProfiles(int tid, std::span<const std::string> profiles,
|
||||
template bool TaskProfiles::SetTaskProfiles(pid_t tid, std::span<const std::string> profiles,
|
||||
bool use_fd_cache);
|
||||
template bool TaskProfiles::SetTaskProfiles(int tid, std::span<const std::string_view> profiles,
|
||||
template bool TaskProfiles::SetTaskProfiles(pid_t tid, std::span<const std::string_view> profiles,
|
||||
bool use_fd_cache);
|
||||
template bool TaskProfiles::SetUserProfiles(uid_t uid, std::span<const std::string> profiles,
|
||||
bool use_fd_cache);
|
||||
|
|
|
@ -37,7 +37,7 @@ class IProfileAttribute {
|
|||
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 GetPathForTask(pid_t tid, std::string* path) const = 0;
|
||||
virtual bool GetPathForUID(uid_t uid, std::string* path) const = 0;
|
||||
};
|
||||
|
||||
|
@ -57,7 +57,7 @@ class ProfileAttribute : public IProfileAttribute {
|
|||
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 GetPathForTask(pid_t tid, std::string* path) const override;
|
||||
bool GetPathForUID(uid_t uid, std::string* path) const override;
|
||||
|
||||
private:
|
||||
|
@ -83,7 +83,7 @@ class ProfileAction {
|
|||
virtual void EnableResourceCaching(ResourceCacheType) {}
|
||||
virtual void DropResourceCaching(ResourceCacheType) {}
|
||||
virtual bool IsValidForProcess(uid_t uid, pid_t pid) const { return false; }
|
||||
virtual bool IsValidForTask(int tid) const { return false; }
|
||||
virtual bool IsValidForTask(pid_t tid) const { return false; }
|
||||
|
||||
protected:
|
||||
enum CacheUseResult { SUCCESS, FAIL, UNUSED };
|
||||
|
@ -96,7 +96,7 @@ class SetClampsAction : public ProfileAction {
|
|||
|
||||
const char* Name() const override { return "SetClamps"; }
|
||||
bool ExecuteForProcess(uid_t uid, pid_t pid) const override;
|
||||
bool ExecuteForTask(int tid) const override;
|
||||
bool ExecuteForTask(pid_t tid) const override;
|
||||
|
||||
protected:
|
||||
int boost_;
|
||||
|
@ -108,14 +108,14 @@ class SetTimerSlackAction : public ProfileAction {
|
|||
SetTimerSlackAction(unsigned long slack) noexcept : slack_(slack) {}
|
||||
|
||||
const char* Name() const override { return "SetTimerSlack"; }
|
||||
bool ExecuteForTask(int tid) const override;
|
||||
bool ExecuteForTask(pid_t tid) const override;
|
||||
bool IsValidForProcess(uid_t uid, pid_t pid) const override { return true; }
|
||||
bool IsValidForTask(int tid) const override { return true; }
|
||||
bool IsValidForTask(pid_t tid) const override { return true; }
|
||||
|
||||
private:
|
||||
unsigned long slack_;
|
||||
|
||||
static bool IsTimerSlackSupported(int tid);
|
||||
static bool IsTimerSlackSupported(pid_t tid);
|
||||
};
|
||||
|
||||
// Set attribute profile element
|
||||
|
@ -126,10 +126,10 @@ class SetAttributeAction : public ProfileAction {
|
|||
|
||||
const char* Name() const override { return "SetAttribute"; }
|
||||
bool ExecuteForProcess(uid_t uid, pid_t pid) const override;
|
||||
bool ExecuteForTask(int tid) const override;
|
||||
bool ExecuteForTask(pid_t tid) const override;
|
||||
bool ExecuteForUID(uid_t uid) const override;
|
||||
bool IsValidForProcess(uid_t uid, pid_t pid) const override;
|
||||
bool IsValidForTask(int tid) const override;
|
||||
bool IsValidForTask(pid_t tid) const override;
|
||||
|
||||
private:
|
||||
const IProfileAttribute* attribute_;
|
||||
|
@ -146,11 +146,11 @@ class SetCgroupAction : public ProfileAction {
|
|||
|
||||
const char* Name() const override { return "SetCgroup"; }
|
||||
bool ExecuteForProcess(uid_t uid, pid_t pid) const override;
|
||||
bool ExecuteForTask(int tid) const override;
|
||||
bool ExecuteForTask(pid_t tid) const override;
|
||||
void EnableResourceCaching(ResourceCacheType cache_type) override;
|
||||
void DropResourceCaching(ResourceCacheType cache_type) override;
|
||||
bool IsValidForProcess(uid_t uid, pid_t pid) const override;
|
||||
bool IsValidForTask(int tid) const override;
|
||||
bool IsValidForTask(pid_t tid) const override;
|
||||
|
||||
const CgroupController* controller() const { return &controller_; }
|
||||
|
||||
|
@ -160,7 +160,7 @@ class SetCgroupAction : public ProfileAction {
|
|||
android::base::unique_fd fd_[ProfileAction::RCT_COUNT];
|
||||
mutable std::mutex fd_mutex_;
|
||||
|
||||
bool AddTidToCgroup(int tid, int fd, ResourceCacheType cache_type) const;
|
||||
bool AddTidToCgroup(pid_t tid, int fd, ResourceCacheType cache_type) const;
|
||||
CacheUseResult UseCachedFd(ResourceCacheType cache_type, int id) const;
|
||||
};
|
||||
|
||||
|
@ -172,11 +172,11 @@ class WriteFileAction : public ProfileAction {
|
|||
|
||||
const char* Name() const override { return "WriteFile"; }
|
||||
bool ExecuteForProcess(uid_t uid, pid_t pid) const override;
|
||||
bool ExecuteForTask(int tid) const override;
|
||||
bool ExecuteForTask(pid_t tid) const override;
|
||||
void EnableResourceCaching(ResourceCacheType cache_type) override;
|
||||
void DropResourceCaching(ResourceCacheType cache_type) override;
|
||||
bool IsValidForProcess(uid_t uid, pid_t pid) const override;
|
||||
bool IsValidForTask(int tid) const override;
|
||||
bool IsValidForTask(pid_t tid) const override;
|
||||
|
||||
private:
|
||||
std::string task_path_, proc_path_, value_;
|
||||
|
@ -198,12 +198,12 @@ class TaskProfile {
|
|||
void MoveTo(TaskProfile* profile);
|
||||
|
||||
bool ExecuteForProcess(uid_t uid, pid_t pid) const;
|
||||
bool ExecuteForTask(int tid) const;
|
||||
bool ExecuteForTask(pid_t tid) const;
|
||||
bool ExecuteForUID(uid_t uid) const;
|
||||
void EnableResourceCaching(ProfileAction::ResourceCacheType cache_type);
|
||||
void DropResourceCaching(ProfileAction::ResourceCacheType cache_type);
|
||||
bool IsValidForProcess(uid_t uid, pid_t pid) const;
|
||||
bool IsValidForTask(int tid) const;
|
||||
bool IsValidForTask(pid_t tid) const;
|
||||
|
||||
private:
|
||||
const std::string name_;
|
||||
|
@ -219,11 +219,11 @@ class ApplyProfileAction : public ProfileAction {
|
|||
|
||||
const char* Name() const override { return "ApplyProfileAction"; }
|
||||
bool ExecuteForProcess(uid_t uid, pid_t pid) const override;
|
||||
bool ExecuteForTask(int tid) const override;
|
||||
bool ExecuteForTask(pid_t tid) const override;
|
||||
void EnableResourceCaching(ProfileAction::ResourceCacheType cache_type) override;
|
||||
void DropResourceCaching(ProfileAction::ResourceCacheType cache_type) override;
|
||||
bool IsValidForProcess(uid_t uid, pid_t pid) const override;
|
||||
bool IsValidForTask(int tid) const override;
|
||||
bool IsValidForTask(pid_t tid) const override;
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<TaskProfile>> profiles_;
|
||||
|
@ -240,7 +240,7 @@ class TaskProfiles {
|
|||
template <typename T>
|
||||
bool SetProcessProfiles(uid_t uid, pid_t pid, std::span<const T> profiles, bool use_fd_cache);
|
||||
template <typename T>
|
||||
bool SetTaskProfiles(int tid, std::span<const T> profiles, bool use_fd_cache);
|
||||
bool SetTaskProfiles(pid_t tid, std::span<const T> profiles, bool use_fd_cache);
|
||||
template <typename T>
|
||||
bool SetUserProfiles(uid_t uid, std::span<const T> profiles, bool use_fd_cache);
|
||||
|
||||
|
|
Loading…
Reference in a new issue