Merge "Support process path for WriteFileAction"
This commit is contained in:
commit
a323e0233d
2 changed files with 95 additions and 49 deletions
|
|
@ -350,14 +350,33 @@ void SetCgroupAction::DropResourceCaching(ResourceCacheType cache_type) {
|
|||
FdCacheHelper::Drop(fd_[cache_type]);
|
||||
}
|
||||
|
||||
WriteFileAction::WriteFileAction(const std::string& path, const std::string& value,
|
||||
bool logfailures)
|
||||
: path_(path), value_(value), logfailures_(logfailures) {
|
||||
FdCacheHelper::Init(path_, fd_);
|
||||
WriteFileAction::WriteFileAction(const std::string& task_path, const std::string& proc_path,
|
||||
const std::string& value, bool logfailures)
|
||||
: task_path_(task_path), proc_path_(proc_path), value_(value), logfailures_(logfailures) {
|
||||
FdCacheHelper::Init(task_path_, fd_[ProfileAction::RCT_TASK]);
|
||||
if (!proc_path_.empty()) FdCacheHelper::Init(proc_path_, fd_[ProfileAction::RCT_PROCESS]);
|
||||
}
|
||||
|
||||
bool WriteFileAction::WriteValueToFile(const std::string& value, const std::string& path,
|
||||
bool logfailures) {
|
||||
bool WriteFileAction::WriteValueToFile(const std::string& value_, ResourceCacheType cache_type,
|
||||
int uid, int pid, bool logfailures) const {
|
||||
std::string value(value_);
|
||||
|
||||
value = StringReplace(value, "<uid>", std::to_string(uid), true);
|
||||
value = StringReplace(value, "<pid>", std::to_string(pid), true);
|
||||
|
||||
CacheUseResult result = UseCachedFd(cache_type, value);
|
||||
|
||||
if (result != ProfileAction::UNUSED) {
|
||||
return result == ProfileAction::SUCCESS;
|
||||
}
|
||||
|
||||
std::string path;
|
||||
if (cache_type == ProfileAction::RCT_TASK || proc_path_.empty()) {
|
||||
path = task_path_;
|
||||
} else {
|
||||
path = proc_path_;
|
||||
}
|
||||
|
||||
// Use WriteStringToFd instead of WriteStringToFile because the latter will open file with
|
||||
// O_TRUNC which causes kernfs_mutex contention
|
||||
unique_fd tmp_fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_WRONLY | O_CLOEXEC)));
|
||||
|
|
@ -378,21 +397,27 @@ bool WriteFileAction::WriteValueToFile(const std::string& value, const std::stri
|
|||
ProfileAction::CacheUseResult WriteFileAction::UseCachedFd(ResourceCacheType cache_type,
|
||||
const std::string& value) const {
|
||||
std::lock_guard<std::mutex> lock(fd_mutex_);
|
||||
if (FdCacheHelper::IsCached(fd_)) {
|
||||
if (FdCacheHelper::IsCached(fd_[cache_type])) {
|
||||
// fd is cached, reuse it
|
||||
if (!WriteStringToFd(value, fd_)) {
|
||||
if (logfailures_) PLOG(ERROR) << "Failed to write '" << value << "' to " << path_;
|
||||
return ProfileAction::FAIL;
|
||||
bool ret = WriteStringToFd(value, fd_[cache_type]);
|
||||
|
||||
if (!ret && logfailures_) {
|
||||
if (cache_type == ProfileAction::RCT_TASK || proc_path_.empty()) {
|
||||
PLOG(ERROR) << "Failed to write '" << value << "' to " << task_path_;
|
||||
} else {
|
||||
PLOG(ERROR) << "Failed to write '" << value << "' to " << proc_path_;
|
||||
}
|
||||
}
|
||||
return ProfileAction::SUCCESS;
|
||||
return ret ? ProfileAction::SUCCESS : ProfileAction::FAIL;
|
||||
}
|
||||
|
||||
if (fd_ == FdCacheHelper::FDS_INACCESSIBLE) {
|
||||
if (fd_[cache_type] == FdCacheHelper::FDS_INACCESSIBLE) {
|
||||
// no permissions to access the file, ignore
|
||||
return ProfileAction::SUCCESS;
|
||||
}
|
||||
|
||||
if (cache_type == ResourceCacheType::RCT_TASK && fd_ == FdCacheHelper::FDS_APP_DEPENDENT) {
|
||||
if (cache_type == ResourceCacheType::RCT_TASK &&
|
||||
fd_[cache_type] == FdCacheHelper::FDS_APP_DEPENDENT) {
|
||||
// application-dependent path can't be used with tid
|
||||
PLOG(ERROR) << "Application profile can't be applied to a thread";
|
||||
return ProfileAction::FAIL;
|
||||
|
|
@ -401,46 +426,64 @@ ProfileAction::CacheUseResult WriteFileAction::UseCachedFd(ResourceCacheType cac
|
|||
}
|
||||
|
||||
bool WriteFileAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
|
||||
std::string value(value_);
|
||||
|
||||
value = StringReplace(value, "<uid>", std::to_string(uid), true);
|
||||
value = StringReplace(value, "<pid>", std::to_string(pid), true);
|
||||
|
||||
CacheUseResult result = UseCachedFd(ProfileAction::RCT_PROCESS, value);
|
||||
if (result != ProfileAction::UNUSED) {
|
||||
return result == ProfileAction::SUCCESS;
|
||||
if (!proc_path_.empty()) {
|
||||
return WriteValueToFile(value_, ProfileAction::RCT_PROCESS, uid, pid, logfailures_);
|
||||
}
|
||||
|
||||
std::string path(path_);
|
||||
path = StringReplace(path, "<uid>", std::to_string(uid), true);
|
||||
path = StringReplace(path, "<pid>", std::to_string(pid), true);
|
||||
DIR* d;
|
||||
struct dirent* de;
|
||||
char proc_path[255];
|
||||
int t_pid;
|
||||
|
||||
return WriteValueToFile(value, path, logfailures_);
|
||||
sprintf(proc_path, "/proc/%d/task", pid);
|
||||
if (!(d = opendir(proc_path))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while ((de = readdir(d))) {
|
||||
if (de->d_name[0] == '.') {
|
||||
continue;
|
||||
}
|
||||
|
||||
t_pid = atoi(de->d_name);
|
||||
|
||||
if (!t_pid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
WriteValueToFile(value_, ProfileAction::RCT_TASK, uid, t_pid, logfailures_);
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteFileAction::ExecuteForTask(int tid) const {
|
||||
std::string value(value_);
|
||||
int uid = getuid();
|
||||
return WriteValueToFile(value_, ProfileAction::RCT_TASK, getuid(), tid, logfailures_);
|
||||
}
|
||||
|
||||
value = StringReplace(value, "<uid>", std::to_string(uid), true);
|
||||
value = StringReplace(value, "<pid>", std::to_string(tid), true);
|
||||
|
||||
CacheUseResult result = UseCachedFd(ProfileAction::RCT_TASK, value);
|
||||
if (result != ProfileAction::UNUSED) {
|
||||
return result == ProfileAction::SUCCESS;
|
||||
void WriteFileAction::EnableResourceCaching(ResourceCacheType cache_type) {
|
||||
std::lock_guard<std::mutex> lock(fd_mutex_);
|
||||
if (fd_[cache_type] != FdCacheHelper::FDS_NOT_CACHED) {
|
||||
return;
|
||||
}
|
||||
switch (cache_type) {
|
||||
case (ProfileAction::RCT_TASK):
|
||||
FdCacheHelper::Cache(task_path_, fd_[cache_type]);
|
||||
break;
|
||||
case (ProfileAction::RCT_PROCESS):
|
||||
if (!proc_path_.empty()) FdCacheHelper::Cache(proc_path_, fd_[cache_type]);
|
||||
break;
|
||||
default:
|
||||
LOG(ERROR) << "Invalid cache type is specified!";
|
||||
break;
|
||||
}
|
||||
|
||||
return WriteValueToFile(value, path_, logfailures_);
|
||||
}
|
||||
|
||||
void WriteFileAction::EnableResourceCaching(ResourceCacheType) {
|
||||
void WriteFileAction::DropResourceCaching(ResourceCacheType cache_type) {
|
||||
std::lock_guard<std::mutex> lock(fd_mutex_);
|
||||
FdCacheHelper::Cache(path_, fd_);
|
||||
}
|
||||
|
||||
void WriteFileAction::DropResourceCaching(ResourceCacheType) {
|
||||
std::lock_guard<std::mutex> lock(fd_mutex_);
|
||||
FdCacheHelper::Drop(fd_);
|
||||
FdCacheHelper::Drop(fd_[cache_type]);
|
||||
}
|
||||
|
||||
bool ApplyProfileAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
|
||||
|
|
@ -659,12 +702,14 @@ bool TaskProfiles::Load(const CgroupMap& cg_map, const std::string& file_name) {
|
|||
}
|
||||
} else if (action_name == "WriteFile") {
|
||||
std::string attr_filepath = params_val["FilePath"].asString();
|
||||
std::string attr_procfilepath = params_val["ProcFilePath"].asString();
|
||||
std::string attr_value = params_val["Value"].asString();
|
||||
// FilePath and Value are mandatory
|
||||
if (!attr_filepath.empty() && !attr_value.empty()) {
|
||||
std::string attr_logfailures = params_val["LogFailures"].asString();
|
||||
bool logfailures = attr_logfailures.empty() || attr_logfailures == "true";
|
||||
profile->Add(std::make_unique<WriteFileAction>(attr_filepath, attr_value,
|
||||
logfailures));
|
||||
profile->Add(std::make_unique<WriteFileAction>(attr_filepath, attr_procfilepath,
|
||||
attr_value, logfailures));
|
||||
} else if (attr_filepath.empty()) {
|
||||
LOG(WARNING) << "WriteFile: invalid parameter: "
|
||||
<< "empty filepath";
|
||||
|
|
|
|||
|
|
@ -140,7 +140,8 @@ class SetCgroupAction : public ProfileAction {
|
|||
// Write to file action
|
||||
class WriteFileAction : public ProfileAction {
|
||||
public:
|
||||
WriteFileAction(const std::string& path, const std::string& value, bool logfailures);
|
||||
WriteFileAction(const std::string& task_path, const std::string& proc_path,
|
||||
const std::string& value, bool logfailures);
|
||||
|
||||
const char* Name() const override { return "WriteFile"; }
|
||||
bool ExecuteForProcess(uid_t uid, pid_t pid) const override;
|
||||
|
|
@ -149,13 +150,13 @@ class WriteFileAction : public ProfileAction {
|
|||
void DropResourceCaching(ResourceCacheType cache_type) override;
|
||||
|
||||
private:
|
||||
std::string path_, value_;
|
||||
std::string task_path_, proc_path_, value_;
|
||||
bool logfailures_;
|
||||
android::base::unique_fd fd_;
|
||||
android::base::unique_fd fd_[ProfileAction::RCT_COUNT];
|
||||
mutable std::mutex fd_mutex_;
|
||||
|
||||
static bool WriteValueToFile(const std::string& value, const std::string& path,
|
||||
bool logfailures);
|
||||
bool WriteValueToFile(const std::string& value, ResourceCacheType cache_type, int uid, int pid,
|
||||
bool logfailures) const;
|
||||
CacheUseResult UseCachedFd(ResourceCacheType cache_type, const std::string& value) const;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue