12498b56bSopenharmony_ci/*
22498b56bSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
32498b56bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
42498b56bSopenharmony_ci * you may not use this file except in compliance with the License.
52498b56bSopenharmony_ci * You may obtain a copy of the License at
62498b56bSopenharmony_ci *
72498b56bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
82498b56bSopenharmony_ci *
92498b56bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
102498b56bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
112498b56bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
122498b56bSopenharmony_ci * See the License for the specific language governing permissions and
132498b56bSopenharmony_ci * limitations under the License.
142498b56bSopenharmony_ci */
152498b56bSopenharmony_ci#include <algorithm>
162498b56bSopenharmony_ci#include <array>
172498b56bSopenharmony_ci#include <chrono>
182498b56bSopenharmony_ci#include <cstdio>
192498b56bSopenharmony_ci#include <cstring>
202498b56bSopenharmony_ci#include <ctime>
212498b56bSopenharmony_ci#include <fcntl.h>
222498b56bSopenharmony_ci#include <iostream>
232498b56bSopenharmony_ci#include <memory>
242498b56bSopenharmony_ci#include <optional>
252498b56bSopenharmony_ci#include <regex>
262498b56bSopenharmony_ci#include <sstream>
272498b56bSopenharmony_ci#include <sys/mman.h>
282498b56bSopenharmony_ci#include <sys/prctl.h>
292498b56bSopenharmony_ci#include <sys/stat.h>
302498b56bSopenharmony_ci#include <thread>
312498b56bSopenharmony_ci#include <unistd.h>
322498b56bSopenharmony_ci#include <dirent.h>
332498b56bSopenharmony_ci
342498b56bSopenharmony_ci#include <securec.h>
352498b56bSopenharmony_ci#include <hilog/log.h>
362498b56bSopenharmony_ci#include <hilog_common.h>
372498b56bSopenharmony_ci#include <log_utils.h>
382498b56bSopenharmony_ci#include <properties.h>
392498b56bSopenharmony_ci
402498b56bSopenharmony_ci#include "log_data.h"
412498b56bSopenharmony_ci#include "log_buffer.h"
422498b56bSopenharmony_ci#include "log_kmsg.h"
432498b56bSopenharmony_ci
442498b56bSopenharmony_ci#include "service_controller.h"
452498b56bSopenharmony_ci
462498b56bSopenharmony_cinamespace OHOS {
472498b56bSopenharmony_cinamespace HiviewDFX {
482498b56bSopenharmony_ciusing namespace std;
492498b56bSopenharmony_cistatic const string LOG_PERSISTER_DIR = HILOG_FILE_DIR;
502498b56bSopenharmony_cistatic constexpr uint16_t DEFAULT_LOG_TYPES = ((0b01 << LOG_APP) | (0b01 << LOG_CORE)
512498b56bSopenharmony_ci                                              | (0b01 << LOG_INIT) | (0b01 << LOG_ONLY_PRERELEASE));
522498b56bSopenharmony_cistatic constexpr uint16_t DEFAULT_REMOVE_LOG_TYPES = ((0b01 << LOG_APP) | (0b01 << LOG_CORE)
532498b56bSopenharmony_ci                                                     | (0b01 << LOG_ONLY_PRERELEASE));
542498b56bSopenharmony_cistatic constexpr uint32_t DEFAULT_PERSIST_FILE_NUM = 10;
552498b56bSopenharmony_cistatic constexpr uint32_t DEFAULT_PERSIST_FILE_SIZE = (4 * 1024 * 1024);
562498b56bSopenharmony_cistatic constexpr uint32_t DEFAULT_PERSIST_NORMAL_JOB_ID = 1;
572498b56bSopenharmony_cistatic constexpr uint32_t DEFAULT_PERSIST_KMSG_JOB_ID = 2;
582498b56bSopenharmony_cistatic constexpr int INFO_SUFFIX = 5;
592498b56bSopenharmony_cistatic const uid_t SHELL_UID = 2000;
602498b56bSopenharmony_cistatic const uid_t ROOT_UID = 0;
612498b56bSopenharmony_cistatic const uid_t LOGD_UID = 1036;
622498b56bSopenharmony_cistatic const uid_t HIVIEW_UID = 1201;
632498b56bSopenharmony_cistatic const uid_t PROFILER_UID = 3063;
642498b56bSopenharmony_ci
652498b56bSopenharmony_ciinline bool IsKmsg(uint16_t types)
662498b56bSopenharmony_ci{
672498b56bSopenharmony_ci    return types == (0b01 << LOG_KMSG);
682498b56bSopenharmony_ci}
692498b56bSopenharmony_ci
702498b56bSopenharmony_ciServiceController::ServiceController(std::unique_ptr<Socket> communicationSocket,
712498b56bSopenharmony_ci    LogCollector& collector, HilogBuffer& hilogBuffer, HilogBuffer& kmsgBuffer)
722498b56bSopenharmony_ci    : m_communicationSocket(std::move(communicationSocket)),
732498b56bSopenharmony_ci    m_logCollector(collector),
742498b56bSopenharmony_ci    m_hilogBuffer(hilogBuffer),
752498b56bSopenharmony_ci    m_kmsgBuffer(kmsgBuffer)
762498b56bSopenharmony_ci{
772498b56bSopenharmony_ci    m_hilogBufferReader = m_hilogBuffer.CreateBufReader([this]() { NotifyForNewData(); });
782498b56bSopenharmony_ci    m_kmsgBufferReader = m_kmsgBuffer.CreateBufReader([this]() { NotifyForNewData(); });
792498b56bSopenharmony_ci}
802498b56bSopenharmony_ci
812498b56bSopenharmony_ciServiceController::~ServiceController()
822498b56bSopenharmony_ci{
832498b56bSopenharmony_ci    m_hilogBuffer.RemoveBufReader(m_hilogBufferReader);
842498b56bSopenharmony_ci    m_kmsgBuffer.RemoveBufReader(m_kmsgBufferReader);
852498b56bSopenharmony_ci    m_notifyNewDataCv.notify_all();
862498b56bSopenharmony_ci}
872498b56bSopenharmony_ci
882498b56bSopenharmony_ciinline bool IsValidFileName(const std::string& strFileName)
892498b56bSopenharmony_ci{
902498b56bSopenharmony_ci    // File name shouldn't contain "[\\/:*?\"<>|]"
912498b56bSopenharmony_ci    std::regex regExpress("[\\/:*?\"<>|]");
922498b56bSopenharmony_ci    bool bValid = !std::regex_search(strFileName, regExpress);
932498b56bSopenharmony_ci    return bValid;
942498b56bSopenharmony_ci}
952498b56bSopenharmony_ci
962498b56bSopenharmony_ciint ServiceController::GetMsgHeader(MsgHeader& hdr)
972498b56bSopenharmony_ci{
982498b56bSopenharmony_ci    if (!m_communicationSocket) {
992498b56bSopenharmony_ci        std::cerr << " Invalid socket handler!" << std::endl;
1002498b56bSopenharmony_ci        return RET_FAIL;
1012498b56bSopenharmony_ci    }
1022498b56bSopenharmony_ci    int ret = m_communicationSocket->Read(reinterpret_cast<char *>(&hdr), sizeof(MsgHeader));
1032498b56bSopenharmony_ci    if (ret < static_cast<int>(sizeof(MsgHeader))) {
1042498b56bSopenharmony_ci        std::cerr << "Read MsgHeader error!" << std::endl;
1052498b56bSopenharmony_ci        return RET_FAIL;
1062498b56bSopenharmony_ci    }
1072498b56bSopenharmony_ci    return RET_SUCCESS;
1082498b56bSopenharmony_ci}
1092498b56bSopenharmony_ci
1102498b56bSopenharmony_ciint ServiceController::GetRqst(const MsgHeader& hdr, char* rqst, int expectedLen)
1112498b56bSopenharmony_ci{
1122498b56bSopenharmony_ci    if (hdr.len !=  expectedLen) {
1132498b56bSopenharmony_ci        std::cout << "Invalid MsgHeader! hdr.len:" << hdr.len << ", expectedLen:" << expectedLen << endl;
1142498b56bSopenharmony_ci        return RET_FAIL;
1152498b56bSopenharmony_ci    }
1162498b56bSopenharmony_ci    int ret = m_communicationSocket->Read(rqst, hdr.len);
1172498b56bSopenharmony_ci    if (ret <= 0) {
1182498b56bSopenharmony_ci        std::cout << "Read socket error! " << ret << endl;
1192498b56bSopenharmony_ci        return RET_FAIL;
1202498b56bSopenharmony_ci    }
1212498b56bSopenharmony_ci    return RET_SUCCESS;
1222498b56bSopenharmony_ci}
1232498b56bSopenharmony_ci
1242498b56bSopenharmony_civoid ServiceController::WriteRspHeader(IoctlCmd cmd, size_t len)
1252498b56bSopenharmony_ci{
1262498b56bSopenharmony_ci    MsgHeader header = {MSG_VER, static_cast<uint8_t>(cmd), 0, static_cast<uint16_t>(len)};
1272498b56bSopenharmony_ci    (void)m_communicationSocket->Write(reinterpret_cast<char*>(&header), sizeof(MsgHeader));
1282498b56bSopenharmony_ci    return;
1292498b56bSopenharmony_ci}
1302498b56bSopenharmony_ci
1312498b56bSopenharmony_civoid ServiceController::WriteErrorRsp(int code)
1322498b56bSopenharmony_ci{
1332498b56bSopenharmony_ci    MsgHeader header = {MSG_VER, static_cast<uint8_t>(IoctlCmd::RSP_ERROR), code, 0};
1342498b56bSopenharmony_ci    (void)m_communicationSocket->Write(reinterpret_cast<char*>(&header), sizeof(MsgHeader));
1352498b56bSopenharmony_ci    return;
1362498b56bSopenharmony_ci}
1372498b56bSopenharmony_ci
1382498b56bSopenharmony_ciint ServiceController::WriteQueryResponse(OptCRef<HilogData> pData)
1392498b56bSopenharmony_ci{
1402498b56bSopenharmony_ci    OutputRsp rsp;
1412498b56bSopenharmony_ci    if (pData == std::nullopt) {
1422498b56bSopenharmony_ci        rsp.end = true; // tell client it's the last messsage
1432498b56bSopenharmony_ci        return m_communicationSocket->Write(reinterpret_cast<char*>(&rsp), sizeof(rsp));
1442498b56bSopenharmony_ci    }
1452498b56bSopenharmony_ci    const HilogData& data = pData->get();
1462498b56bSopenharmony_ci    rsp.len = data.len; /* data len, equals tagLen plus content length, include '\0' */
1472498b56bSopenharmony_ci    rsp.level = data.level;
1482498b56bSopenharmony_ci    rsp.type = data.type;
1492498b56bSopenharmony_ci    rsp.tagLen = data.tagLen; /* include '\0' */
1502498b56bSopenharmony_ci    rsp.pid = data.pid;
1512498b56bSopenharmony_ci    rsp.tid = data.tid;
1522498b56bSopenharmony_ci    rsp.domain = data.domain;
1532498b56bSopenharmony_ci    rsp.tv_sec = data.tv_sec;
1542498b56bSopenharmony_ci    rsp.tv_nsec = data.tv_nsec;
1552498b56bSopenharmony_ci    rsp.mono_sec = data.mono_sec;
1562498b56bSopenharmony_ci    rsp.end = false;
1572498b56bSopenharmony_ci    static const int vec_num = 2;
1582498b56bSopenharmony_ci    iovec vec[vec_num];
1592498b56bSopenharmony_ci    vec[0].iov_base = &rsp;
1602498b56bSopenharmony_ci    vec[0].iov_len = sizeof(OutputRsp);
1612498b56bSopenharmony_ci    vec[1].iov_base = data.tag;
1622498b56bSopenharmony_ci    vec[1].iov_len = data.len;
1632498b56bSopenharmony_ci    return m_communicationSocket->WriteV(vec, vec_num);
1642498b56bSopenharmony_ci}
1652498b56bSopenharmony_ci
1662498b56bSopenharmony_cistatic void StatsEntry2StatsRsp(const StatsEntry &entry, StatsRsp &rsp)
1672498b56bSopenharmony_ci{
1682498b56bSopenharmony_ci    // can't use std::copy, because StatsRsp is a packet struct
1692498b56bSopenharmony_ci    int i = 0;
1702498b56bSopenharmony_ci    for (i = 0; i < LevelNum; i++) {
1712498b56bSopenharmony_ci        rsp.lines[i] = entry.lines[i];
1722498b56bSopenharmony_ci        rsp.len[i] = entry.len[i];
1732498b56bSopenharmony_ci    }
1742498b56bSopenharmony_ci    rsp.dropped = entry.dropped;
1752498b56bSopenharmony_ci    rsp.freqMax = entry.GetFreqMax();
1762498b56bSopenharmony_ci    rsp.freqMaxSec = entry.realTimeFreqMax.tv_sec;
1772498b56bSopenharmony_ci    rsp.freqMaxNsec = entry.realTimeFreqMax.tv_nsec;
1782498b56bSopenharmony_ci    rsp.throughputMax = entry.GetThroughputMax();
1792498b56bSopenharmony_ci    rsp.tpMaxSec = entry.realTimeThroughputMax.tv_sec;
1802498b56bSopenharmony_ci    rsp.tpMaxNsec = entry.realTimeThroughputMax.tv_nsec;
1812498b56bSopenharmony_ci}
1822498b56bSopenharmony_ci
1832498b56bSopenharmony_civoid ServiceController::SendOverallStats(const LogStats& stats)
1842498b56bSopenharmony_ci{
1852498b56bSopenharmony_ci    StatsQueryRsp rsp;
1862498b56bSopenharmony_ci    const LogTypeDomainTable& ldTable = stats.GetDomainTable();
1872498b56bSopenharmony_ci    const PidTable& pTable = stats.GetPidTable();
1882498b56bSopenharmony_ci    const LogTimeStamp tsBegin = stats.GetBeginTs();
1892498b56bSopenharmony_ci    rsp.tsBeginSec = tsBegin.tv_sec;
1902498b56bSopenharmony_ci    rsp.tsBeginNsec = tsBegin.tv_nsec;
1912498b56bSopenharmony_ci    const LogTimeStamp monoBegin = stats.GetBeginMono();
1922498b56bSopenharmony_ci    LogTimeStamp monoNow(CLOCK_MONOTONIC);
1932498b56bSopenharmony_ci    monoNow -= monoBegin;
1942498b56bSopenharmony_ci    rsp.durationSec = monoNow.tv_sec;
1952498b56bSopenharmony_ci    rsp.durationNsec = monoNow.tv_nsec;
1962498b56bSopenharmony_ci    stats.GetTotalLines(rsp.totalLines);
1972498b56bSopenharmony_ci    stats.GetTotalLens(rsp.totalLens);
1982498b56bSopenharmony_ci    rsp.typeNum = 0;
1992498b56bSopenharmony_ci    for (const DomainTable &dt : ldTable) {
2002498b56bSopenharmony_ci        if (dt.size() == 0) {
2012498b56bSopenharmony_ci            continue;
2022498b56bSopenharmony_ci        }
2032498b56bSopenharmony_ci        rsp.typeNum++;
2042498b56bSopenharmony_ci    }
2052498b56bSopenharmony_ci    rsp.ldStats = nullptr;
2062498b56bSopenharmony_ci    rsp.procNum = pTable.size();
2072498b56bSopenharmony_ci    rsp.pStats = nullptr;
2082498b56bSopenharmony_ci    m_communicationSocket->Write(reinterpret_cast<char *>(&rsp), sizeof(StatsQueryRsp));
2092498b56bSopenharmony_ci}
2102498b56bSopenharmony_ci
2112498b56bSopenharmony_civoid ServiceController::SendLogTypeDomainStats(const LogStats& stats)
2122498b56bSopenharmony_ci{
2132498b56bSopenharmony_ci    const LogTypeDomainTable& ldTable = stats.GetDomainTable();
2142498b56bSopenharmony_ci    int typeNum = 0;
2152498b56bSopenharmony_ci    for (const DomainTable &dt : ldTable) {
2162498b56bSopenharmony_ci        if (dt.size() == 0) {
2172498b56bSopenharmony_ci            continue;
2182498b56bSopenharmony_ci        }
2192498b56bSopenharmony_ci        typeNum++;
2202498b56bSopenharmony_ci    }
2212498b56bSopenharmony_ci    int msgSize = typeNum * sizeof(LogTypeDomainStatsRsp);
2222498b56bSopenharmony_ci    if (msgSize == 0) {
2232498b56bSopenharmony_ci        return;
2242498b56bSopenharmony_ci    }
2252498b56bSopenharmony_ci    char* tmp = new (std::nothrow) char[msgSize];
2262498b56bSopenharmony_ci    if (tmp == nullptr) {
2272498b56bSopenharmony_ci        return;
2282498b56bSopenharmony_ci    }
2292498b56bSopenharmony_ci    if (memset_s(tmp, msgSize, 0, msgSize) != 0) {
2302498b56bSopenharmony_ci        delete []tmp;
2312498b56bSopenharmony_ci        tmp = nullptr;
2322498b56bSopenharmony_ci        return;
2332498b56bSopenharmony_ci    }
2342498b56bSopenharmony_ci    LogTypeDomainStatsRsp *ldStats = reinterpret_cast<LogTypeDomainStatsRsp *>(tmp);
2352498b56bSopenharmony_ci    int i = 0;
2362498b56bSopenharmony_ci    int j = 0;
2372498b56bSopenharmony_ci    for (const DomainTable &dt : ldTable) {
2382498b56bSopenharmony_ci        j++;
2392498b56bSopenharmony_ci        if (dt.size() == 0) {
2402498b56bSopenharmony_ci            continue;
2412498b56bSopenharmony_ci        }
2422498b56bSopenharmony_ci        ldStats[i].type = (j - 1);
2432498b56bSopenharmony_ci        ldStats[i].domainNum = dt.size();
2442498b56bSopenharmony_ci        i++;
2452498b56bSopenharmony_ci    }
2462498b56bSopenharmony_ci    m_communicationSocket->Write(tmp, msgSize);
2472498b56bSopenharmony_ci    delete []tmp;
2482498b56bSopenharmony_ci    tmp = nullptr;
2492498b56bSopenharmony_ci}
2502498b56bSopenharmony_ci
2512498b56bSopenharmony_civoid ServiceController::SendDomainStats(const LogStats& stats)
2522498b56bSopenharmony_ci{
2532498b56bSopenharmony_ci    const LogTypeDomainTable& ldTable = stats.GetDomainTable();
2542498b56bSopenharmony_ci    for (const DomainTable &dt : ldTable) {
2552498b56bSopenharmony_ci        if (dt.size() == 0) {
2562498b56bSopenharmony_ci            continue;
2572498b56bSopenharmony_ci        }
2582498b56bSopenharmony_ci        int msgSize = dt.size() * sizeof(DomainStatsRsp);
2592498b56bSopenharmony_ci        char *tmp = new (std::nothrow) char[msgSize];
2602498b56bSopenharmony_ci        if (tmp == nullptr) {
2612498b56bSopenharmony_ci            return;
2622498b56bSopenharmony_ci        }
2632498b56bSopenharmony_ci        if (memset_s(tmp, msgSize, 0, msgSize) != 0) {
2642498b56bSopenharmony_ci            delete []tmp;
2652498b56bSopenharmony_ci            tmp = nullptr;
2662498b56bSopenharmony_ci            return;
2672498b56bSopenharmony_ci        }
2682498b56bSopenharmony_ci        DomainStatsRsp *dStats = reinterpret_cast<DomainStatsRsp *>(tmp);
2692498b56bSopenharmony_ci        int i = 0;
2702498b56bSopenharmony_ci        for (auto &it : dt) {
2712498b56bSopenharmony_ci            dStats[i].domain = it.first;
2722498b56bSopenharmony_ci            if (!stats.IsTagEnable()) {
2732498b56bSopenharmony_ci                dStats[i].tagNum = 0;
2742498b56bSopenharmony_ci            } else {
2752498b56bSopenharmony_ci                dStats[i].tagNum = it.second.tagStats.size();
2762498b56bSopenharmony_ci            }
2772498b56bSopenharmony_ci            if (dStats[i].tagNum == 0) {
2782498b56bSopenharmony_ci                dStats[i].tStats = nullptr;
2792498b56bSopenharmony_ci            }
2802498b56bSopenharmony_ci            StatsEntry2StatsRsp(it.second.stats, dStats[i].stats);
2812498b56bSopenharmony_ci            i++;
2822498b56bSopenharmony_ci        }
2832498b56bSopenharmony_ci        m_communicationSocket->Write(tmp, msgSize);
2842498b56bSopenharmony_ci        delete []tmp;
2852498b56bSopenharmony_ci        tmp = nullptr;
2862498b56bSopenharmony_ci    }
2872498b56bSopenharmony_ci}
2882498b56bSopenharmony_ci
2892498b56bSopenharmony_civoid ServiceController::SendDomainTagStats(const LogStats& stats)
2902498b56bSopenharmony_ci{
2912498b56bSopenharmony_ci    const LogTypeDomainTable& ldTable = stats.GetDomainTable();
2922498b56bSopenharmony_ci    for (const DomainTable &dt : ldTable) {
2932498b56bSopenharmony_ci        if (dt.size() == 0) {
2942498b56bSopenharmony_ci            continue;
2952498b56bSopenharmony_ci        }
2962498b56bSopenharmony_ci        for (auto &it : dt) {
2972498b56bSopenharmony_ci            SendTagStats(it.second.tagStats);
2982498b56bSopenharmony_ci        }
2992498b56bSopenharmony_ci    }
3002498b56bSopenharmony_ci}
3012498b56bSopenharmony_ci
3022498b56bSopenharmony_civoid ServiceController::SendProcStats(const LogStats& stats)
3032498b56bSopenharmony_ci{
3042498b56bSopenharmony_ci    const PidTable& pTable = stats.GetPidTable();
3052498b56bSopenharmony_ci    int msgSize =  pTable.size() * sizeof(ProcStatsRsp);
3062498b56bSopenharmony_ci    if (msgSize == 0) {
3072498b56bSopenharmony_ci        return;
3082498b56bSopenharmony_ci    }
3092498b56bSopenharmony_ci    char* tmp = new (std::nothrow) char[msgSize];
3102498b56bSopenharmony_ci    if (tmp == nullptr) {
3112498b56bSopenharmony_ci        return;
3122498b56bSopenharmony_ci    }
3132498b56bSopenharmony_ci    if (memset_s(tmp, msgSize, 0, msgSize) != 0) {
3142498b56bSopenharmony_ci        delete []tmp;
3152498b56bSopenharmony_ci        tmp = nullptr;
3162498b56bSopenharmony_ci        return;
3172498b56bSopenharmony_ci    }
3182498b56bSopenharmony_ci    ProcStatsRsp *pStats = reinterpret_cast<ProcStatsRsp *>(tmp);
3192498b56bSopenharmony_ci    int i = 0;
3202498b56bSopenharmony_ci    for (auto &it : pTable) {
3212498b56bSopenharmony_ci        ProcStatsRsp &procStats = pStats[i];
3222498b56bSopenharmony_ci        i++;
3232498b56bSopenharmony_ci        procStats.pid = it.first;
3242498b56bSopenharmony_ci        if (strncpy_s(procStats.name, MAX_PROC_NAME_LEN, it.second.name.c_str(), MAX_PROC_NAME_LEN - 1) != 0) {
3252498b56bSopenharmony_ci            continue;
3262498b56bSopenharmony_ci        }
3272498b56bSopenharmony_ci        StatsEntry2StatsRsp(it.second.statsAll, procStats.stats);
3282498b56bSopenharmony_ci        procStats.typeNum = 0;
3292498b56bSopenharmony_ci        for (auto &itt : it.second.stats) {
3302498b56bSopenharmony_ci            if (itt.GetTotalLines() == 0) {
3312498b56bSopenharmony_ci                continue;
3322498b56bSopenharmony_ci            }
3332498b56bSopenharmony_ci            procStats.typeNum++;
3342498b56bSopenharmony_ci        }
3352498b56bSopenharmony_ci        if (!stats.IsTagEnable()) {
3362498b56bSopenharmony_ci            procStats.tagNum = 0;
3372498b56bSopenharmony_ci        } else {
3382498b56bSopenharmony_ci            procStats.tagNum = it.second.tagStats.size();
3392498b56bSopenharmony_ci        }
3402498b56bSopenharmony_ci        if (procStats.tagNum == 0) {
3412498b56bSopenharmony_ci            procStats.tStats = nullptr;
3422498b56bSopenharmony_ci        }
3432498b56bSopenharmony_ci    }
3442498b56bSopenharmony_ci    m_communicationSocket->Write(tmp, msgSize);
3452498b56bSopenharmony_ci    delete []tmp;
3462498b56bSopenharmony_ci    tmp = nullptr;
3472498b56bSopenharmony_ci}
3482498b56bSopenharmony_ci
3492498b56bSopenharmony_civoid ServiceController::SendProcLogTypeStats(const LogStats& stats)
3502498b56bSopenharmony_ci{
3512498b56bSopenharmony_ci    const PidTable& pTable = stats.GetPidTable();
3522498b56bSopenharmony_ci    for (auto &it : pTable) {
3532498b56bSopenharmony_ci        int typeNum = 0;
3542498b56bSopenharmony_ci        for (auto &itt : it.second.stats) {
3552498b56bSopenharmony_ci            if (itt.GetTotalLines() == 0) {
3562498b56bSopenharmony_ci                continue;
3572498b56bSopenharmony_ci            }
3582498b56bSopenharmony_ci            typeNum++;
3592498b56bSopenharmony_ci        }
3602498b56bSopenharmony_ci        int msgSize =  typeNum * sizeof(LogTypeStatsRsp);
3612498b56bSopenharmony_ci        if (msgSize == 0) {
3622498b56bSopenharmony_ci            return;
3632498b56bSopenharmony_ci        }
3642498b56bSopenharmony_ci        char* tmp = new (std::nothrow) char[msgSize];
3652498b56bSopenharmony_ci        if (tmp == nullptr) {
3662498b56bSopenharmony_ci            return;
3672498b56bSopenharmony_ci        }
3682498b56bSopenharmony_ci        if (memset_s(tmp, msgSize, 0, msgSize) != 0) {
3692498b56bSopenharmony_ci            delete []tmp;
3702498b56bSopenharmony_ci            tmp = nullptr;
3712498b56bSopenharmony_ci            return;
3722498b56bSopenharmony_ci        }
3732498b56bSopenharmony_ci        LogTypeStatsRsp *lStats = reinterpret_cast<LogTypeStatsRsp *>(tmp);
3742498b56bSopenharmony_ci        int i = 0;
3752498b56bSopenharmony_ci        int j = 0;
3762498b56bSopenharmony_ci        for (auto &itt : it.second.stats) {
3772498b56bSopenharmony_ci            j++;
3782498b56bSopenharmony_ci            if (itt.GetTotalLines() == 0) {
3792498b56bSopenharmony_ci                continue;
3802498b56bSopenharmony_ci            }
3812498b56bSopenharmony_ci            LogTypeStatsRsp &logTypeStats = lStats[i];
3822498b56bSopenharmony_ci            logTypeStats.type = (j - 1);
3832498b56bSopenharmony_ci            StatsEntry2StatsRsp(itt, logTypeStats.stats);
3842498b56bSopenharmony_ci            i++;
3852498b56bSopenharmony_ci        }
3862498b56bSopenharmony_ci        m_communicationSocket->Write(tmp, msgSize);
3872498b56bSopenharmony_ci        delete []tmp;
3882498b56bSopenharmony_ci        tmp = nullptr;
3892498b56bSopenharmony_ci    }
3902498b56bSopenharmony_ci}
3912498b56bSopenharmony_ci
3922498b56bSopenharmony_civoid ServiceController::SendProcTagStats(const LogStats& stats)
3932498b56bSopenharmony_ci{
3942498b56bSopenharmony_ci    const PidTable& pTable = stats.GetPidTable();
3952498b56bSopenharmony_ci    for (auto &it : pTable) {
3962498b56bSopenharmony_ci        SendTagStats(it.second.tagStats);
3972498b56bSopenharmony_ci    }
3982498b56bSopenharmony_ci}
3992498b56bSopenharmony_ci
4002498b56bSopenharmony_civoid ServiceController::SendTagStats(const TagTable &tagTable)
4012498b56bSopenharmony_ci{
4022498b56bSopenharmony_ci    int msgSize =  tagTable.size() * sizeof(TagStatsRsp);
4032498b56bSopenharmony_ci    if (msgSize == 0) {
4042498b56bSopenharmony_ci        return;
4052498b56bSopenharmony_ci    }
4062498b56bSopenharmony_ci    char* tmp = new (std::nothrow) char[msgSize];
4072498b56bSopenharmony_ci    if (tmp == nullptr) {
4082498b56bSopenharmony_ci        return;
4092498b56bSopenharmony_ci    }
4102498b56bSopenharmony_ci    if (memset_s(tmp, msgSize, 0, msgSize) != 0) {
4112498b56bSopenharmony_ci        delete []tmp;
4122498b56bSopenharmony_ci        tmp = nullptr;
4132498b56bSopenharmony_ci        return;
4142498b56bSopenharmony_ci    }
4152498b56bSopenharmony_ci    TagStatsRsp *tStats = reinterpret_cast<TagStatsRsp *>(tmp);
4162498b56bSopenharmony_ci    int i = 0;
4172498b56bSopenharmony_ci    for (auto &itt : tagTable) {
4182498b56bSopenharmony_ci        TagStatsRsp &tagStats = tStats[i];
4192498b56bSopenharmony_ci        if (strncpy_s(tagStats.tag, MAX_TAG_LEN, itt.first.c_str(), MAX_TAG_LEN - 1) != 0) {
4202498b56bSopenharmony_ci            continue;
4212498b56bSopenharmony_ci        }
4222498b56bSopenharmony_ci        i++;
4232498b56bSopenharmony_ci        StatsEntry2StatsRsp(itt.second, tagStats.stats);
4242498b56bSopenharmony_ci    }
4252498b56bSopenharmony_ci    m_communicationSocket->Write(tmp, msgSize);
4262498b56bSopenharmony_ci    delete []tmp;
4272498b56bSopenharmony_ci    tmp = nullptr;
4282498b56bSopenharmony_ci}
4292498b56bSopenharmony_ci
4302498b56bSopenharmony_ciint ServiceController::CheckOutputRqst(const OutputRqst& rqst)
4312498b56bSopenharmony_ci{
4322498b56bSopenharmony_ci    if (((rqst.types & (0b01 << LOG_KMSG)) != 0) && (GetBitsCount(rqst.types) > 1)) {
4332498b56bSopenharmony_ci        return ERR_QUERY_TYPE_INVALID;
4342498b56bSopenharmony_ci    }
4352498b56bSopenharmony_ci    if (rqst.domainCount > MAX_DOMAINS) {
4362498b56bSopenharmony_ci        return ERR_TOO_MANY_DOMAINS;
4372498b56bSopenharmony_ci    }
4382498b56bSopenharmony_ci    if (rqst.tagCount > MAX_TAGS) {
4392498b56bSopenharmony_ci        return ERR_TOO_MANY_TAGS;
4402498b56bSopenharmony_ci    }
4412498b56bSopenharmony_ci    if (rqst.pidCount > MAX_PIDS) {
4422498b56bSopenharmony_ci        return ERR_TOO_MANY_PIDS;
4432498b56bSopenharmony_ci    }
4442498b56bSopenharmony_ci    // Check Uid permission
4452498b56bSopenharmony_ci    uid_t uid = m_communicationSocket->GetUid();
4462498b56bSopenharmony_ci    if (uid != ROOT_UID && uid != SHELL_UID && rqst.pidCount > 0 && uid != HIVIEW_UID && uid != PROFILER_UID) {
4472498b56bSopenharmony_ci        return ERR_NO_PID_PERMISSION;
4482498b56bSopenharmony_ci    }
4492498b56bSopenharmony_ci    return RET_SUCCESS;
4502498b56bSopenharmony_ci}
4512498b56bSopenharmony_ci
4522498b56bSopenharmony_civoid ServiceController::LogFilterFromOutputRqst(const OutputRqst& rqst, LogFilter& filter)
4532498b56bSopenharmony_ci{
4542498b56bSopenharmony_ci    if (rqst.types == 0) {
4552498b56bSopenharmony_ci        filter.types = DEFAULT_LOG_TYPES;
4562498b56bSopenharmony_ci    } else {
4572498b56bSopenharmony_ci        filter.types = rqst.types;
4582498b56bSopenharmony_ci    }
4592498b56bSopenharmony_ci    if (rqst.levels == 0) {
4602498b56bSopenharmony_ci        filter.levels = ~rqst.levels; // 0 means all
4612498b56bSopenharmony_ci    } else {
4622498b56bSopenharmony_ci        filter.levels = rqst.levels;
4632498b56bSopenharmony_ci    }
4642498b56bSopenharmony_ci    int i;
4652498b56bSopenharmony_ci    filter.blackDomain = rqst.blackDomain;
4662498b56bSopenharmony_ci    filter.domainCount = rqst.domainCount;
4672498b56bSopenharmony_ci    for (i = 0; i < rqst.domainCount; i++) {
4682498b56bSopenharmony_ci        filter.domains[i] = rqst.domains[i];
4692498b56bSopenharmony_ci    }
4702498b56bSopenharmony_ci    filter.blackTag = rqst.blackTag;
4712498b56bSopenharmony_ci    filter.tagCount = rqst.tagCount;
4722498b56bSopenharmony_ci    for (i = 0; i < rqst.tagCount; i++) {
4732498b56bSopenharmony_ci        (void)strncpy_s(filter.tags[i], MAX_TAG_LEN, rqst.tags[i], MAX_TAG_LEN - 1);
4742498b56bSopenharmony_ci    }
4752498b56bSopenharmony_ci    filter.blackPid = rqst.blackPid;
4762498b56bSopenharmony_ci    filter.pidCount = rqst.pidCount;
4772498b56bSopenharmony_ci    for (i = 0; i < rqst.pidCount; i++) {
4782498b56bSopenharmony_ci        filter.pids[i] = rqst.pids[i];
4792498b56bSopenharmony_ci    }
4802498b56bSopenharmony_ci    (void)strncpy_s(filter.regex, MAX_REGEX_STR_LEN, rqst.regex, MAX_REGEX_STR_LEN - 1);
4812498b56bSopenharmony_ci    filter.Print();
4822498b56bSopenharmony_ci    // Permission check
4832498b56bSopenharmony_ci    uid_t uid = m_communicationSocket->GetUid();
4842498b56bSopenharmony_ci    uint32_t pid = static_cast<uint32_t>(m_communicationSocket->GetPid());
4852498b56bSopenharmony_ci    if (uid != ROOT_UID && uid != SHELL_UID && uid != LOGD_UID && uid != HIVIEW_UID && uid != PROFILER_UID) {
4862498b56bSopenharmony_ci        filter.blackPid = false;
4872498b56bSopenharmony_ci        filter.pidCount = 1;
4882498b56bSopenharmony_ci        filter.pids[0] = pid;
4892498b56bSopenharmony_ci        uint32_t ppid = GetPPidByPid(pid);
4902498b56bSopenharmony_ci        if (ppid > 0) {
4912498b56bSopenharmony_ci            filter.pidCount++;
4922498b56bSopenharmony_ci            filter.pids[1] = ppid;
4932498b56bSopenharmony_ci        }
4942498b56bSopenharmony_ci    }
4952498b56bSopenharmony_ci}
4962498b56bSopenharmony_ci
4972498b56bSopenharmony_civoid ServiceController::HandleOutputRqst(const OutputRqst &rqst)
4982498b56bSopenharmony_ci{
4992498b56bSopenharmony_ci    // check OutputRqst
5002498b56bSopenharmony_ci    int ret = CheckOutputRqst(rqst);
5012498b56bSopenharmony_ci    if (ret != RET_SUCCESS) {
5022498b56bSopenharmony_ci        WriteErrorRsp(ret);
5032498b56bSopenharmony_ci        return;
5042498b56bSopenharmony_ci    }
5052498b56bSopenharmony_ci    LogFilter filter = {0};
5062498b56bSopenharmony_ci    LogFilterFromOutputRqst(rqst, filter);
5072498b56bSopenharmony_ci    int lines = rqst.headLines ? rqst.headLines : rqst.tailLines;
5082498b56bSopenharmony_ci    int tailCount = rqst.tailLines;
5092498b56bSopenharmony_ci    int linesCountDown = lines;
5102498b56bSopenharmony_ci
5112498b56bSopenharmony_ci    bool isKmsg = IsKmsg(filter.types);
5122498b56bSopenharmony_ci    HilogBuffer& logBuffer = isKmsg ? m_kmsgBuffer : m_hilogBuffer;
5132498b56bSopenharmony_ci    HilogBuffer::ReaderId readId = isKmsg ? m_kmsgBufferReader : m_hilogBufferReader;
5142498b56bSopenharmony_ci
5152498b56bSopenharmony_ci    WriteRspHeader(IoctlCmd::OUTPUT_RSP, sizeof(OutputRsp));
5162498b56bSopenharmony_ci    for (;;) {
5172498b56bSopenharmony_ci        std::optional<HilogData> data = logBuffer.Query(filter, readId, tailCount);
5182498b56bSopenharmony_ci        if (!data.has_value()) {
5192498b56bSopenharmony_ci            if (rqst.noBlock) {
5202498b56bSopenharmony_ci                // reach the end of buffer and don't block
5212498b56bSopenharmony_ci                (void)WriteQueryResponse(std::nullopt);
5222498b56bSopenharmony_ci                break;
5232498b56bSopenharmony_ci            }
5242498b56bSopenharmony_ci            std::unique_lock<decltype(m_notifyNewDataMtx)> ul(m_notifyNewDataMtx);
5252498b56bSopenharmony_ci            m_notifyNewDataCv.wait(ul);
5262498b56bSopenharmony_ci            continue;
5272498b56bSopenharmony_ci        }
5282498b56bSopenharmony_ci        int ret = WriteQueryResponse(data.value());
5292498b56bSopenharmony_ci        if (ret < 0) { // write socket failed, it means that client has disconnected
5302498b56bSopenharmony_ci            std::cerr << "Client disconnect" << std::endl;
5312498b56bSopenharmony_ci            break;
5322498b56bSopenharmony_ci        }
5332498b56bSopenharmony_ci        if (lines && (--linesCountDown) <= 0) {
5342498b56bSopenharmony_ci            (void)WriteQueryResponse(std::nullopt);
5352498b56bSopenharmony_ci            sleep(1); // let client receive all messages and exit gracefully
5362498b56bSopenharmony_ci            break;
5372498b56bSopenharmony_ci        }
5382498b56bSopenharmony_ci    }
5392498b56bSopenharmony_ci}
5402498b56bSopenharmony_ci
5412498b56bSopenharmony_ciint ServiceController::CheckPersistStartRqst(const PersistStartRqst &rqst)
5422498b56bSopenharmony_ci{
5432498b56bSopenharmony_ci    // check OutputFilter
5442498b56bSopenharmony_ci    int ret = CheckOutputRqst(rqst.outputFilter);
5452498b56bSopenharmony_ci    if (ret != RET_SUCCESS) {
5462498b56bSopenharmony_ci        return ret;
5472498b56bSopenharmony_ci    }
5482498b56bSopenharmony_ci    if (rqst.jobId && (rqst.jobId < JOB_ID_MIN || rqst.jobId == JOB_ID_MAX)) {
5492498b56bSopenharmony_ci        return ERR_LOG_PERSIST_JOBID_INVALID;
5502498b56bSopenharmony_ci    }
5512498b56bSopenharmony_ci    if (rqst.fileSize && (rqst.fileSize < MIN_LOG_FILE_SIZE || rqst.fileSize > MAX_LOG_FILE_SIZE)) {
5522498b56bSopenharmony_ci        return ERR_LOG_PERSIST_FILE_SIZE_INVALID;
5532498b56bSopenharmony_ci    }
5542498b56bSopenharmony_ci    if (rqst.fileName[0] && IsValidFileName(rqst.fileName) == false) {
5552498b56bSopenharmony_ci        return ERR_LOG_PERSIST_FILE_NAME_INVALID;
5562498b56bSopenharmony_ci    }
5572498b56bSopenharmony_ci    if (rqst.fileNum && (rqst.fileNum > MAX_LOG_FILE_NUM || rqst.fileNum < MIN_LOG_FILE_NUM)) {
5582498b56bSopenharmony_ci        return ERR_LOG_FILE_NUM_INVALID;
5592498b56bSopenharmony_ci    }
5602498b56bSopenharmony_ci    return RET_SUCCESS;
5612498b56bSopenharmony_ci}
5622498b56bSopenharmony_ci
5632498b56bSopenharmony_civoid ServiceController::PersistStartRqst2Msg(const PersistStartRqst &rqst, LogPersistStartMsg &msg)
5642498b56bSopenharmony_ci{
5652498b56bSopenharmony_ci    LogFilterFromOutputRqst(rqst.outputFilter, msg.filter);
5662498b56bSopenharmony_ci    bool isKmsgType = rqst.outputFilter.types == (0b01 << LOG_KMSG);
5672498b56bSopenharmony_ci    msg.compressAlg = LogCompress::Str2CompressType(rqst.stream);
5682498b56bSopenharmony_ci    msg.fileSize = rqst.fileSize == 0 ? DEFAULT_PERSIST_FILE_SIZE : rqst.fileSize;
5692498b56bSopenharmony_ci    msg.fileNum = rqst.fileNum == 0 ? DEFAULT_PERSIST_FILE_NUM : rqst.fileNum;
5702498b56bSopenharmony_ci    msg.jobId = rqst.jobId;
5712498b56bSopenharmony_ci    if (msg.jobId == 0) {
5722498b56bSopenharmony_ci        msg.jobId = isKmsgType ? DEFAULT_PERSIST_KMSG_JOB_ID : DEFAULT_PERSIST_NORMAL_JOB_ID;
5732498b56bSopenharmony_ci    }
5742498b56bSopenharmony_ci    string fileName = rqst.fileName;
5752498b56bSopenharmony_ci    if (fileName == "") {
5762498b56bSopenharmony_ci        fileName = (isKmsgType ? "hilog_kmsg" : "hilog");
5772498b56bSopenharmony_ci    }
5782498b56bSopenharmony_ci    string filePath = LOG_PERSISTER_DIR + fileName;
5792498b56bSopenharmony_ci    (void)strncpy_s(msg.filePath, FILE_PATH_MAX_LEN, filePath.c_str(), filePath.length());
5802498b56bSopenharmony_ci}
5812498b56bSopenharmony_ci
5822498b56bSopenharmony_ciint StartPersistStoreJob(const PersistRecoveryInfo& info, HilogBuffer& hilogBuffer, bool restore)
5832498b56bSopenharmony_ci{
5842498b56bSopenharmony_ci    std::shared_ptr<LogPersister> persister = LogPersister::CreateLogPersister(hilogBuffer);
5852498b56bSopenharmony_ci    if (persister == nullptr) {
5862498b56bSopenharmony_ci        return RET_FAIL;
5872498b56bSopenharmony_ci    }
5882498b56bSopenharmony_ci    int ret = persister->Init(info, restore);
5892498b56bSopenharmony_ci    if (ret != RET_SUCCESS) {
5902498b56bSopenharmony_ci        return ret;
5912498b56bSopenharmony_ci    }
5922498b56bSopenharmony_ci    persister->Start();
5932498b56bSopenharmony_ci    return RET_SUCCESS;
5942498b56bSopenharmony_ci}
5952498b56bSopenharmony_ci
5962498b56bSopenharmony_civoid ServiceController::HandlePersistStartRqst(const PersistStartRqst &rqst)
5972498b56bSopenharmony_ci{
5982498b56bSopenharmony_ci    int ret = WaitingToDo(WAITING_DATA_MS, HILOG_FILE_DIR, [](const string &path) {
5992498b56bSopenharmony_ci        struct stat s;
6002498b56bSopenharmony_ci        if (stat(path.c_str(), &s) != -1) {
6012498b56bSopenharmony_ci            return RET_SUCCESS;
6022498b56bSopenharmony_ci        }
6032498b56bSopenharmony_ci        return RET_FAIL;
6042498b56bSopenharmony_ci    });
6052498b56bSopenharmony_ci    if (ret != RET_SUCCESS) {
6062498b56bSopenharmony_ci        WriteErrorRsp(ERR_LOG_PERSIST_FILE_PATH_INVALID);
6072498b56bSopenharmony_ci        return;
6082498b56bSopenharmony_ci    }
6092498b56bSopenharmony_ci    ret = CheckPersistStartRqst(rqst);
6102498b56bSopenharmony_ci    if (ret != RET_SUCCESS) {
6112498b56bSopenharmony_ci        WriteErrorRsp(ret);
6122498b56bSopenharmony_ci        return;
6132498b56bSopenharmony_ci    }
6142498b56bSopenharmony_ci    list<LogPersistQueryResult> resultList;
6152498b56bSopenharmony_ci    LogPersister::Query(resultList);
6162498b56bSopenharmony_ci    if (resultList.size() >= MAX_JOBS) {
6172498b56bSopenharmony_ci        WriteErrorRsp(ERR_TOO_MANY_JOBS);
6182498b56bSopenharmony_ci        return;
6192498b56bSopenharmony_ci    }
6202498b56bSopenharmony_ci    LogPersistStartMsg msg = { 0 };
6212498b56bSopenharmony_ci    PersistStartRqst2Msg(rqst, msg);
6222498b56bSopenharmony_ci    PersistRecoveryInfo info = {0, msg};
6232498b56bSopenharmony_ci    HilogBuffer& logBuffer = IsKmsg(rqst.outputFilter.types) ? m_kmsgBuffer : m_hilogBuffer;
6242498b56bSopenharmony_ci    ret = StartPersistStoreJob(info, logBuffer, false);
6252498b56bSopenharmony_ci    if (ret != RET_SUCCESS) {
6262498b56bSopenharmony_ci        WriteErrorRsp(ret);
6272498b56bSopenharmony_ci        return;
6282498b56bSopenharmony_ci    }
6292498b56bSopenharmony_ci    PersistStartRsp rsp = { msg.jobId };
6302498b56bSopenharmony_ci    WriteRspHeader(IoctlCmd::PERSIST_START_RSP, sizeof(rsp));
6312498b56bSopenharmony_ci    (void)m_communicationSocket->Write(reinterpret_cast<char*>(&rsp), sizeof(rsp));
6322498b56bSopenharmony_ci}
6332498b56bSopenharmony_ci
6342498b56bSopenharmony_civoid ServiceController::HandlePersistStopRqst(const PersistStopRqst &rqst)
6352498b56bSopenharmony_ci{
6362498b56bSopenharmony_ci    PersistStopRsp rsp = { 0 };
6372498b56bSopenharmony_ci    list<LogPersistQueryResult> resultList;
6382498b56bSopenharmony_ci    LogPersister::Query(resultList);
6392498b56bSopenharmony_ci    if (rqst.jobId == 0 && resultList.empty()) {
6402498b56bSopenharmony_ci        WriteErrorRsp(ERR_PERSIST_TASK_EMPTY);
6412498b56bSopenharmony_ci        return;
6422498b56bSopenharmony_ci    }
6432498b56bSopenharmony_ci    for (auto it = resultList.begin(); it != resultList.end() && rsp.jobNum < MAX_JOBS; ++it) {
6442498b56bSopenharmony_ci        uint32_t jobId = it->jobId;
6452498b56bSopenharmony_ci        if (rqst.jobId == 0 || rqst.jobId == jobId) {
6462498b56bSopenharmony_ci            (void)LogPersister::Kill(jobId);
6472498b56bSopenharmony_ci            rsp.jobId[rsp.jobNum] = jobId;
6482498b56bSopenharmony_ci            rsp.jobNum++;
6492498b56bSopenharmony_ci        }
6502498b56bSopenharmony_ci    }
6512498b56bSopenharmony_ci    if (rsp.jobNum == 0) {
6522498b56bSopenharmony_ci        WriteErrorRsp(ERR_JOBID_NOT_EXSIST);
6532498b56bSopenharmony_ci        return;
6542498b56bSopenharmony_ci    }
6552498b56bSopenharmony_ci    WriteRspHeader(IoctlCmd::PERSIST_STOP_RSP, sizeof(rsp));
6562498b56bSopenharmony_ci    (void)m_communicationSocket->Write(reinterpret_cast<char*>(&rsp), sizeof(rsp));
6572498b56bSopenharmony_ci}
6582498b56bSopenharmony_ci
6592498b56bSopenharmony_civoid ServiceController::HandlePersistQueryRqst(const PersistQueryRqst& rqst)
6602498b56bSopenharmony_ci{
6612498b56bSopenharmony_ci    list<LogPersistQueryResult> resultList;
6622498b56bSopenharmony_ci    LogPersister::Query(resultList);
6632498b56bSopenharmony_ci    if (resultList.size() == 0) {
6642498b56bSopenharmony_ci        WriteErrorRsp(ERR_NO_RUNNING_TASK);
6652498b56bSopenharmony_ci        return;
6662498b56bSopenharmony_ci    }
6672498b56bSopenharmony_ci    PersistQueryRsp rsp = { 0 };
6682498b56bSopenharmony_ci    for (auto it = resultList.begin(); it != resultList.end() && rsp.jobNum < MAX_JOBS; ++it) {
6692498b56bSopenharmony_ci        PersistTaskInfo &task = rsp.taskInfo[rsp.jobNum];
6702498b56bSopenharmony_ci        task.jobId = it->jobId;
6712498b56bSopenharmony_ci        task.fileNum = it->fileNum;
6722498b56bSopenharmony_ci        task.fileSize = it->fileSize;
6732498b56bSopenharmony_ci        task.outputFilter.types = it->logType;
6742498b56bSopenharmony_ci        (void)strncpy_s(task.fileName, MAX_FILE_NAME_LEN, it->filePath, MAX_FILE_NAME_LEN - 1);
6752498b56bSopenharmony_ci        (void)strncpy_s(task.stream, MAX_STREAM_NAME_LEN,
6762498b56bSopenharmony_ci                        LogCompress::CompressType2Str(it->compressAlg).c_str(), MAX_STREAM_NAME_LEN - 1);
6772498b56bSopenharmony_ci        rsp.jobNum++;
6782498b56bSopenharmony_ci    }
6792498b56bSopenharmony_ci    WriteRspHeader(IoctlCmd::PERSIST_QUERY_RSP, sizeof(rsp));
6802498b56bSopenharmony_ci    (void)m_communicationSocket->Write(reinterpret_cast<char*>(&rsp), sizeof(rsp));
6812498b56bSopenharmony_ci}
6822498b56bSopenharmony_ci
6832498b56bSopenharmony_civoid ServiceController::HandlePersistRefreshRqst(const PersistRefreshRqst& rqst)
6842498b56bSopenharmony_ci{
6852498b56bSopenharmony_ci    PersistRefreshRsp rsp = { 0 };
6862498b56bSopenharmony_ci    list<LogPersistQueryResult> resultList;
6872498b56bSopenharmony_ci    LogPersister::Query(resultList);
6882498b56bSopenharmony_ci    if (rqst.jobId == 0 && resultList.empty()) {
6892498b56bSopenharmony_ci        WriteErrorRsp(ERR_PERSIST_TASK_EMPTY);
6902498b56bSopenharmony_ci        return;
6912498b56bSopenharmony_ci    }
6922498b56bSopenharmony_ci    for (auto it = resultList.begin(); it != resultList.end() && rsp.jobNum < MAX_JOBS; ++it) {
6932498b56bSopenharmony_ci        uint32_t jobId = it->jobId;
6942498b56bSopenharmony_ci        if (rqst.jobId == 0 || rqst.jobId == jobId) {
6952498b56bSopenharmony_ci            (void)LogPersister::Refresh(jobId);
6962498b56bSopenharmony_ci            rsp.jobId[rsp.jobNum] = jobId;
6972498b56bSopenharmony_ci            rsp.jobNum++;
6982498b56bSopenharmony_ci        }
6992498b56bSopenharmony_ci    }
7002498b56bSopenharmony_ci    if (rsp.jobNum == 0) {
7012498b56bSopenharmony_ci        WriteErrorRsp(ERR_JOBID_NOT_EXSIST);
7022498b56bSopenharmony_ci        return;
7032498b56bSopenharmony_ci    }
7042498b56bSopenharmony_ci    WriteRspHeader(IoctlCmd::PERSIST_REFRESH_RSP, sizeof(rsp));
7052498b56bSopenharmony_ci    (void)m_communicationSocket->Write(reinterpret_cast<char*>(&rsp), sizeof(rsp));
7062498b56bSopenharmony_ci}
7072498b56bSopenharmony_ci
7082498b56bSopenharmony_civoid ServiceController::HandlePersistClearRqst()
7092498b56bSopenharmony_ci{
7102498b56bSopenharmony_ci    LogPersister::Clear();
7112498b56bSopenharmony_ci    PersistClearRsp rsp = { 0 };
7122498b56bSopenharmony_ci    WriteRspHeader(IoctlCmd::PERSIST_CLEAR_RSP, sizeof(rsp));
7132498b56bSopenharmony_ci    (void)m_communicationSocket->Write(reinterpret_cast<char*>(&rsp), sizeof(rsp));
7142498b56bSopenharmony_ci}
7152498b56bSopenharmony_ci
7162498b56bSopenharmony_civoid ServiceController::HandleBufferSizeGetRqst(const BufferSizeGetRqst& rqst)
7172498b56bSopenharmony_ci{
7182498b56bSopenharmony_ci    vector<uint16_t> allTypes = GetAllLogTypes();
7192498b56bSopenharmony_ci    uint16_t types = rqst.types;
7202498b56bSopenharmony_ci    if (types == 0) {
7212498b56bSopenharmony_ci        types = DEFAULT_LOG_TYPES;
7222498b56bSopenharmony_ci    }
7232498b56bSopenharmony_ci    int i = 0;
7242498b56bSopenharmony_ci    BufferSizeGetRsp rsp = { 0 };
7252498b56bSopenharmony_ci    for (uint16_t t : allTypes) {
7262498b56bSopenharmony_ci        if ((1 << t) & types) {
7272498b56bSopenharmony_ci            HilogBuffer& hilogBuffer = t == LOG_KMSG ? m_kmsgBuffer : m_hilogBuffer;
7282498b56bSopenharmony_ci            rsp.size[t] = static_cast<uint32_t>(hilogBuffer.GetBuffLen(t));
7292498b56bSopenharmony_ci            i++;
7302498b56bSopenharmony_ci        }
7312498b56bSopenharmony_ci    }
7322498b56bSopenharmony_ci    if (i == 0) {
7332498b56bSopenharmony_ci        WriteErrorRsp(ERR_LOG_TYPE_INVALID);
7342498b56bSopenharmony_ci        return;
7352498b56bSopenharmony_ci    }
7362498b56bSopenharmony_ci    WriteRspHeader(IoctlCmd::BUFFERSIZE_GET_RSP, sizeof(rsp));
7372498b56bSopenharmony_ci    (void)m_communicationSocket->Write(reinterpret_cast<char*>(&rsp), sizeof(rsp));
7382498b56bSopenharmony_ci}
7392498b56bSopenharmony_ci
7402498b56bSopenharmony_civoid ServiceController::HandleBufferSizeSetRqst(const BufferSizeSetRqst& rqst)
7412498b56bSopenharmony_ci{
7422498b56bSopenharmony_ci    vector<uint16_t> allTypes = GetAllLogTypes();
7432498b56bSopenharmony_ci    uint16_t types = rqst.types;
7442498b56bSopenharmony_ci    if (types == 0) {
7452498b56bSopenharmony_ci        types = DEFAULT_LOG_TYPES;
7462498b56bSopenharmony_ci    }
7472498b56bSopenharmony_ci    int i = 0;
7482498b56bSopenharmony_ci    BufferSizeSetRsp rsp = { 0 };
7492498b56bSopenharmony_ci    for (uint16_t t : allTypes) {
7502498b56bSopenharmony_ci        if ((1 << t) & types) {
7512498b56bSopenharmony_ci            HilogBuffer& hilogBuffer = t == LOG_KMSG ? m_kmsgBuffer : m_hilogBuffer;
7522498b56bSopenharmony_ci            int ret = hilogBuffer.SetBuffLen(t, rqst.size);
7532498b56bSopenharmony_ci            if (ret != RET_SUCCESS) {
7542498b56bSopenharmony_ci                rsp.size[t] = ret;
7552498b56bSopenharmony_ci            } else {
7562498b56bSopenharmony_ci                SetBufferSize(t, true, rqst.size);
7572498b56bSopenharmony_ci                rsp.size[t] = rqst.size;
7582498b56bSopenharmony_ci            }
7592498b56bSopenharmony_ci            i++;
7602498b56bSopenharmony_ci        }
7612498b56bSopenharmony_ci    }
7622498b56bSopenharmony_ci    if (i == 0) {
7632498b56bSopenharmony_ci        WriteErrorRsp(ERR_LOG_TYPE_INVALID);
7642498b56bSopenharmony_ci        return;
7652498b56bSopenharmony_ci    }
7662498b56bSopenharmony_ci    WriteRspHeader(IoctlCmd::BUFFERSIZE_SET_RSP, sizeof(rsp));
7672498b56bSopenharmony_ci    (void)m_communicationSocket->Write(reinterpret_cast<char*>(&rsp), sizeof(rsp));
7682498b56bSopenharmony_ci}
7692498b56bSopenharmony_ci
7702498b56bSopenharmony_civoid ServiceController::HandleStatsQueryRqst(const StatsQueryRqst& rqst)
7712498b56bSopenharmony_ci{
7722498b56bSopenharmony_ci    LogStats& stats = m_hilogBuffer.GetStatsInfo();
7732498b56bSopenharmony_ci    if (!stats.IsEnable()) {
7742498b56bSopenharmony_ci        WriteErrorRsp(ERR_STATS_NOT_ENABLE);
7752498b56bSopenharmony_ci        return;
7762498b56bSopenharmony_ci    }
7772498b56bSopenharmony_ci    std::unique_lock<std::mutex> lk(stats.GetLock());
7782498b56bSopenharmony_ci
7792498b56bSopenharmony_ci    WriteRspHeader(IoctlCmd::STATS_QUERY_RSP, sizeof(StatsQueryRsp));
7802498b56bSopenharmony_ci    SendOverallStats(stats);
7812498b56bSopenharmony_ci    SendLogTypeDomainStats(stats);
7822498b56bSopenharmony_ci    SendDomainStats(stats);
7832498b56bSopenharmony_ci    if (stats.IsTagEnable()) {
7842498b56bSopenharmony_ci        SendDomainTagStats(stats);
7852498b56bSopenharmony_ci    }
7862498b56bSopenharmony_ci    SendProcStats(stats);
7872498b56bSopenharmony_ci    SendProcLogTypeStats(stats);
7882498b56bSopenharmony_ci    if (stats.IsTagEnable()) {
7892498b56bSopenharmony_ci        SendProcTagStats(stats);
7902498b56bSopenharmony_ci    }
7912498b56bSopenharmony_ci}
7922498b56bSopenharmony_ci
7932498b56bSopenharmony_civoid ServiceController::HandleStatsClearRqst(const StatsClearRqst& rqst)
7942498b56bSopenharmony_ci{
7952498b56bSopenharmony_ci    m_hilogBuffer.ResetStats();
7962498b56bSopenharmony_ci    StatsClearRsp rsp = { 0 };
7972498b56bSopenharmony_ci    WriteRspHeader(IoctlCmd::STATS_CLEAR_RSP, sizeof(rsp));
7982498b56bSopenharmony_ci    (void)m_communicationSocket->Write(reinterpret_cast<char*>(&rsp), sizeof(rsp));
7992498b56bSopenharmony_ci}
8002498b56bSopenharmony_ci
8012498b56bSopenharmony_civoid ServiceController::HandleDomainFlowCtrlRqst(const DomainFlowCtrlRqst& rqst)
8022498b56bSopenharmony_ci{
8032498b56bSopenharmony_ci    SetDomainSwitchOn(rqst.on);
8042498b56bSopenharmony_ci    m_logCollector.SetLogFlowControl(rqst.on);
8052498b56bSopenharmony_ci    // set domain flow control later
8062498b56bSopenharmony_ci    DomainFlowCtrlRsp rsp = { 0 };
8072498b56bSopenharmony_ci    WriteRspHeader(IoctlCmd::DOMAIN_FLOWCTRL_RSP, sizeof(rsp));
8082498b56bSopenharmony_ci    (void)m_communicationSocket->Write(reinterpret_cast<char*>(&rsp), sizeof(rsp));
8092498b56bSopenharmony_ci}
8102498b56bSopenharmony_ci
8112498b56bSopenharmony_civoid ServiceController::HandleLogRemoveRqst(const LogRemoveRqst& rqst)
8122498b56bSopenharmony_ci{
8132498b56bSopenharmony_ci    vector<uint16_t> allTypes = GetAllLogTypes();
8142498b56bSopenharmony_ci    uint16_t types = rqst.types;
8152498b56bSopenharmony_ci    if (types == 0) {
8162498b56bSopenharmony_ci        types = DEFAULT_REMOVE_LOG_TYPES;
8172498b56bSopenharmony_ci    }
8182498b56bSopenharmony_ci    int i = 0;
8192498b56bSopenharmony_ci    LogRemoveRsp rsp = { types };
8202498b56bSopenharmony_ci    for (uint16_t t : allTypes) {
8212498b56bSopenharmony_ci        if ((1 << t) & types) {
8222498b56bSopenharmony_ci            HilogBuffer& hilogBuffer = (t == LOG_KMSG) ? m_kmsgBuffer : m_hilogBuffer;
8232498b56bSopenharmony_ci            (void)hilogBuffer.Delete(t);
8242498b56bSopenharmony_ci            i++;
8252498b56bSopenharmony_ci        }
8262498b56bSopenharmony_ci    }
8272498b56bSopenharmony_ci    if (i == 0) {
8282498b56bSopenharmony_ci        WriteErrorRsp(ERR_LOG_TYPE_INVALID);
8292498b56bSopenharmony_ci        return;
8302498b56bSopenharmony_ci    }
8312498b56bSopenharmony_ci    WriteRspHeader(IoctlCmd::LOG_REMOVE_RSP, sizeof(rsp));
8322498b56bSopenharmony_ci    (void)m_communicationSocket->Write(reinterpret_cast<char*>(&rsp), sizeof(rsp));
8332498b56bSopenharmony_ci}
8342498b56bSopenharmony_ci
8352498b56bSopenharmony_civoid ServiceController::HandleLogKmsgEnableRqst(const KmsgEnableRqst& rqst)
8362498b56bSopenharmony_ci{
8372498b56bSopenharmony_ci    SetKmsgSwitchOn(rqst.on);
8382498b56bSopenharmony_ci
8392498b56bSopenharmony_ci    LogKmsg& logKmsg = LogKmsg::GetInstance(m_kmsgBuffer);
8402498b56bSopenharmony_ci    if (rqst.on) {
8412498b56bSopenharmony_ci        logKmsg.Start();
8422498b56bSopenharmony_ci    } else {
8432498b56bSopenharmony_ci        logKmsg.Stop();
8442498b56bSopenharmony_ci    }
8452498b56bSopenharmony_ci    // set domain flow control later
8462498b56bSopenharmony_ci    KmsgEnableRsp rsp = { 0 };
8472498b56bSopenharmony_ci    WriteRspHeader(IoctlCmd::KMSG_ENABLE_RSP, sizeof(rsp));
8482498b56bSopenharmony_ci    (void)m_communicationSocket->Write(reinterpret_cast<char*>(&rsp), sizeof(rsp));
8492498b56bSopenharmony_ci}
8502498b56bSopenharmony_ci
8512498b56bSopenharmony_cibool ServiceController::IsValidCmd(const CmdList& list, IoctlCmd cmd)
8522498b56bSopenharmony_ci{
8532498b56bSopenharmony_ci    auto it = find(list.begin(), list.end(), cmd);
8542498b56bSopenharmony_ci    return (it != list.end());
8552498b56bSopenharmony_ci}
8562498b56bSopenharmony_ci
8572498b56bSopenharmony_civoid ServiceController::CommunicationLoop(std::atomic<bool>& stopLoop, const CmdList& list)
8582498b56bSopenharmony_ci{
8592498b56bSopenharmony_ci    std::cout << "ServiceController Loop Begin" << std::endl;
8602498b56bSopenharmony_ci    MsgHeader hdr;
8612498b56bSopenharmony_ci    int ret = GetMsgHeader(hdr);
8622498b56bSopenharmony_ci    if (ret != RET_SUCCESS) {
8632498b56bSopenharmony_ci        return;
8642498b56bSopenharmony_ci    }
8652498b56bSopenharmony_ci    IoctlCmd cmd = static_cast<IoctlCmd>(hdr.cmd);
8662498b56bSopenharmony_ci    std::cout << "Receive cmd: " << static_cast<int>(cmd) << endl;
8672498b56bSopenharmony_ci    if (!IsValidCmd(list, cmd)) {
8682498b56bSopenharmony_ci        cout << "Not valid cmd for this executor" << endl;
8692498b56bSopenharmony_ci        WriteErrorRsp(ERR_INVALID_RQST_CMD);
8702498b56bSopenharmony_ci        return;
8712498b56bSopenharmony_ci    }
8722498b56bSopenharmony_ci    switch (cmd) {
8732498b56bSopenharmony_ci        case IoctlCmd::OUTPUT_RQST: {
8742498b56bSopenharmony_ci            RequestHandler<OutputRqst>(hdr, [this](const OutputRqst& rqst) {
8752498b56bSopenharmony_ci                HandleOutputRqst(rqst);
8762498b56bSopenharmony_ci            });
8772498b56bSopenharmony_ci            break;
8782498b56bSopenharmony_ci        }
8792498b56bSopenharmony_ci        case IoctlCmd::PERSIST_START_RQST: {
8802498b56bSopenharmony_ci            RequestHandler<PersistStartRqst>(hdr, [this](const PersistStartRqst& rqst) {
8812498b56bSopenharmony_ci                HandlePersistStartRqst(rqst);
8822498b56bSopenharmony_ci            });
8832498b56bSopenharmony_ci            break;
8842498b56bSopenharmony_ci        }
8852498b56bSopenharmony_ci        case IoctlCmd::PERSIST_STOP_RQST: {
8862498b56bSopenharmony_ci            RequestHandler<PersistStopRqst>(hdr, [this](const PersistStopRqst& rqst) {
8872498b56bSopenharmony_ci                HandlePersistStopRqst(rqst);
8882498b56bSopenharmony_ci            });
8892498b56bSopenharmony_ci            break;
8902498b56bSopenharmony_ci        }
8912498b56bSopenharmony_ci        case IoctlCmd::PERSIST_QUERY_RQST: {
8922498b56bSopenharmony_ci            RequestHandler<PersistQueryRqst>(hdr, [this](const PersistQueryRqst& rqst) {
8932498b56bSopenharmony_ci                HandlePersistQueryRqst(rqst);
8942498b56bSopenharmony_ci            });
8952498b56bSopenharmony_ci            break;
8962498b56bSopenharmony_ci        }
8972498b56bSopenharmony_ci        case IoctlCmd::BUFFERSIZE_GET_RQST: {
8982498b56bSopenharmony_ci            RequestHandler<BufferSizeGetRqst>(hdr, [this](const BufferSizeGetRqst& rqst) {
8992498b56bSopenharmony_ci                HandleBufferSizeGetRqst(rqst);
9002498b56bSopenharmony_ci            });
9012498b56bSopenharmony_ci            break;
9022498b56bSopenharmony_ci        }
9032498b56bSopenharmony_ci        case IoctlCmd::BUFFERSIZE_SET_RQST: {
9042498b56bSopenharmony_ci            RequestHandler<BufferSizeSetRqst>(hdr, [this](const BufferSizeSetRqst& rqst) {
9052498b56bSopenharmony_ci                HandleBufferSizeSetRqst(rqst);
9062498b56bSopenharmony_ci            });
9072498b56bSopenharmony_ci            break;
9082498b56bSopenharmony_ci        }
9092498b56bSopenharmony_ci        case IoctlCmd::STATS_QUERY_RQST: {
9102498b56bSopenharmony_ci            RequestHandler<StatsQueryRqst>(hdr, [this](const StatsQueryRqst& rqst) {
9112498b56bSopenharmony_ci                HandleStatsQueryRqst(rqst);
9122498b56bSopenharmony_ci            });
9132498b56bSopenharmony_ci            break;
9142498b56bSopenharmony_ci        }
9152498b56bSopenharmony_ci        case IoctlCmd::PERSIST_REFRESH_RQST: {
9162498b56bSopenharmony_ci            RequestHandler<PersistRefreshRqst>(hdr, [this](const PersistRefreshRqst& rqst) {
9172498b56bSopenharmony_ci                HandlePersistRefreshRqst(rqst);
9182498b56bSopenharmony_ci            });
9192498b56bSopenharmony_ci            break;
9202498b56bSopenharmony_ci        }
9212498b56bSopenharmony_ci        case IoctlCmd::PERSIST_CLEAR_RQST: {
9222498b56bSopenharmony_ci            RequestHandler<PersistClearRqst>(hdr, [this](const PersistClearRqst& rqst) {
9232498b56bSopenharmony_ci                HandlePersistClearRqst();
9242498b56bSopenharmony_ci            });
9252498b56bSopenharmony_ci            break;
9262498b56bSopenharmony_ci        }
9272498b56bSopenharmony_ci        case IoctlCmd::STATS_CLEAR_RQST: {
9282498b56bSopenharmony_ci            RequestHandler<StatsClearRqst>(hdr, [this](const StatsClearRqst& rqst) {
9292498b56bSopenharmony_ci                HandleStatsClearRqst(rqst);
9302498b56bSopenharmony_ci            });
9312498b56bSopenharmony_ci            break;
9322498b56bSopenharmony_ci        }
9332498b56bSopenharmony_ci        case IoctlCmd::DOMAIN_FLOWCTRL_RQST: {
9342498b56bSopenharmony_ci            RequestHandler<DomainFlowCtrlRqst>(hdr, [this](const DomainFlowCtrlRqst& rqst) {
9352498b56bSopenharmony_ci                HandleDomainFlowCtrlRqst(rqst);
9362498b56bSopenharmony_ci            });
9372498b56bSopenharmony_ci            break;
9382498b56bSopenharmony_ci        }
9392498b56bSopenharmony_ci        case IoctlCmd::LOG_REMOVE_RQST: {
9402498b56bSopenharmony_ci            RequestHandler<LogRemoveRqst>(hdr, [this](const LogRemoveRqst& rqst) {
9412498b56bSopenharmony_ci                HandleLogRemoveRqst(rqst);
9422498b56bSopenharmony_ci            });
9432498b56bSopenharmony_ci            break;
9442498b56bSopenharmony_ci        }
9452498b56bSopenharmony_ci        case IoctlCmd::KMSG_ENABLE_RQST: {
9462498b56bSopenharmony_ci            RequestHandler<KmsgEnableRqst>(hdr, [this](const KmsgEnableRqst& rqst) {
9472498b56bSopenharmony_ci                HandleLogKmsgEnableRqst(rqst);
9482498b56bSopenharmony_ci            });
9492498b56bSopenharmony_ci            break;
9502498b56bSopenharmony_ci        }
9512498b56bSopenharmony_ci        default: {
9522498b56bSopenharmony_ci            std::cerr << " Unknown message. Skipped!" << endl;
9532498b56bSopenharmony_ci            break;
9542498b56bSopenharmony_ci        }
9552498b56bSopenharmony_ci    }
9562498b56bSopenharmony_ci    stopLoop.store(true);
9572498b56bSopenharmony_ci    std::cout << " ServiceController Loop End" << endl;
9582498b56bSopenharmony_ci}
9592498b56bSopenharmony_ci
9602498b56bSopenharmony_civoid ServiceController::NotifyForNewData()
9612498b56bSopenharmony_ci{
9622498b56bSopenharmony_ci    m_notifyNewDataCv.notify_one();
9632498b56bSopenharmony_ci}
9642498b56bSopenharmony_ci
9652498b56bSopenharmony_ciint RestorePersistJobs(HilogBuffer& hilogBuffer, HilogBuffer& kmsgBuffer)
9662498b56bSopenharmony_ci{
9672498b56bSopenharmony_ci    std::cout << " Start restoring persist jobs!\n";
9682498b56bSopenharmony_ci    DIR *dir = opendir(LOG_PERSISTER_DIR.c_str());
9692498b56bSopenharmony_ci    struct dirent *ent = nullptr;
9702498b56bSopenharmony_ci    if (dir == nullptr) {
9712498b56bSopenharmony_ci        perror("Failed to open persister directory!");
9722498b56bSopenharmony_ci        return ERR_LOG_PERSIST_DIR_OPEN_FAIL;
9732498b56bSopenharmony_ci    }
9742498b56bSopenharmony_ci    while ((ent = readdir(dir)) != nullptr) {
9752498b56bSopenharmony_ci        size_t length = strlen(ent->d_name);
9762498b56bSopenharmony_ci        std::string pPath(ent->d_name, length);
9772498b56bSopenharmony_ci        if (length >= INFO_SUFFIX && pPath.substr(length - INFO_SUFFIX, length) == ".info") {
9782498b56bSopenharmony_ci            if (pPath == "hilog.info") {
9792498b56bSopenharmony_ci                continue;
9802498b56bSopenharmony_ci            }
9812498b56bSopenharmony_ci            std::cout << " Found a persist job! Path: " << LOG_PERSISTER_DIR + pPath << "\n";
9822498b56bSopenharmony_ci            FILE* infile = fopen((LOG_PERSISTER_DIR + pPath).c_str(), "r");
9832498b56bSopenharmony_ci            if (infile == nullptr) {
9842498b56bSopenharmony_ci                std::cerr << " Error opening recovery info file!\n";
9852498b56bSopenharmony_ci                continue;
9862498b56bSopenharmony_ci            }
9872498b56bSopenharmony_ci            PersistRecoveryInfo info = { 0 };
9882498b56bSopenharmony_ci            fread(&info, sizeof(PersistRecoveryInfo), 1, infile);
9892498b56bSopenharmony_ci            uint64_t hashSum = 0L;
9902498b56bSopenharmony_ci            fread(&hashSum, sizeof(hashSum), 1, infile);
9912498b56bSopenharmony_ci            fclose(infile);
9922498b56bSopenharmony_ci            uint64_t hash = GenerateHash(reinterpret_cast<char *>(&info), sizeof(PersistRecoveryInfo));
9932498b56bSopenharmony_ci            if (hash != hashSum) {
9942498b56bSopenharmony_ci                std::cout << " Info file checksum Failed!\n";
9952498b56bSopenharmony_ci                continue;
9962498b56bSopenharmony_ci            }
9972498b56bSopenharmony_ci            HilogBuffer& logBuffer = IsKmsg(info.msg.filter.types) ? kmsgBuffer : hilogBuffer;
9982498b56bSopenharmony_ci            int result = StartPersistStoreJob(info, logBuffer, true);
9992498b56bSopenharmony_ci            std::cout << " Recovery Info:\n"
10002498b56bSopenharmony_ci                << "  restoring result: " << (result == RET_SUCCESS
10012498b56bSopenharmony_ci                    ? std::string("Success\n")
10022498b56bSopenharmony_ci                    : std::string("Failed(") + std::to_string(result) + ")\n")
10032498b56bSopenharmony_ci                << "  jobId=" << (unsigned)(info.msg.jobId) << "\n"
10042498b56bSopenharmony_ci                << "  filePath=" << (info.msg.filePath) << "\n"
10052498b56bSopenharmony_ci                << "  index=" << (info.index) << "\n";
10062498b56bSopenharmony_ci        }
10072498b56bSopenharmony_ci    }
10082498b56bSopenharmony_ci    closedir(dir);
10092498b56bSopenharmony_ci    std::cout << " Finished restoring persist jobs!\n";
10102498b56bSopenharmony_ci    return EXIT_SUCCESS;
10112498b56bSopenharmony_ci}
10122498b56bSopenharmony_ci} // namespace HiviewDFX
10132498b56bSopenharmony_ci} // namespace OHOS
1014