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
162498b56bSopenharmony_ci#include <iostream>
172498b56bSopenharmony_ci#include <sys/stat.h>
182498b56bSopenharmony_ci#include <sys/prctl.h>
192498b56bSopenharmony_ci#include <sys/stat.h>
202498b56bSopenharmony_ci#include <future>
212498b56bSopenharmony_ci#include <unistd.h>
222498b56bSopenharmony_ci#include <csignal>
232498b56bSopenharmony_ci#include <fcntl.h>
242498b56bSopenharmony_ci#include <hilog_input_socket_server.h>
252498b56bSopenharmony_ci#include <properties.h>
262498b56bSopenharmony_ci#include <log_utils.h>
272498b56bSopenharmony_ci
282498b56bSopenharmony_ci#include "cmd_executor.h"
292498b56bSopenharmony_ci#include "ffrt.h"
302498b56bSopenharmony_ci#include "flow_control.h"
312498b56bSopenharmony_ci#include "log_kmsg.h"
322498b56bSopenharmony_ci#include "log_collector.h"
332498b56bSopenharmony_ci#include "service_controller.h"
342498b56bSopenharmony_ci
352498b56bSopenharmony_ci#ifdef DEBUG
362498b56bSopenharmony_ci#include <cstdio>
372498b56bSopenharmony_ci#include <cerrno>
382498b56bSopenharmony_ci#endif
392498b56bSopenharmony_ci
402498b56bSopenharmony_cinamespace OHOS {
412498b56bSopenharmony_cinamespace HiviewDFX {
422498b56bSopenharmony_ciusing namespace std;
432498b56bSopenharmony_ci
442498b56bSopenharmony_cistatic const string SYSTEM_BG_STUNE = "/dev/stune/system-background/cgroup.procs";
452498b56bSopenharmony_cistatic const string SYSTEM_BG_CPUSET = "/dev/cpuset/system-background/cgroup.procs";
462498b56bSopenharmony_cistatic const string SYSTEM_BG_BLKIO  = "/dev/blkio/system-background/cgroup.procs";
472498b56bSopenharmony_ci
482498b56bSopenharmony_ci#ifdef DEBUG
492498b56bSopenharmony_cistatic int g_fd = -1;
502498b56bSopenharmony_ci#endif
512498b56bSopenharmony_ci
522498b56bSopenharmony_cistatic void SigHandler(int sig)
532498b56bSopenharmony_ci{
542498b56bSopenharmony_ci    if (sig == SIGINT) {
552498b56bSopenharmony_ci#ifdef DEBUG
562498b56bSopenharmony_ci        if (g_fd > 0) {
572498b56bSopenharmony_ci            close(g_fd);
582498b56bSopenharmony_ci            g_fd = -1;
592498b56bSopenharmony_ci        }
602498b56bSopenharmony_ci#endif
612498b56bSopenharmony_ci    }
622498b56bSopenharmony_ci}
632498b56bSopenharmony_ci
642498b56bSopenharmony_cistatic bool WriteStringToFile(int fd, const std::string& content)
652498b56bSopenharmony_ci{
662498b56bSopenharmony_ci    const char *p = content.data();
672498b56bSopenharmony_ci    size_t remaining = content.size();
682498b56bSopenharmony_ci    while (remaining > 0) {
692498b56bSopenharmony_ci        ssize_t n = write(fd, p, remaining);
702498b56bSopenharmony_ci        if (n == -1) {
712498b56bSopenharmony_ci            return false;
722498b56bSopenharmony_ci        }
732498b56bSopenharmony_ci        p += n;
742498b56bSopenharmony_ci        remaining -= static_cast<size_t>(n);
752498b56bSopenharmony_ci    }
762498b56bSopenharmony_ci    return true;
772498b56bSopenharmony_ci}
782498b56bSopenharmony_ci
792498b56bSopenharmony_cistatic bool WriteStringToFile(const std::string& content, const std::string& filePath)
802498b56bSopenharmony_ci{
812498b56bSopenharmony_ci    int ret = WaitingToDo(WAITING_DATA_MS, filePath, [](const string &path) {
822498b56bSopenharmony_ci        int fd;
832498b56bSopenharmony_ci        if (!access(path.c_str(), W_OK)) {
842498b56bSopenharmony_ci            fd = open(path.c_str(), O_WRONLY | O_CLOEXEC);
852498b56bSopenharmony_ci            if (fd >= 0) {
862498b56bSopenharmony_ci                close(fd);
872498b56bSopenharmony_ci                return RET_SUCCESS;
882498b56bSopenharmony_ci            }
892498b56bSopenharmony_ci        }
902498b56bSopenharmony_ci        return RET_FAIL;
912498b56bSopenharmony_ci    });
922498b56bSopenharmony_ci    if (ret != RET_SUCCESS) {
932498b56bSopenharmony_ci        return false;
942498b56bSopenharmony_ci    }
952498b56bSopenharmony_ci    if (access(filePath.c_str(), W_OK)) {
962498b56bSopenharmony_ci        return false;
972498b56bSopenharmony_ci    }
982498b56bSopenharmony_ci    int fd = open(filePath.c_str(), O_WRONLY | O_CLOEXEC);
992498b56bSopenharmony_ci    if (fd < 0) {
1002498b56bSopenharmony_ci        return false;
1012498b56bSopenharmony_ci    }
1022498b56bSopenharmony_ci    bool result = WriteStringToFile(fd, content);
1032498b56bSopenharmony_ci    close(fd);
1042498b56bSopenharmony_ci    return result;
1052498b56bSopenharmony_ci}
1062498b56bSopenharmony_ci
1072498b56bSopenharmony_ci#ifdef DEBUG
1082498b56bSopenharmony_cistatic void RedirectStdStreamToLogFile()
1092498b56bSopenharmony_ci{
1102498b56bSopenharmony_ci    int ret = WaitingToDo(WAITING_DATA_MS, HILOG_FILE_DIR, [](const string &path) {
1112498b56bSopenharmony_ci        struct stat s;
1122498b56bSopenharmony_ci        if (stat(path.c_str(), &s) != -1) {
1132498b56bSopenharmony_ci            return RET_SUCCESS;
1142498b56bSopenharmony_ci        }
1152498b56bSopenharmony_ci        return RET_FAIL;
1162498b56bSopenharmony_ci    });
1172498b56bSopenharmony_ci    if (ret == RET_SUCCESS) {
1182498b56bSopenharmony_ci        const char *path = HILOG_FILE_DIR"hilogd_debug.txt";
1192498b56bSopenharmony_ci        int mask = O_WRONLY | O_APPEND | O_CREAT;
1202498b56bSopenharmony_ci        struct stat st;
1212498b56bSopenharmony_ci        if (stat(path, &st) == -1) {
1222498b56bSopenharmony_ci            mask |= O_CREAT;
1232498b56bSopenharmony_ci        }
1242498b56bSopenharmony_ci        int fd = open(path, mask, S_IWUSR | S_IWGRP);
1252498b56bSopenharmony_ci        if (fd > 0) {
1262498b56bSopenharmony_ci            g_fd = dup2(fd, fileno(stdout));
1272498b56bSopenharmony_ci        } else {
1282498b56bSopenharmony_ci            std::cout << "open file error: ";
1292498b56bSopenharmony_ci            PrintErrorno(errno);
1302498b56bSopenharmony_ci        }
1312498b56bSopenharmony_ci    }
1322498b56bSopenharmony_ci}
1332498b56bSopenharmony_ci#endif
1342498b56bSopenharmony_ci
1352498b56bSopenharmony_ciint HilogdEntry()
1362498b56bSopenharmony_ci{
1372498b56bSopenharmony_ci    const int hilogFileMask = 0022;
1382498b56bSopenharmony_ci    umask(hilogFileMask);
1392498b56bSopenharmony_ci
1402498b56bSopenharmony_ci#ifdef DEBUG
1412498b56bSopenharmony_ci    RedirectStdStreamToLogFile();
1422498b56bSopenharmony_ci#endif
1432498b56bSopenharmony_ci    std::signal(SIGINT, SigHandler);
1442498b56bSopenharmony_ci    HilogBuffer hilogBuffer(true);
1452498b56bSopenharmony_ci    LogCollector logCollector(hilogBuffer);
1462498b56bSopenharmony_ci
1472498b56bSopenharmony_ci    // Start log_collector
1482498b56bSopenharmony_ci#ifndef __RECV_MSG_WITH_UCRED_
1492498b56bSopenharmony_ci    auto onDataReceive = [&logCollector](std::vector<char>& data, int dataLen) {
1502498b56bSopenharmony_ci        logCollector.onDataRecv(data, dataLen);
1512498b56bSopenharmony_ci    };
1522498b56bSopenharmony_ci#else
1532498b56bSopenharmony_ci    auto onDataReceive = [&logCollector](const ucred& cred, std::vector<char>& data, int dataLen) {
1542498b56bSopenharmony_ci        logCollector.onDataRecv(cred, data, dataLen);
1552498b56bSopenharmony_ci    };
1562498b56bSopenharmony_ci#endif
1572498b56bSopenharmony_ci
1582498b56bSopenharmony_ci    HilogInputSocketServer incomingLogsServer(onDataReceive);
1592498b56bSopenharmony_ci    if (incomingLogsServer.Init() < 0) {
1602498b56bSopenharmony_ci#ifdef DEBUG
1612498b56bSopenharmony_ci        cout << "Failed to init input server socket ! ";
1622498b56bSopenharmony_ci        PrintErrorno(errno);
1632498b56bSopenharmony_ci#endif
1642498b56bSopenharmony_ci    } else {
1652498b56bSopenharmony_ci#ifdef DEBUG
1662498b56bSopenharmony_ci        cout << "Begin to listen !\n";
1672498b56bSopenharmony_ci#endif
1682498b56bSopenharmony_ci        incomingLogsServer.RunServingThread();
1692498b56bSopenharmony_ci    }
1702498b56bSopenharmony_ci
1712498b56bSopenharmony_ci    HilogBuffer kmsgBuffer(false);
1722498b56bSopenharmony_ci    ffrt::submit([&hilogBuffer, &kmsgBuffer]() {
1732498b56bSopenharmony_ci        int ret = WaitingToDo(WAITING_DATA_MS, HILOG_FILE_DIR, [](const string &path) {
1742498b56bSopenharmony_ci            struct stat s;
1752498b56bSopenharmony_ci            if (stat(path.c_str(), &s) != -1) {
1762498b56bSopenharmony_ci                return RET_SUCCESS;
1772498b56bSopenharmony_ci            }
1782498b56bSopenharmony_ci            return RET_FAIL;
1792498b56bSopenharmony_ci        });
1802498b56bSopenharmony_ci        if (ret == RET_SUCCESS) {
1812498b56bSopenharmony_ci            RestorePersistJobs(hilogBuffer, kmsgBuffer);
1822498b56bSopenharmony_ci        }
1832498b56bSopenharmony_ci    }, {}, {}, ffrt::task_attr().name("hilogd.pst_res"));
1842498b56bSopenharmony_ci
1852498b56bSopenharmony_ci    bool kmsgEnable = IsKmsgSwitchOn();
1862498b56bSopenharmony_ci    if (kmsgEnable) {
1872498b56bSopenharmony_ci        LogKmsg& logKmsg = LogKmsg::GetInstance(kmsgBuffer);
1882498b56bSopenharmony_ci        logKmsg.Start();
1892498b56bSopenharmony_ci    }
1902498b56bSopenharmony_ci
1912498b56bSopenharmony_ci    ffrt::submit([]() {
1922498b56bSopenharmony_ci        string myPid = to_string(getprocpid());
1932498b56bSopenharmony_ci        (void)WriteStringToFile(myPid, SYSTEM_BG_STUNE);
1942498b56bSopenharmony_ci        (void)WriteStringToFile(myPid, SYSTEM_BG_CPUSET);
1952498b56bSopenharmony_ci        (void)WriteStringToFile(myPid, SYSTEM_BG_BLKIO);
1962498b56bSopenharmony_ci    }, {}, {}, ffrt::task_attr().name("hilogd.cgroup_set"));
1972498b56bSopenharmony_ci
1982498b56bSopenharmony_ci    std::thread([&logCollector, &hilogBuffer, &kmsgBuffer] () {
1992498b56bSopenharmony_ci        prctl(PR_SET_NAME, "hilogd.cmd");
2002498b56bSopenharmony_ci        CmdList controlCmdList {
2012498b56bSopenharmony_ci            IoctlCmd::PERSIST_START_RQST,
2022498b56bSopenharmony_ci            IoctlCmd::PERSIST_STOP_RQST,
2032498b56bSopenharmony_ci            IoctlCmd::PERSIST_QUERY_RQST,
2042498b56bSopenharmony_ci            IoctlCmd::PERSIST_REFRESH_RQST,
2052498b56bSopenharmony_ci            IoctlCmd::PERSIST_CLEAR_RQST,
2062498b56bSopenharmony_ci            IoctlCmd::BUFFERSIZE_GET_RQST,
2072498b56bSopenharmony_ci            IoctlCmd::BUFFERSIZE_SET_RQST,
2082498b56bSopenharmony_ci            IoctlCmd::STATS_QUERY_RQST,
2092498b56bSopenharmony_ci            IoctlCmd::STATS_CLEAR_RQST,
2102498b56bSopenharmony_ci            IoctlCmd::DOMAIN_FLOWCTRL_RQST,
2112498b56bSopenharmony_ci            IoctlCmd::LOG_REMOVE_RQST,
2122498b56bSopenharmony_ci            IoctlCmd::KMSG_ENABLE_RQST,
2132498b56bSopenharmony_ci        };
2142498b56bSopenharmony_ci        CmdExecutor controlExecutor(logCollector, hilogBuffer, kmsgBuffer, controlCmdList, ("hilogd.control"));
2152498b56bSopenharmony_ci        controlExecutor.MainLoop(CONTROL_SOCKET_NAME);
2162498b56bSopenharmony_ci    }).detach();
2172498b56bSopenharmony_ci
2182498b56bSopenharmony_ci    CmdList outputList {IoctlCmd::OUTPUT_RQST};
2192498b56bSopenharmony_ci    CmdExecutor outputExecutor(logCollector, hilogBuffer, kmsgBuffer, outputList, ("hilogd.output"));
2202498b56bSopenharmony_ci    outputExecutor.MainLoop(OUTPUT_SOCKET_NAME);
2212498b56bSopenharmony_ci
2222498b56bSopenharmony_ci    return 0;
2232498b56bSopenharmony_ci}
2242498b56bSopenharmony_ci} // namespace HiviewDFX
2252498b56bSopenharmony_ci} // namespace OHOS
2262498b56bSopenharmony_ci
2272498b56bSopenharmony_ciint main()
2282498b56bSopenharmony_ci{
2292498b56bSopenharmony_ci    (void)OHOS::HiviewDFX::HilogdEntry();
2302498b56bSopenharmony_ci    return 0;
2312498b56bSopenharmony_ci}
232