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