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 "file_system_data_parser.h"
16 #include "process_filter.h"
17 #include "stat_filter.h"
18 #include "string_to_numerical.h"
19
20 namespace SysTuning {
21 namespace TraceStreamer {
FileSystemDataParser(TraceDataCache * dataCache,const TraceStreamerFilters * ctx)22 FileSystemDataParser::FileSystemDataParser(TraceDataCache* dataCache, const TraceStreamerFilters* ctx)
23 : EventParserBase(dataCache, ctx),
24 EbpfBase(dataCache, ctx),
25 timeParser_(std::make_unique<HtracePluginTimeParser>(dataCache, ctx))
26 {
27 }
~FileSystemDataParser()28 FileSystemDataParser::~FileSystemDataParser()
29 {
30 TS_LOGI("EBPF FileSystem data ts MIN:%llu, MAX:%llu",
31 static_cast<unsigned long long>(timeParser_->GetPluginStartTime()),
32 static_cast<unsigned long long>(timeParser_->GetPluginEndTime()));
33 }
ParseFileSystemEvent()34 void FileSystemDataParser::ParseFileSystemEvent()
35 {
36 if (!reader_->GetFileSystemEventMap().size()) {
37 return;
38 }
39 auto& tracerEventToStrIndexMap = reader_->GetTracerEventToStrIndexMap();
40 for (auto mapItor = reader_->GetFileSystemEventMap().begin(); mapItor != reader_->GetFileSystemEventMap().end();
41 mapItor++) {
42 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_EBPF_FILE_SYSTEM, STAT_EVENT_RECEIVED);
43 auto fsFixedHeadrAddr = mapItor->second;
44 bool callIdExistFlag = false;
45
46 auto userIpsAddr = reinterpret_cast<const uint64_t*>(fsFixedHeadrAddr + 1);
47 if (fsFixedHeadrAddr->nrUserIPs) {
48 std::string ipsToStr(reinterpret_cast<const char*>(userIpsAddr),
49 fsFixedHeadrAddr->nrUserIPs * SINGLE_IP_SIZE);
50 auto ipsHashValue = hashFun_(ipsToStr);
51 auto value = pidAndipsToCallId_.Find(fsFixedHeadrAddr->pid, ipsHashValue);
52 if (value != INVALID_UINT64) {
53 callIdExistFlag = true;
54 currentCallId_ = value;
55 } else {
56 pidAndipsToCallId_.Insert(fsFixedHeadrAddr->pid, ipsHashValue, callChainId_);
57 currentCallId_ = callChainId_++;
58 }
59 } else {
60 currentCallId_ = INVALID_UINT64;
61 }
62
63 uint16_t type = INVALID_UINT16;
64 auto tmp = fucSubToSummaryType.find(fsFixedHeadrAddr->type);
65 if (tmp == fucSubToSummaryType.end()) {
66 return;
67 }
68 type = fucSubToSummaryType.at(fsFixedHeadrAddr->type);
69
70 // Init process name data
71 auto processName = const_cast<char*>(fsFixedHeadrAddr->processName);
72 processName[MAX_PROCESS_NAME_SZIE - 1] = '\0';
73 uint32_t ipid =
74 streamFilters_->processFilter_->UpdateOrCreateProcessWithName(fsFixedHeadrAddr->pid, processName);
75 uint32_t itid =
76 streamFilters_->processFilter_->GetOrCreateThreadWithPid(fsFixedHeadrAddr->tid, fsFixedHeadrAddr->pid);
77 auto newStartTs = streamFilters_->clockFilter_->ToPrimaryTraceTime(clockId_, fsFixedHeadrAddr->startTime);
78 timeParser_->UpdatePluginTimeRange(clockId_, fsFixedHeadrAddr->startTime, newStartTs);
79 auto newEndTs = streamFilters_->clockFilter_->ToPrimaryTraceTime(clockId_, fsFixedHeadrAddr->endTime);
80 timeParser_->UpdatePluginTimeRange(clockId_, fsFixedHeadrAddr->endTime, newEndTs);
81 if (newStartTs > newEndTs) {
82 TS_LOGE("File system event origin startTs = %lu, endTs = %lu, newStartTs = %lu, newEndTs = %lu",
83 fsFixedHeadrAddr->startTime, fsFixedHeadrAddr->endTime, newStartTs, newEndTs);
84 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_EBPF_FILE_SYSTEM, STAT_EVENT_DATA_INVALID);
85 return;
86 }
87 uint64_t duration = newEndTs - newStartTs;
88 DataIndex returnValue = INVALID_UINT64;
89 DataIndex errorCode = INVALID_UINT64;
90 if (fsFixedHeadrAddr->ret < 0) {
91 returnValue = ConvertToHexTextIndex(0);
92 errorCode = ConvertToHexTextIndex(-fsFixedHeadrAddr->ret);
93 } else {
94 returnValue = ConvertToHexTextIndex(fsFixedHeadrAddr->ret);
95 }
96
97 int i = 0;
98 auto firstArgument = ConvertToHexTextIndex(fsFixedHeadrAddr->args[i++]);
99 auto secondArgument = ConvertToHexTextIndex(fsFixedHeadrAddr->args[i++]);
100 auto thirdArgument = ConvertToHexTextIndex(fsFixedHeadrAddr->args[i++]);
101 auto fourthArgument = ConvertToHexTextIndex(fsFixedHeadrAddr->args[i]);
102
103 // get file descriptor
104 auto fd = GetFileDescriptor(fsFixedHeadrAddr, type);
105 // get file path
106 uint64_t filePathId = INVALID_UINT64;
107 if (fsFixedHeadrAddr->type == SYS_OPENAT2 || fsFixedHeadrAddr->type == SYS_CLOSE) {
108 filePathId =
109 tracerEventToStrIndexMap.Find(ITEM_EVENT_FS, fsFixedHeadrAddr->type, itid, fsFixedHeadrAddr->startTime);
110 if (filePathId != INVALID_UINT64) {
111 tracerEventToStrIndexMap.Erase(ITEM_EVENT_FS, fsFixedHeadrAddr->type, itid,
112 fsFixedHeadrAddr->startTime);
113 }
114 }
115
116 // get read or writ size
117 size_t size = MAX_SIZE_T;
118 if ((type == READ || type == WRITE) && fsFixedHeadrAddr->ret >= 0) {
119 size = fsFixedHeadrAddr->ret;
120 }
121
122 traceDataCache_->GetFileSystemSample()->AppendNewData(
123 currentCallId_, type, ipid, itid, newStartTs, newEndTs, duration, returnValue, errorCode, size, fd,
124 filePathId, firstArgument, secondArgument, thirdArgument, fourthArgument);
125 if (!callIdExistFlag) {
126 ParseCallStackData(userIpsAddr, fsFixedHeadrAddr->nrUserIPs, fsFixedHeadrAddr->pid, currentCallId_);
127 }
128 }
129 }
130
GetFileDescriptor(const FsFixedHeader * fsFixedHeader,uint32_t fucType)131 int32_t FileSystemDataParser::GetFileDescriptor(const FsFixedHeader* fsFixedHeader, uint32_t fucType)
132 {
133 auto returnValue = fsFixedHeader->ret;
134 int32_t fd = INVALID_INT32;
135 if (fucType == OPEN and returnValue >= 0) {
136 fd = returnValue;
137 } else if (fucType == READ or fucType == WRITE) {
138 fd = fsFixedHeader->args[0];
139 } else if (fucType == CLOSE) {
140 fd = fsFixedHeader->args[1];
141 }
142 return fd;
143 }
144 } // namespace TraceStreamer
145 } // namespace SysTuning
146