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