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 "service_controller.h"
17
18 #include <algorithm>
19 #include <array>
20 #include <chrono>
21 #include <cstdio>
22 #include <cstring>
23 #include <ctime>
24 #include <fcntl.h>
25 #include <iostream>
26 #include <memory>
27 #include <optional>
28 #include <regex>
29 #include <sstream>
30 #include <sys/mman.h>
31 #include <sys/prctl.h>
32 #include <thread>
33
34 #include <unistd.h>
35 #include <dirent.h>
36
37 #include <securec.h>
38 #include "hilog/log.h"
39 #include "hilog_common.h"
40 #include "log_data.h"
41 #include "hilogtool_msg.h"
42 #include "log_buffer.h"
43 #include "log_persister.h"
44
45 namespace OHOS {
46 namespace HiviewDFX {
47 using namespace std;
48 string g_logPersisterDir = HILOG_FILE_DIR;
49 constexpr int DEFAULT_LOG_TYPE = 1<<LOG_INIT | 1<<LOG_APP | 1<<LOG_CORE | 1<<LOG_KMSG;
50
51 constexpr int INFO_SUFFIX = 5;
52
SetMsgHead(MessageHeader & msgHeader,uint8_t msgCmd,uint16_t msgLen)53 inline void SetMsgHead(MessageHeader& msgHeader, uint8_t msgCmd, uint16_t msgLen)
54 {
55 msgHeader.version = 0;
56 msgHeader.msgType = msgCmd;
57 msgHeader.msgLen = msgLen;
58 }
59
IsValidFileName(const std::string & strFileName)60 inline bool IsValidFileName(const std::string& strFileName)
61 {
62 // File name shouldn't contain "[\\/:*?\"<>|]"
63 std::regex regExpress("[\\/:*?\"<>|]");
64 bool bValid = !std::regex_search(strFileName, regExpress);
65 return bValid;
66 }
67
IsLogTypeForbidden(uint16_t queryTypes)68 inline bool IsLogTypeForbidden(uint16_t queryTypes)
69 {
70 if (queryTypes == (0b01 << LOG_KMSG) || (queryTypes & (0b01 << LOG_KMSG)) == 0) {
71 return false;
72 } else {
73 std::cout << "queryTypes can not contain app/core/init and kmsg at the same time,"
74 "try to -t app/core/init or -t kmsg separately\n";
75 return true;
76 }
77 }
78
StartPersistStoreJob(const LogPersister::InitData & initData,HilogBuffer & hilogBuffer)79 int StartPersistStoreJob(const LogPersister::InitData& initData, HilogBuffer& hilogBuffer)
80 {
81 std::shared_ptr<LogPersister> persister = LogPersister::CreateLogPersister(hilogBuffer);
82
83 int persistRes = persister->Init(initData);
84 if (persistRes != RET_SUCCESS) {
85 if (persistRes == ERR_LOG_PERSIST_TASK_FAIL) {
86 std::cerr << __PRETTY_FUNCTION__ << " Log persist task exists!\n";
87 } else {
88 std::cerr << __PRETTY_FUNCTION__ << " LogPersister failed to initialize!\n";
89 }
90 return persistRes;
91 }
92 persister->Start();
93 return RET_SUCCESS;
94 }
95
HandlePersistStartRequest(const PacketBuf & rawData)96 void ServiceController::HandlePersistStartRequest(const PacketBuf& rawData)
97 {
98 const LogPersistStartRequest* request = reinterpret_cast<const LogPersistStartRequest*>(rawData.data());
99 const LogPersistStartMsg* requestMsg = reinterpret_cast<const LogPersistStartMsg*>(&request->logPersistStartMsg);
100
101 PacketBuf respondRaw = {0};
102 LogPersistStartResponse* respond = reinterpret_cast<LogPersistStartResponse*>(respondRaw.data());
103 LogPersistStartResult* respondMsg = reinterpret_cast<LogPersistStartResult*>(&respond->logPersistStartRst);
104
105 if (respondMsg == nullptr) {
106 return;
107 } else if (IsLogTypeForbidden(requestMsg->logType)) {
108 respondMsg->result = ERR_QUERY_TYPE_INVALID;
109 } else if (requestMsg->jobId <= 0) {
110 respondMsg->result = ERR_LOG_PERSIST_JOBID_INVALID;
111 } else if (requestMsg->fileSize < MAX_PERSISTER_BUFFER_SIZE) {
112 std::cout << __PRETTY_FUNCTION__ << " Persist log file size less than min size\n";
113 respondMsg->result = ERR_LOG_PERSIST_FILE_SIZE_INVALID;
114 } else if (!IsValidFileName(requestMsg->filePath)) {
115 std::cout << __PRETTY_FUNCTION__ << " FileName is not valid!\n";
116 respondMsg->result = ERR_LOG_PERSIST_FILE_NAME_INVALID;
117 } else if (requestMsg->fileNum > MAX_LOG_FILE_NUM || requestMsg->fileNum < MIN_LOG_FILE_NUM) {
118 cout << "File number is not valid!" << endl;
119 respondMsg->result = ERR_LOG_FILE_NUM_INVALID;
120 } else {
121 LogPersister::InitData initData = *requestMsg;
122 auto& requestMsgCpy = std::get<LogPersistStartMsg>(initData);
123
124 bool isKmsg = (requestMsgCpy.logType == (0b01 << LOG_KMSG));
125 std::string logPersisterFileName = isKmsg ? "hilog_kmsg" : "hilog";
126 std::cout << __PRETTY_FUNCTION__ << " logPersisterFileName: " << logPersisterFileName << "\n";
127 bool isPathEmpty = requestMsgCpy.filePath[0] == '\0' ? true : false;
128 std::string logPersisterPath = isPathEmpty
129 ? (g_logPersisterDir + logPersisterFileName)
130 : (g_logPersisterDir + string(requestMsgCpy.filePath));
131 if (strcpy_s(requestMsgCpy.filePath, FILE_PATH_MAX_LEN, logPersisterPath.c_str()) != 0) {
132 std::cerr << __PRETTY_FUNCTION__ << " Can't copy request msg filePath for log persister\n";
133 respondMsg->result = RET_FAIL;
134 } else {
135 respondMsg->result = StartPersistStoreJob(initData, m_hilogBuffer);
136 }
137 }
138
139 respondMsg->jobId = requestMsg->jobId;
140 SetMsgHead(respond->msgHeader, MC_RSP_LOG_PERSIST_START, sizeof(*respondMsg));
141 m_communicationSocket->Write(respondRaw.data(), sizeof(*respondMsg) + sizeof(MessageHeader));
142 }
143
HandlePersistStopRequest(const PacketBuf & rawData)144 void ServiceController::HandlePersistStopRequest(const PacketBuf& rawData)
145 {
146 const LogPersistStopRequest* request = reinterpret_cast<const LogPersistStopRequest*>(rawData.data());
147 const LogPersistStopMsg* requestMsg = reinterpret_cast<const LogPersistStopMsg*>(&request->logPersistStopMsg);
148
149 PacketBuf respondRaw = {0};
150 LogPersistStopResponse* respond = reinterpret_cast<LogPersistStopResponse*>(respondRaw.data());
151 LogPersistStopResult* respondMsg = reinterpret_cast<LogPersistStopResult*>(&respond->logPersistStopRst);
152
153 if (request->msgHeader.msgLen > sizeof(LogPersistStopMsg) * LOG_TYPE_MAX) {
154 return;
155 }
156 uint32_t msgNum = 0;
157 list<LogPersistQueryResult> resultList;
158 LogPersister::Query(DEFAULT_LOG_TYPE, resultList);
159 if (requestMsg && sizeof(LogPersistQueryMsg) <= request->msgHeader.msgLen) {
160 if (requestMsg->jobId != JOB_ID_ALL) {
161 int32_t rst = LogPersister::Kill(requestMsg->jobId);
162 if (respondMsg) {
163 respondMsg->jobId = requestMsg->jobId;
164 respondMsg->result = (rst < 0) ? rst : RET_SUCCESS;
165 respondMsg++;
166 msgNum++;
167 }
168 } else {
169 for (auto it = resultList.begin(); it != resultList.end(); ++it) {
170 int32_t rst = LogPersister::Kill((*it).jobId);
171 if (respondMsg) {
172 respondMsg->jobId = (*it).jobId;
173 respondMsg->result = (rst < 0) ? rst : RET_SUCCESS;
174 respondMsg++;
175 msgNum++;
176 }
177 }
178 }
179 }
180 uint16_t resultMessagesSize = msgNum * sizeof(LogPersistStopResult);
181 SetMsgHead(respond->msgHeader, MC_RSP_LOG_PERSIST_STOP, resultMessagesSize);
182 m_communicationSocket->Write(respondRaw.data(), resultMessagesSize + sizeof(MessageHeader));
183 }
184
HandlePersistQueryRequest(const PacketBuf & rawData)185 void ServiceController::HandlePersistQueryRequest(const PacketBuf& rawData)
186 {
187 const LogPersistQueryRequest* request = reinterpret_cast<const LogPersistQueryRequest*>(rawData.data());
188 const LogPersistQueryMsg* requestMsg = reinterpret_cast<const LogPersistQueryMsg*>(&request->logPersistQueryMsg);
189
190 PacketBuf respondRaw = {0};
191 LogPersistQueryResponse* respond = reinterpret_cast<LogPersistQueryResponse*>(respondRaw.data());
192 LogPersistQueryResult* respondMsg = reinterpret_cast<LogPersistQueryResult*>(&respond->logPersistQueryRst);
193
194 uint32_t recvMsgLen = 0;
195 uint32_t respondMsgNum = 0;
196
197 if (request->msgHeader.msgLen > sizeof(LogPersistQueryMsg) * LOG_TYPE_MAX) {
198 return;
199 }
200
201 while (requestMsg && recvMsgLen + sizeof(LogPersistQueryMsg) <= request->msgHeader.msgLen) {
202 list<LogPersistQueryResult> resultList;
203 std::cout << requestMsg->logType << endl;
204 int32_t rst = LogPersister::Query(requestMsg->logType, resultList);
205 for (auto it = resultList.begin(); it != resultList.end(); ++it) {
206 if ((respondMsgNum + 1) * sizeof(LogPersistQueryResult) + sizeof(MessageHeader) > respondRaw.size()) {
207 break;
208 }
209 if (respondMsg) {
210 respondMsg->result = (rst < 0) ? rst : RET_SUCCESS;
211 respondMsg->jobId = (*it).jobId;
212 respondMsg->logType = (*it).logType;
213 respondMsg->compressAlg = (*it).compressAlg;
214 if (strcpy_s(respondMsg->filePath, FILE_PATH_MAX_LEN, (*it).filePath)) {
215 return;
216 }
217 respondMsg->fileSize = (*it).fileSize;
218 respondMsg->fileNum = (*it).fileNum;
219 respondMsg++;
220 respondMsgNum++;
221 }
222 }
223 requestMsg++;
224 recvMsgLen += sizeof(LogPersistQueryMsg);
225 }
226 uint16_t respondMsgSize = respondMsgNum * sizeof(LogPersistQueryResult);
227 SetMsgHead(respond->msgHeader, MC_RSP_LOG_PERSIST_QUERY, respondMsgSize);
228 m_communicationSocket->Write(respondRaw.data(), respondMsgSize + sizeof(MessageHeader));
229 }
230
HandleBufferResizeRequest(const PacketBuf & rawData)231 void ServiceController::HandleBufferResizeRequest(const PacketBuf& rawData)
232 {
233 const BufferResizeRequest* request = reinterpret_cast<const BufferResizeRequest*>(rawData.data());
234 const BuffResizeMsg* requestMsg = reinterpret_cast<const BuffResizeMsg*>(&request->buffResizeMsg);
235
236 PacketBuf respondRaw = {0};
237 BufferResizeResponse* respond = reinterpret_cast<BufferResizeResponse*>(respondRaw.data());
238 BuffResizeResult* respondMsg = reinterpret_cast<BuffResizeResult*>(&respond->buffResizeRst);
239 uint32_t recvMsgLen = 0;
240 uint32_t respondMsgNum = 0;
241
242 if (request->msgHeader.msgLen > sizeof(BuffResizeMsg) * LOG_TYPE_MAX) {
243 return;
244 }
245
246 while (requestMsg && recvMsgLen + sizeof(BuffResizeMsg) <= request->msgHeader.msgLen) {
247 if ((respondMsgNum + 1) * sizeof(BuffResizeResult) + sizeof(MessageHeader) > respondRaw.size()) {
248 break;
249 }
250 int32_t rst = m_hilogBuffer.SetBuffLen(requestMsg->logType, requestMsg->buffSize);
251 if (respondMsg) {
252 respondMsg->logType = requestMsg->logType;
253 respondMsg->buffSize = requestMsg->buffSize;
254 respondMsg->result = (rst < 0) ? rst : RET_SUCCESS;
255 respondMsg++;
256 }
257 requestMsg++;
258 recvMsgLen += sizeof(BuffResizeMsg);
259 respondMsgNum++;
260 }
261 uint16_t respondMsgSize = respondMsgNum * sizeof(BuffResizeResult);
262 SetMsgHead(respond->msgHeader, MC_RSP_BUFFER_RESIZE, respondMsgSize);
263 m_communicationSocket->Write(respondRaw.data(), respondMsgSize + sizeof(MessageHeader));
264 }
265
HandleBufferSizeRequest(const PacketBuf & rawData)266 void ServiceController::HandleBufferSizeRequest(const PacketBuf& rawData)
267 {
268 const BufferSizeRequest* request = reinterpret_cast<const BufferSizeRequest*>(rawData.data());
269 const BuffSizeMsg* requestMsg = reinterpret_cast<const BuffSizeMsg*>(&request->buffSizeMsg);
270
271 PacketBuf respondRaw = {0};
272 BufferSizeResponse* respond = reinterpret_cast<BufferSizeResponse*>(respondRaw.data());
273 BuffSizeResult* pBuffSizeRst = reinterpret_cast<BuffSizeResult*>(&respond->buffSizeRst);
274
275 uint32_t recvMsgLen = 0;
276 uint32_t respondMsgNum = 0;
277
278 if (request->msgHeader.msgLen > sizeof(BuffSizeMsg) * LOG_TYPE_MAX) {
279 return;
280 }
281
282 while (requestMsg && recvMsgLen + sizeof(BuffSizeMsg) <= request->msgHeader.msgLen) {
283 if ((respondMsgNum + 1) * sizeof(BuffSizeResult) + sizeof(MessageHeader) > respondRaw.size()) {
284 break;
285 }
286 int64_t buffLen = m_hilogBuffer.GetBuffLen(requestMsg->logType);
287 if (pBuffSizeRst) {
288 pBuffSizeRst->logType = requestMsg->logType;
289 pBuffSizeRst->buffSize = static_cast<uint64_t>(buffLen);
290 pBuffSizeRst->result = (buffLen < 0) ? buffLen : RET_SUCCESS;
291 pBuffSizeRst++;
292 }
293 recvMsgLen += sizeof(BuffSizeMsg);
294 respondMsgNum++;
295 requestMsg++;
296 }
297 uint16_t respondMsgSize = respondMsgNum * sizeof(BuffSizeResult);
298 SetMsgHead(respond->msgHeader, MC_RSP_BUFFER_SIZE, respondMsgSize);
299 m_communicationSocket->Write(respondRaw.data(), respondMsgSize + sizeof(MessageHeader));
300 }
301
HandleInfoQueryRequest(const PacketBuf & rawData)302 void ServiceController::HandleInfoQueryRequest(const PacketBuf& rawData)
303 {
304 PacketBuf respondRaw = {0};
305 const StatisticInfoQueryRequest* request = reinterpret_cast<const StatisticInfoQueryRequest*>(rawData.data());
306 StatisticInfoQueryResponse* respond = reinterpret_cast<StatisticInfoQueryResponse*>(respondRaw.data());
307
308 if (request->domain == 0xffffffff) {
309 respond->logType = request->logType;
310 respond->domain = request->domain;
311 int32_t rst = m_hilogBuffer.GetStatisticInfoByLog(request->logType, respond->printLen,
312 respond->cacheLen, respond->dropped);
313 respond->result = (rst < 0) ? rst : RET_SUCCESS;
314 } else {
315 respond->logType = request->logType;
316 respond->domain = request->domain;
317 int32_t rst = m_hilogBuffer.GetStatisticInfoByDomain(request->domain, respond->printLen,
318 respond->cacheLen, respond->dropped);
319 respond->result = (rst < 0) ? rst : RET_SUCCESS;
320 }
321 SetMsgHead(respond->msgHeader, MC_RSP_STATISTIC_INFO_QUERY, sizeof(*respond) - sizeof(MessageHeader));
322 m_communicationSocket->Write(respondRaw.data(), sizeof(*respond));
323 }
324
HandleInfoClearRequest(const PacketBuf & rawData)325 void ServiceController::HandleInfoClearRequest(const PacketBuf& rawData)
326 {
327 PacketBuf respondRaw = {0};
328 const StatisticInfoClearRequest* request = reinterpret_cast<const StatisticInfoClearRequest*>(rawData.data());
329 StatisticInfoClearResponse* respond = reinterpret_cast<StatisticInfoClearResponse*>(respondRaw.data());
330 if (request->domain == 0xffffffff) {
331 respond->logType = request->logType;
332 respond->domain = request->domain;
333 int32_t rst = m_hilogBuffer.ClearStatisticInfoByLog(request->logType);
334 respond->result = (rst < 0) ? rst : RET_SUCCESS;
335 } else {
336 respond->logType = request->logType;
337 respond->domain = request->domain;
338 int32_t rst = m_hilogBuffer.ClearStatisticInfoByDomain(request->domain);
339 respond->result = (rst < 0) ? rst : RET_SUCCESS;
340 }
341 SetMsgHead(respond->msgHeader, MC_RSP_STATISTIC_INFO_CLEAR, sizeof(*respond) - sizeof(MessageHeader));
342 m_communicationSocket->Write(respondRaw.data(), sizeof(*respond));
343 }
344
HandleBufferClearRequest(const PacketBuf & rawData)345 void ServiceController::HandleBufferClearRequest(const PacketBuf& rawData)
346 {
347 const LogClearRequest* request = reinterpret_cast<const LogClearRequest*>(rawData.data());
348 const LogClearMsg* requestMsg = reinterpret_cast<const LogClearMsg*>(&request->logClearMsg);
349
350 PacketBuf respondRaw = {0};
351 LogClearResponse* respond = reinterpret_cast<LogClearResponse*>(respondRaw.data());
352 LogClearResult* respondMsg = reinterpret_cast<LogClearResult*>(&respond->logClearRst);
353
354 uint32_t recvMsgLen = 0;
355 uint32_t respondMsgNum = 0;
356
357 if (request->msgHeader.msgLen > sizeof(LogClearMsg) * LOG_TYPE_MAX) {
358 return;
359 }
360
361 while (requestMsg && recvMsgLen + sizeof(LogClearMsg) <= request->msgHeader.msgLen) {
362 if ((respondMsgNum + 1) * sizeof(LogClearResult) + sizeof(MessageHeader) > respondRaw.size()) {
363 break;
364 }
365 int32_t rst = m_hilogBuffer.Delete(requestMsg->logType);
366 if (respondMsg) {
367 respondMsg->logType = requestMsg->logType;
368 respondMsg->result = (rst < 0) ? rst : RET_SUCCESS;
369 respondMsg++;
370 }
371 requestMsg++;
372 recvMsgLen += sizeof(LogClearMsg);
373 respondMsgNum++;
374 }
375
376 uint16_t respondMsgSize = respondMsgNum * sizeof(LogClearResult);
377 SetMsgHead(respond->msgHeader, MC_RSP_LOG_CLEAR, respondMsgSize);
378 m_communicationSocket->Write(respondRaw.data(), respondMsgSize + sizeof(MessageHeader));
379 }
380
381
ServiceController(std::unique_ptr<Socket> communicationSocket,HilogBuffer & buffer)382 ServiceController::ServiceController(std::unique_ptr<Socket> communicationSocket, HilogBuffer& buffer)
383 : m_communicationSocket(std::move(communicationSocket))
384 , m_hilogBuffer(buffer)
385 {
386 m_bufReader = m_hilogBuffer.CreateBufReader([this]() { NotifyForNewData(); });
387 }
388
~ServiceController()389 ServiceController::~ServiceController()
390 {
391 m_hilogBuffer.RemoveBufReader(m_bufReader);
392
393 m_notifyNewDataCv.notify_all();
394 }
395
CommunicationLoop(const std::atomic<bool> & stopLoop)396 void ServiceController::CommunicationLoop(const std::atomic<bool>& stopLoop)
397 {
398 std::cout << __PRETTY_FUNCTION__ << " Begin\n";
399 if (!m_communicationSocket) {
400 std::cerr << __PRETTY_FUNCTION__ << " Invalid socket handler!\n";
401 return;
402 }
403 PacketBuf rawDataBuffer = {0};
404 ;
405 while (!stopLoop.load() && m_communicationSocket->Read(rawDataBuffer.data(), rawDataBuffer.size() - 1) > 0) {
406 MessageHeader *header = reinterpret_cast<MessageHeader *>(rawDataBuffer.data());
407 switch (header->msgType) {
408 case LOG_QUERY_REQUEST:
409 SetFilters(rawDataBuffer);
410 if (IsLogTypeForbidden(m_filters.inclusions.types)) {
411 return;
412 }
413 HandleLogQueryRequest();
414 break;
415 case NEXT_REQUEST:
416 HandleNextRequest(rawDataBuffer, stopLoop);
417 break;
418 case MC_REQ_LOG_PERSIST_START:
419 HandlePersistStartRequest(rawDataBuffer);
420 break;
421 case MC_REQ_LOG_PERSIST_STOP:
422 HandlePersistStopRequest(rawDataBuffer);
423 break;
424 case MC_REQ_LOG_PERSIST_QUERY:
425 HandlePersistQueryRequest(rawDataBuffer);
426 break;
427 case MC_REQ_BUFFER_RESIZE:
428 HandleBufferResizeRequest(rawDataBuffer);
429 break;
430 case MC_REQ_BUFFER_SIZE:
431 HandleBufferSizeRequest(rawDataBuffer);
432 break;
433 case MC_REQ_STATISTIC_INFO_QUERY:
434 HandleInfoQueryRequest(rawDataBuffer);
435 break;
436 case MC_REQ_STATISTIC_INFO_CLEAR:
437 HandleInfoClearRequest(rawDataBuffer);
438 break;
439 case MC_REQ_LOG_CLEAR:
440 HandleBufferClearRequest(rawDataBuffer);
441 break;
442 default:
443 std::cout << __PRETTY_FUNCTION__ << " Unknown message. Skipped!\n";
444 break;
445 }
446 }
447 std::cout << __PRETTY_FUNCTION__ << " Done\n";
448 }
449
SetFilters(const PacketBuf & rawData)450 void ServiceController::SetFilters(const PacketBuf& rawData)
451 {
452 const LogQueryRequest& qRstMsg = *reinterpret_cast<const LogQueryRequest*>(rawData.data());
453 m_filters.inclusions.levels = qRstMsg.levels;
454 m_filters.inclusions.types = qRstMsg.types;
455
456 m_filters.inclusions.pids.resize(std::min(qRstMsg.nPid, static_cast<uint8_t>(MAX_PIDS)));
457 std::copy(qRstMsg.pids, qRstMsg.pids+m_filters.inclusions.pids.size(), m_filters.inclusions.pids.begin());
458
459 m_filters.inclusions.domains.resize(std::min(qRstMsg.nDomain, static_cast<uint8_t>(MAX_DOMAINS)));
460 std::copy(qRstMsg.domains, qRstMsg.domains+m_filters.inclusions.domains.size(),
461 m_filters.inclusions.domains.begin());
462
463 m_filters.inclusions.tags.resize(std::min(qRstMsg.nTag, static_cast<uint8_t>(MAX_TAGS)));
464 for (size_t i = 0; i < m_filters.inclusions.tags.size(); ++i) {
465 m_filters.inclusions.tags[i] = qRstMsg.tags[i];
466 }
467
468 m_filters.exclusions.levels = qRstMsg.noLevels;
469 m_filters.exclusions.types = qRstMsg.noTypes;
470
471 m_filters.exclusions.pids.resize(std::min(qRstMsg.nNoPid, static_cast<uint8_t>(MAX_PIDS)));
472 std::copy(qRstMsg.noPids, qRstMsg.noPids+m_filters.exclusions.pids.size(), m_filters.exclusions.pids.begin());
473
474 m_filters.exclusions.domains.resize(std::min(qRstMsg.nNoDomain, static_cast<uint8_t>(MAX_DOMAINS)));
475 std::copy(qRstMsg.noDomains, qRstMsg.noDomains+m_filters.exclusions.domains.size(),
476 m_filters.exclusions.domains.begin());
477
478 m_filters.exclusions.tags.resize(std::min(qRstMsg.nNoTag, static_cast<uint8_t>(MAX_TAGS)));
479 for (size_t i = 0; i < m_filters.exclusions.tags.size(); ++i) {
480 m_filters.exclusions.tags[i] = qRstMsg.noTags[i];
481 }
482 }
483
HandleLogQueryRequest()484 void ServiceController::HandleLogQueryRequest()
485 {
486 auto result = m_hilogBuffer.Query(m_filters, m_bufReader, [this](const HilogData& logData) {
487 WriteLogQueryRespond(SENDIDA, LOG_QUERY_RESPONSE, logData);
488 });
489 if (!result) {
490 WriteLogQueryRespond(SENDIDN, LOG_QUERY_RESPONSE, std::nullopt);
491 }
492 }
493
HandleNextRequest(const PacketBuf & rawData,const std::atomic<bool> & stopLoop)494 void ServiceController::HandleNextRequest(const PacketBuf& rawData, const std::atomic<bool>& stopLoop)
495 {
496 const NextRequest& nRstMsg = *reinterpret_cast<const NextRequest*>(rawData.data());
497 if (nRstMsg.sendId != SENDIDA) {
498 return;
499 }
500
501 auto result = m_hilogBuffer.Query(m_filters, m_bufReader, [this](const HilogData& logData) {
502 WriteLogQueryRespond(SENDIDA, NEXT_RESPONSE, logData);
503 });
504 if (!result) {
505 WriteLogQueryRespond(SENDIDN, NEXT_RESPONSE, std::nullopt);
506 } else {
507 return;
508 }
509
510 std::unique_lock<decltype(m_notifyNewDataMtx)> ul(m_notifyNewDataMtx);
511 for (;;) {
512 bool isStopped = stopLoop.load();
513 if (isStopped) {
514 return;
515 }
516
517 bool isNotified = m_notifyNewDataCv.wait_for(ul, 100ms) == std::cv_status::no_timeout;
518 if (isNotified) {
519 break;
520 }
521 }
522 LogQueryResponse rsp;
523 rsp.data.sendId = SENDIDS;
524 rsp.data.type = -1;
525 /* set header */
526 SetMsgHead(rsp.header, NEXT_RESPONSE, sizeof(rsp));
527 if (WriteData(rsp, std::nullopt) <= 0) {
528 std::cerr << __PRETTY_FUNCTION__ << " Can't send notification about new logs\n";
529 }
530 }
531
WriteLogQueryRespond(unsigned int sendId,uint32_t respondCmd,OptCRef<HilogData> pData)532 int ServiceController::WriteLogQueryRespond(unsigned int sendId, uint32_t respondCmd, OptCRef<HilogData> pData)
533 {
534 LogQueryResponse rsp;
535 MessageHeader& header = rsp.header;
536 HilogDataMessage& msg = rsp.data;
537
538 /* set header */
539 SetMsgHead(header, respondCmd, sizeof(rsp) + ((pData != std::nullopt) ? pData->get().len : 0));
540
541 /* set data */
542 msg.sendId = sendId;
543 if (pData != std::nullopt) {
544 const HilogData& data = pData->get();
545 msg.length = data.len; /* data len, equals tag_len plus content length, include '\0' */
546 msg.level = data.level;
547 msg.type = data.type;
548 msg.tag_len = data.tag_len; /* include '\0' */
549 msg.pid = data.pid;
550 msg.tid = data.tid;
551 msg.domain = data.domain;
552 msg.tv_sec = data.tv_sec;
553 msg.tv_nsec = data.tv_nsec;
554 }
555
556 /* write into socket */
557 return WriteData(rsp, pData);
558 }
559
WriteData(LogQueryResponse & rsp,OptCRef<HilogData> pData)560 int ServiceController::WriteData(LogQueryResponse& rsp, OptCRef<HilogData> pData)
561 {
562 iovec vec[3];
563 vec[0].iov_base = &rsp;
564 vec[0].iov_len = sizeof(LogQueryResponse);
565 if (pData == std::nullopt) {
566 return WriteV(vec, 1);
567 }
568 const HilogData& data = pData->get();
569 vec[1].iov_base = data.tag;
570 vec[1].iov_len = data.tag_len;
571 vec[2].iov_base = data.content;
572 vec[2].iov_len = data.len - data.tag_len;
573
574 return WriteV(vec, 3);
575 }
576
WriteV(const iovec * vec,size_t len)577 int ServiceController::WriteV(const iovec* vec, size_t len)
578 {
579 static thread_local std::vector<char> dataBuf;
580
581 size_t allSize = 0;
582 for (size_t i = 0; i < len; ++i) {
583 allSize += vec[i].iov_len;
584 }
585
586 if (dataBuf.size() < allSize) {
587 dataBuf.resize(allSize);
588 }
589
590 uint32_t offset = 0;
591 for (uint32_t i = 0; i < len; ++i) {
592 auto src_address = (char*)vec[i].iov_base;
593 std::copy(src_address, src_address + vec[i].iov_len, dataBuf.data() + offset);
594 offset += vec[i].iov_len;
595 }
596 return m_communicationSocket->Write(dataBuf.data(), allSize);
597 }
598
NotifyForNewData()599 void ServiceController::NotifyForNewData()
600 {
601 m_notifyNewDataCv.notify_one();
602 }
603
RestorePersistJobs(HilogBuffer & hilogBuffer)604 int RestorePersistJobs(HilogBuffer& hilogBuffer)
605 {
606 std::cout << __PRETTY_FUNCTION__ << " Start restoring persist jobs!\n";
607 DIR *dir = opendir(g_logPersisterDir.c_str());
608 struct dirent *ent = nullptr;
609 if (dir != nullptr) {
610 while ((ent = readdir(dir)) != nullptr) {
611 size_t length = strlen(ent->d_name);
612 std::string pPath(ent->d_name, length);
613 if (length >= INFO_SUFFIX && pPath.substr(length - INFO_SUFFIX, length) == ".info") {
614 if (pPath == "hilog.info") continue;
615 std::cout << __PRETTY_FUNCTION__ << " Found a persist job! Path: " << g_logPersisterDir + pPath << "\n";
616 FILE* infile = fopen((g_logPersisterDir + pPath).c_str(), "r");
617 if (infile == nullptr) {
618 std::cerr << __PRETTY_FUNCTION__ << " Error opening recovery info file!\n";
619 continue;
620 }
621 LogPersister::InitData initData = PersistRecoveryInfo();
622 auto& info = std::get<PersistRecoveryInfo>(initData);
623 fread(&info, sizeof(PersistRecoveryInfo), 1, infile);
624 uint64_t hashSum = 0L;
625 fread(&hashSum, sizeof(hashSum), 1, infile);
626 fclose(infile);
627 uint64_t hash = GenerateHash(info);
628 if (hash != hashSum) {
629 std::cout << __PRETTY_FUNCTION__ << " Info file checksum Failed!\n";
630 continue;
631 }
632 int result = StartPersistStoreJob(initData, hilogBuffer);
633 std::cout << __PRETTY_FUNCTION__ << " Recovery Info:\n"
634 << " restoring result: " << (result == RET_SUCCESS
635 ? std::string("Success\n")
636 : std::string("Failed(") + std::to_string(result) + ")\n")
637 << " jobId=" << (unsigned)(info.msg.jobId) << "\n"
638 << " filePath=" << (info.msg.filePath) << "\n"
639 << " index=" << (info.index) << "\n";
640 }
641 }
642 closedir(dir);
643 } else {
644 perror("Failed to open persister directory!");
645 return ERR_LOG_PERSIST_DIR_OPEN_FAIL;
646 }
647 std::cout << __PRETTY_FUNCTION__ << " Finished restoring persist jobs!\n";
648 return EXIT_SUCCESS;
649 }
650 } // namespace HiviewDFX
651 } // namespace OHOS
652