• 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 
16 #include "rpc_server.h"
17 
18 #include <cstdint>
19 #include <cstring>
20 #include <functional>
21 #if IS_WASM
22 #include <filesystem>
23 #endif
24 #include "log.h"
25 #include "string_help.h"
26 #include "version.h"
27 
28 #define UNUSED(expr)             \
29     do {                         \
30         static_cast<void>(expr); \
31     } while (0)
32 namespace SysTuning {
33 namespace TraceStreamer {
34 uint32_t g_fileLen = 0;
35 FILE* g_importFileFd = nullptr;
ParseData(const uint8_t * data,size_t len,ResultCallBack resultCallBack)36 bool RpcServer::ParseData(const uint8_t* data, size_t len, ResultCallBack resultCallBack)
37 {
38     g_loadSize += len;
39     size_t blockSize = 1024 * 1024;
40     do {
41         size_t parseSize = std::min(len, blockSize);
42         std::unique_ptr<uint8_t[]> buf = std::make_unique<uint8_t[]>(parseSize);
43         std::copy(data, data + parseSize, buf.get());
44         if (!ts_->ParseTraceDataSegment(std::move(buf), parseSize)) {
45             if (resultCallBack) {
46                 resultCallBack("formaterror\r\n", SEND_FINISH);
47             }
48             return false;
49         }
50         data += parseSize;
51         len -= parseSize;
52         lenParseData_ += parseSize;
53     } while (len > 0);
54     if (resultCallBack) {
55         resultCallBack("ok\r\n", SEND_FINISH);
56     }
57     return true;
58 }
59 
UpdateTraceTime(const uint8_t * data,int32_t len)60 int32_t RpcServer::UpdateTraceTime(const uint8_t* data, int32_t len)
61 {
62     std::unique_ptr<uint8_t[]> buf = std::make_unique<uint8_t[]>(len);
63     std::copy(data, data + len, buf.get());
64     ts_->UpdateTraceRangeTime(buf.get(), len);
65     return 0;
66 }
67 
TraceStreamer_Init_ThirdParty_Config(const uint8_t * data,int32_t len)68 int32_t RpcServer::TraceStreamer_Init_ThirdParty_Config(const uint8_t* data, int32_t len)
69 {
70     TS_LOGE("TraceStreamer_Init_ThirdParty_Config is comming!");
71     std::string thirdPartyConfig = reinterpret_cast<const char*>(data);
72     TS_LOGE("thirdPartyConfig = %s", thirdPartyConfig.c_str());
73     std::vector<std::string> comPonentStr = SplitStringToVec(thirdPartyConfig, ";");
74     const int32_t EVENT_COUNT_PAIR = 2;
75     if (comPonentStr.size() % EVENT_COUNT_PAIR != 0) {
76         TS_LOGE("thirdPartyConfig is wrong!");
77         return -1;
78     }
79     for (int32_t m = 0; m < comPonentStr.size(); m += EVENT_COUNT_PAIR) {
80         int32_t componentId = std::stoi(comPonentStr.at(m));
81         std::string componentName = comPonentStr.at(m + 1);
82         TS_LOGE("comPonentStr[m] = %d, comPonentStr[m + 1] = %s", componentId, componentName.c_str());
83         g_thirdPartyConfig.insert((std::map<int32_t, std::string>::value_type(componentId, componentName)));
84     }
85     return 0;
86 }
87 
ParseDataOver(const uint8_t * data,size_t len,ResultCallBack resultCallBack)88 bool RpcServer::ParseDataOver(const uint8_t* data, size_t len, ResultCallBack resultCallBack)
89 {
90     UNUSED(data);
91     UNUSED(len);
92     MetaData* metaData = ts_->GetMetaData();
93     metaData->SetSourceFileName("input stream mode");
94     metaData->SetOutputFileName("wasm mode");
95     metaData->SetParserToolVersion(TRACE_STREAM_VERSION);
96     metaData->SetParserToolPublishDateTime(TRACE_STREAM_PUBLISHVERSION);
97     metaData->SetTraceDataSize(g_loadSize);
98     metaData->SetTraceType((ts_->DataType() == TRACE_FILETYPE_H_TRACE) ? "proto-based-trace" : "txt-based-trace");
99     TS_LOGI("RPC ParseDataOver, has parsed len %zu", lenParseData_);
100 
101     ts_->WaitForParserEnd();
102 #ifndef USE_VTABLE
103     ts_->Clear();
104 #endif
105     if (resultCallBack) {
106         resultCallBack("ok\r\n", SEND_FINISH);
107     }
108     lenParseData_ = 0;
109     g_loadSize = 0;
110     return true;
111 }
112 
SqlOperate(const uint8_t * data,size_t len,ResultCallBack resultCallBack)113 bool RpcServer::SqlOperate(const uint8_t* data, size_t len, ResultCallBack resultCallBack)
114 {
115     ts_->SetCancel(false);
116     std::string sql(reinterpret_cast<const char*>(data), len);
117     TS_LOGI("RPC SqlOperate(%s, %zu)", sql.c_str(), len);
118 
119     int32_t ret = ts_->OperateDatabase(sql);
120     if (resultCallBack) {
121         std::string response = "ok\r\n";
122         if (ret != 0) {
123             response = "dberror\r\n";
124         }
125         resultCallBack(response, SEND_FINISH);
126     }
127     return (ret == 0);
128 }
129 
SqlQuery(const uint8_t * data,size_t len,ResultCallBack resultCallBack)130 bool RpcServer::SqlQuery(const uint8_t* data, size_t len, ResultCallBack resultCallBack)
131 {
132     ts_->SetCancel(false);
133     std::string sql(reinterpret_cast<const char*>(data), len);
134     TS_LOGI("RPC SqlQuery %zu:%s", len, sql.c_str());
135 
136     int32_t ret = ts_->SearchDatabase(sql, resultCallBack);
137     if (resultCallBack && ret != 0) {
138         resultCallBack("dberror\r\n", SEND_FINISH);
139     }
140     ts_->SetCancel(false);
141     return (ret == 0);
142 }
143 
CancelSqlQuery()144 void RpcServer::CancelSqlQuery()
145 {
146     ts_->SetCancel(true);
147 }
148 
Reset(const uint8_t * data,size_t len,ResultCallBack resultCallBack)149 bool RpcServer::Reset(const uint8_t* data, size_t len, ResultCallBack resultCallBack)
150 {
151     UNUSED(data);
152     UNUSED(len);
153     TS_LOGI("RPC reset trace_streamer");
154 
155     ts_->WaitForParserEnd();
156     ts_ = std::make_unique<TraceStreamerSelector>();
157     if (resultCallBack) {
158         resultCallBack("ok\r\n", SEND_FINISH);
159     }
160     return true;
161 }
162 
WasmSqlQuery(const uint8_t * data,size_t len,uint8_t * out,int32_t outLen)163 int32_t RpcServer::WasmSqlQuery(const uint8_t* data, size_t len, uint8_t* out, int32_t outLen)
164 {
165     ts_->SetCancel(false);
166     std::string sql(reinterpret_cast<const char*>(data), len);
167     TS_LOGI("WASM RPC SqlQuery outlen(%d) sql(%zu:%s)", outLen, len, sql.c_str());
168 
169     int32_t ret = ts_->SearchDatabase(sql, out, outLen);
170     return ret;
171 }
WasmSqlQueryWithCallback(const uint8_t * data,size_t len,ResultCallBack callback) const172 int32_t RpcServer::WasmSqlQueryWithCallback(const uint8_t* data, size_t len, ResultCallBack callback) const
173 {
174     ts_->SetCancel(false);
175     std::string sql(reinterpret_cast<const char*>(data), len);
176     TS_LOGI("WASM RPC SqlQuery sql(%zu:%s)", len, sql.c_str());
177 
178     int32_t ret = ts_->SearchDatabase(sql, callback);
179     return ret;
180 }
181 
WasmExportDatabase(ResultCallBack resultCallBack)182 int32_t RpcServer::WasmExportDatabase(ResultCallBack resultCallBack)
183 {
184     return ts_->ExportDatabase("default.db", resultCallBack);
185 }
186 
187 #if IS_WASM
DownloadELFCallback(const std::string & fileName,size_t totalLen,const uint8_t * data,size_t len,int32_t finish,ParseELFFileCallBack parseELFFile)188 int32_t RpcServer::DownloadELFCallback(const std::string& fileName,
189                                        size_t totalLen,
190                                        const uint8_t* data,
191                                        size_t len,
192                                        int32_t finish,
193                                        ParseELFFileCallBack parseELFFile)
194 {
195     g_fileLen += len;
196     std::string filePath = "";
197     TS_LOGI("fileName = %s", fileName.c_str());
198     std::string symbolsPath = fileName.substr(0, fileName.find("/"));
199     TS_LOGI("symbolsPath = %s", symbolsPath.c_str());
200     filePath = fileName.substr(0, fileName.find_last_of("/"));
201     if (std::filesystem::exists(filePath)) {
202         TS_LOGE("%s exist", filePath.c_str());
203     } else {
204         if (std::filesystem::create_directories(filePath)) {
205             TS_LOGI("create_directories success");
206         } else {
207             TS_LOGI("create_directories failed!");
208         }
209     }
210     TS_LOGI("filePath = %s", filePath.c_str());
211     if (g_fileLen < totalLen) {
212         if (g_importFileFd == nullptr) {
213             g_importFileFd = fopen(fileName.c_str(), "a+");
214             if (g_importFileFd == nullptr) {
215                 TS_LOGE("wasm file create failed");
216                 return false;
217             }
218         }
219         int32_t writeLength = fwrite(data, len, 1, g_importFileFd);
220         if (!writeLength) {
221             fclose(g_importFileFd);
222             TS_LOGE("wasm write file failed");
223             return false;
224         }
225         return false;
226     }
227     g_fileLen = 0;
228     if (g_importFileFd == nullptr) {
229         g_importFileFd = fopen(fileName.c_str(), "a+");
230         if (g_importFileFd == nullptr) {
231             TS_LOGE("wasm file create failed");
232             return false;
233         }
234     }
235     int32_t writeLength = fwrite(data, len, 1, g_importFileFd);
236     (void)fclose(g_importFileFd);
237     g_importFileFd = nullptr;
238     if (!writeLength) {
239         TS_LOGE("wasm write file failed");
240         return false;
241     }
242     TS_LOGI("symbolsPath = %s, fileName = %s", symbolsPath.c_str(), fileName.c_str());
243     symbolsPathFiles_.emplace_back(fileName);
244     parseELFFile("file send over\r\n", SEND_FINISH);
245 
246     if (finish) {
247         if (!ts_->ReloadSymbolFiles(symbolsPath, symbolsPathFiles_)) {
248             symbolsPathFiles_.clear();
249             if (parseELFFile) {
250                 parseELFFile("formaterror\r\n", SEND_FINISH);
251             }
252             return false;
253         }
254         symbolsPathFiles_.clear();
255         if (parseELFFile) {
256             parseELFFile("ok\r\n", SEND_FINISH);
257         }
258         std::filesystem::remove_all(symbolsPath);
259     }
260     return true;
261 }
262 #endif
263 } // namespace TraceStreamer
264 } // namespace SysTuning
265