• 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 
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