• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
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_UINT32) {
43             callIdExistFlag = true;
44             currentCallId_ = value;
45         } else {
46             pidAndipsToCallId_.Insert(fsFixedHeadrAddr->pid, ipsHashValue, callChainId_);
47             currentCallId_ = callChainId_++;
48         }
49     } else {
50         currentCallId_ = INVALID_UINT32;
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     auto &tracerEventToStrIndexMap = reader_->GetTracerEventToStrIndexMap();
104     for (auto mapItor = reader_->GetFileSystemEventMap().begin(); mapItor != reader_->GetFileSystemEventMap().end();
105          mapItor++) {
106         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_EBPF_FILE_SYSTEM, STAT_EVENT_RECEIVED);
107         auto fsFixedHeadrAddr = mapItor->second;
108         bool callIdExistFlag = false;
109         auto userIpsAddr = reinterpret_cast<const uint64_t *>(fsFixedHeadrAddr + 1);
110         // Find the corresponding callId for the number of user IP addresses
111         IpAndCallidFind(fsFixedHeadrAddr, callIdExistFlag, userIpsAddr);
112         uint16_t type = INVALID_UINT16;
113         auto tmp = fucSubToSummaryType.find(fsFixedHeadrAddr->type);
114         if (tmp == fucSubToSummaryType.end()) {
115             return;
116         }
117         type = fucSubToSummaryType.at(fsFixedHeadrAddr->type);
118         // Init process name data
119         auto processName = const_cast<char *>(fsFixedHeadrAddr->processName);
120         processName[MAX_PROCESS_NAME_SZIE - 1] = '\0';
121         uint32_t ipid =
122             streamFilters_->processFilter_->UpdateOrCreateProcessWithName(fsFixedHeadrAddr->pid, processName);
123         uint32_t itid =
124             streamFilters_->processFilter_->GetOrCreateThreadWithPid(fsFixedHeadrAddr->tid, fsFixedHeadrAddr->pid);
125         auto newStartTs = streamFilters_->clockFilter_->ToPrimaryTraceTime(clockId_, fsFixedHeadrAddr->startTime);
126         auto newEndTs = streamFilters_->clockFilter_->ToPrimaryTraceTime(clockId_, fsFixedHeadrAddr->endTime);
127         DataIndex returnValue = INVALID_UINT64;
128         DataIndex errorCode = INVALID_UINT64;
129         //(newStartTs > newEndTs), When the data is invalid, the maximum value returned is uint64_t(size_t size
130         //=numeric_limits<uint64_t>::max());
131         uint64_t duration = StartEndTime(fsFixedHeadrAddr, newStartTs, newEndTs, returnValue, errorCode);
132         if (newStartTs > newEndTs) {
133             return;
134         }
135         int32_t i = 0;
136         auto firstArgument = ConvertToHexTextIndex(fsFixedHeadrAddr->args[i++]);
137         auto secondArgument = ConvertToHexTextIndex(fsFixedHeadrAddr->args[i++]);
138         auto thirdArgument = ConvertToHexTextIndex(fsFixedHeadrAddr->args[i++]);
139         auto fourthArgument = ConvertToHexTextIndex(fsFixedHeadrAddr->args[i]);
140         // get file descriptor
141         uint64_t filePathId = INVALID_UINT64;
142         auto fd = GetFileDescriptor(fsFixedHeadrAddr, type);
143         size_t size = FileWriteOperation(tracerEventToStrIndexMap, fsFixedHeadrAddr, itid, filePathId, type);
144         FileSystemSampleRow fileSystemSampleRow = {
145             currentCallId_, type, ipid, itid,       newStartTs,    newEndTs,       duration,      returnValue,
146             errorCode,      size, fd,   filePathId, firstArgument, secondArgument, thirdArgument, fourthArgument};
147         traceDataCache_->GetFileSystemSample()->AppendNewData(fileSystemSampleRow);
148         if (!callIdExistFlag) {
149             ParseCallStackData(userIpsAddr, fsFixedHeadrAddr->nrUserIPs, fsFixedHeadrAddr->pid, currentCallId_);
150         }
151     }
152 }
153 
GetFileDescriptor(const FsFixedHeader * fsFixedHeader,uint32_t fucType)154 int32_t FileSystemDataParser::GetFileDescriptor(const FsFixedHeader *fsFixedHeader, uint32_t fucType)
155 {
156     auto returnValue = fsFixedHeader->ret;
157     int32_t fd = INVALID_INT32;
158     if (fucType == OPEN and returnValue >= 0) {
159         fd = returnValue;
160     } else if (fucType == READ or fucType == WRITE) {
161         fd = fsFixedHeader->args[0];
162     } else if (fucType == CLOSE) {
163         fd = fsFixedHeader->args[1];
164     }
165     return fd;
166 }
167 } // namespace TraceStreamer
168 } // namespace SysTuning
169