• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "ftrace_fs_ops.h"
16 
17 #include <fcntl.h>
18 #include <set>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22 
23 #include "file_utils.h"
24 #include "logging.h"
25 
26 FTRACE_NS_BEGIN
GetInstance()27 FtraceFsOps& FtraceFsOps::GetInstance()
28 {
29     static FtraceFsOps instance;
30     return instance;
31 }
32 
FtraceFsOps()33 FtraceFsOps::FtraceFsOps() : ftraceRoot_(GetFtraceRoot())
34 {
35     HILOG_INFO(LOG_CORE, "FtraceFsOps create!");
36 }
37 
~FtraceFsOps()38 FtraceFsOps::~FtraceFsOps()
39 {
40     HILOG_INFO(LOG_CORE, "FtraceFsOps destroy!");
41 }
42 
GetFtraceRoot()43 std::string FtraceFsOps::GetFtraceRoot()
44 {
45     std::vector<std::string> testRootPath = {"/sys/kernel/tracing", "/sys/kernel/debug/tracing"};
46     for (auto iter = testRootPath.begin(); iter != testRootPath.end(); ++iter) {
47         auto path = *iter + "/events";
48         struct stat s;
49         lstat(path.c_str(), &s);
50         if (S_ISDIR(s.st_mode)) {
51             return *iter;
52         }
53     }
54     return "";
55 }
56 
GetPrintkFormats() const57 std::string FtraceFsOps::GetPrintkFormats() const
58 {
59     return FileUtils::ReadFile(ftraceRoot_ + "/printk_formats");
60 }
61 
GetKptrRestrict()62 std::string GetKptrRestrict()
63 {
64     return FileUtils::ReadFile("/proc/sys/kernel/kptr_restrict");
65 }
66 
SetKptrRestrict(const std::string & value)67 bool SetKptrRestrict(const std::string& value)
68 {
69     return FileUtils::WriteFile("/proc/sys/kernel/kptr_restrict", value) > 0;
70 }
71 
GetKernelSymbols() const72 std::string FtraceFsOps::GetKernelSymbols() const
73 {
74     std::string restrictValue = GetKptrRestrict();
75     CHECK_TRUE(restrictValue.size() > 0, "", "read kptr_restrict failed!");
76 
77     bool valueChanged = false;
78     if (std::stoi(restrictValue) == 0) {
79         SetKptrRestrict("1");
80         valueChanged = true;
81     }
82 
83     std::string result = FileUtils::ReadFile("/proc/kallsyms");
84     if (valueChanged) {
85         SetKptrRestrict(restrictValue);
86     }
87     return result;
88 }
89 
SetSavedCmdLinesSize(uint32_t size)90 bool FtraceFsOps::SetSavedCmdLinesSize(uint32_t size)
91 {
92     std::string path = ftraceRoot_ + "/saved_cmdlines_size";
93     return FileUtils::WriteFile(path, std::to_string(static_cast<int>(size))) > 0;
94 }
95 
GetSavedCmdLines() const96 std::string FtraceFsOps::GetSavedCmdLines() const
97 {
98     return FileUtils::ReadFile(ftraceRoot_ + "/saved_cmdlines");
99 }
100 
GetSavedTgids() const101 std::string FtraceFsOps::GetSavedTgids() const
102 {
103     return FileUtils::ReadFile(ftraceRoot_ + "/saved_tgids");
104 }
105 
GetProcessComm(int pid)106 std::string FtraceFsOps::GetProcessComm(int pid)
107 {
108     std::string path = "/proc/" + std::to_string(pid) + "/comm";
109     if (access(path.c_str(), R_OK) != 0) {
110         return "";
111     }
112     return FileUtils::ReadFile(path);
113 }
114 
GetThreadComm(int pid,int tid)115 std::string FtraceFsOps::GetThreadComm(int pid, int tid)
116 {
117     std::string path = "/proc/" + std::to_string(pid) + "/task/" + std::to_string(tid) + "/comm";
118     if (access(path.c_str(), R_OK) != 0) {
119         return "";
120     }
121     return FileUtils::ReadFile(path);
122 }
123 
GetPerCpuStats(int cpu) const124 std::string FtraceFsOps::GetPerCpuStats(int cpu) const
125 {
126     return FileUtils::ReadFile(ftraceRoot_ + "/per_cpu/cpu" + std::to_string(cpu) + "/stats");
127 }
128 
GetRawTracePath(int cpu) const129 std::string FtraceFsOps::GetRawTracePath(int cpu) const
130 {
131     return ftraceRoot_ + "/per_cpu/cpu" + std::to_string(cpu) + "/trace_pipe_raw";
132 }
133 
GetPageHeaderFormat() const134 std::string FtraceFsOps::GetPageHeaderFormat() const
135 {
136     return FileUtils::ReadFile(ftraceRoot_ + "/events/header_page");
137 }
138 
GetEventDataFormat(const std::string & type,const std::string & name) const139 std::string FtraceFsOps::GetEventDataFormat(const std::string& type, const std::string& name) const
140 {
141     return FileUtils::ReadFile(ftraceRoot_ + "/events/" + type + "/" + name + "/format");
142 }
143 
ClearTraceBuffer()144 bool FtraceFsOps::ClearTraceBuffer()
145 {
146     char realPath[PATH_MAX + 1] = {0};
147 
148     std::string path = ftraceRoot_ + "/trace";
149     CHECK_TRUE((path.length() < PATH_MAX) && (realpath(path.c_str(), realPath) != nullptr), false,
150                "%s:path is invalid: %s, errno=%d", __func__, path.c_str(), errno);
151     int fd = open(realPath, O_TRUNC);
152     CHECK_TRUE(fd >= 0, false, "open %s failed!", realPath);
153     return close(fd) == 0;
154 }
155 
SetRecordCmdOption(bool enable)156 bool FtraceFsOps::SetRecordCmdOption(bool enable)
157 {
158     std::string path = ftraceRoot_ + "/options/record-cmd";
159     return FileUtils::WriteFile(path, std::to_string(static_cast<int>(enable))) > 0;
160 }
161 
SetRecordTgidOption(bool enable)162 bool FtraceFsOps::SetRecordTgidOption(bool enable)
163 {
164     std::string path = ftraceRoot_ + "/options/record-tgid";
165     return FileUtils::WriteFile(path, std::to_string(static_cast<int>(enable))) > 0;
166 }
167 
SetBufferSizeKb(int sizeKb)168 bool FtraceFsOps::SetBufferSizeKb(int sizeKb)
169 {
170     std::string path = ftraceRoot_ + "/buffer_size_kb";
171     return FileUtils::WriteFile(path, std::to_string(sizeKb)) > 0;
172 }
173 
SetTraceClock(const std::string & clock)174 bool FtraceFsOps::SetTraceClock(const std::string& clock)
175 {
176     std::string path = ftraceRoot_ + "/trace_clock";
177     return FileUtils::WriteFile(path, clock) > 0;
178 }
179 
GetTraceClock()180 std::string FtraceFsOps::GetTraceClock()
181 {
182     std::string path = ftraceRoot_ + "/trace_clock";
183     std::string value = FileUtils::ReadFile(path);
184     auto pos = value.find('[');
185     CHECK_TRUE(pos != std::string::npos, "", "find [ in %s failed!", path.c_str());
186     pos++;
187 
188     auto rpos = value.find(']', pos);
189     CHECK_TRUE(rpos != std::string::npos, "", "find ] in %s failed!", path.c_str());
190     return value.substr(pos, rpos - pos);
191 }
192 
GetPlatformEvents()193 std::vector<std::pair<std::string, std::string>> FtraceFsOps::GetPlatformEvents()
194 {
195     std::set<std::pair<std::string, std::string>> eventSet;
196     std::string eventsPath = ftraceRoot_ + "/events";
197     for (auto& type : FileUtils::ListDir(eventsPath)) {
198         struct stat st = {};
199         std::string typePath = eventsPath + "/" + type;
200         if (stat(typePath.c_str(), &st) != 0 || !S_ISDIR(st.st_mode)) {
201             continue;
202         }
203         for (auto& name : FileUtils::ListDir(typePath)) {
204             struct stat st = {};
205             std::string namePath = typePath + "/" + name;
206             if (stat(namePath.c_str(), &st) != 0 || !S_ISDIR(st.st_mode)) {
207                 continue;
208             }
209             eventSet.insert(std::make_pair(type, name));
210         }
211     }
212     HILOG_INFO(LOG_CORE, "get platform event formats done, types: %zu!", eventSet.size());
213     return {eventSet.begin(), eventSet.end()};
214 }
215 
AppendSetEvent(const std::string & type,const std::string & name)216 bool FtraceFsOps::AppendSetEvent(const std::string& type, const std::string& name)
217 {
218     std::string path = ftraceRoot_ + "/set_event";
219     return FileUtils::WriteFile(path, type + ":" + name + "\n", O_WRONLY | O_APPEND) > 0;
220 }
221 
ClearSetEvent()222 bool FtraceFsOps::ClearSetEvent()
223 {
224     return FileUtils::WriteFile(ftraceRoot_ + "/set_event", "\n", O_WRONLY | O_TRUNC) > 0;
225 }
226 
EnableEvent(const std::string & type,const std::string & name)227 bool FtraceFsOps::EnableEvent(const std::string& type, const std::string& name)
228 {
229     std::string enablePath = ftraceRoot_ + "/events/" + type + "/" + name + "/enable";
230     return FileUtils::WriteFile(enablePath, "1") > 0;
231 }
232 
DisableEvent(const std::string & type,const std::string & name)233 bool FtraceFsOps::DisableEvent(const std::string& type, const std::string& name)
234 {
235     std::string enablePath = ftraceRoot_ + "/events/" + type + "/" + name + "/enable";
236     return FileUtils::WriteFile(enablePath, "0") > 0;
237 }
238 
DisableCategories(const std::string & categories)239 bool FtraceFsOps::DisableCategories(const std::string& categories)
240 {
241     std::string enablePath = ftraceRoot_ + "/events/" + categories + "/enable";
242     return FileUtils::WriteFile(enablePath, "0") > 0;
243 }
244 
EnableTracing()245 bool FtraceFsOps::EnableTracing()
246 {
247     std::string tracingOn = ftraceRoot_ + "/tracing_on";
248     return FileUtils::WriteFile(tracingOn, "1") > 0;
249 }
250 
DisableTracing()251 bool FtraceFsOps::DisableTracing()
252 {
253     std::string tracingOn = ftraceRoot_ + "/tracing_on";
254     return FileUtils::WriteFile(tracingOn, "0") > 0;
255 }
256 FTRACE_NS_END
257