• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <iostream>
17 #include <sys/stat.h>
18 #include <sys/prctl.h>
19 #include <sys/stat.h>
20 #include <future>
21 #include <unistd.h>
22 #include <csignal>
23 #include <fcntl.h>
24 #include <hilog_input_socket_server.h>
25 #include <properties.h>
26 #include <log_utils.h>
27 
28 #include "cmd_executor.h"
29 #include "flow_control.h"
30 #include "log_kmsg.h"
31 #include "log_collector.h"
32 #include "service_controller.h"
33 
34 #ifdef DEBUG
35 #include <cstdio>
36 #include <cerrno>
37 #endif
38 
39 namespace OHOS {
40 namespace HiviewDFX {
41 using namespace std;
42 
43 static const string SYSTEM_BG_STUNE = "/dev/stune/system-background/cgroup.procs";
44 static const string SYSTEM_BG_CPUSET = "/dev/cpuset/system-background/cgroup.procs";
45 static const string SYSTEM_BG_BLKIO  = "/dev/blkio/system-background/cgroup.procs";
46 
47 #ifdef DEBUG
48 static int g_fd = -1;
49 #endif
50 
SigHandler(int sig)51 static void SigHandler(int sig)
52 {
53     if (sig == SIGINT) {
54 #ifdef DEBUG
55         if (g_fd > 0) {
56             close(g_fd);
57             g_fd = -1;
58         }
59 #endif
60         std::cout<<"Exited!"<<std::endl;
61     }
62 }
63 
WriteStringToFile(int fd,const std::string & content)64 static bool WriteStringToFile(int fd, const std::string& content)
65 {
66     const char *p = content.data();
67     size_t remaining = content.size();
68     while (remaining > 0) {
69         ssize_t n = write(fd, p, remaining);
70         if (n == -1) {
71             return false;
72         }
73         p += n;
74         remaining -= static_cast<size_t>(n);
75     }
76     return true;
77 }
78 
WriteStringToFile(const std::string & content,const std::string & filePath)79 static bool WriteStringToFile(const std::string& content, const std::string& filePath)
80 {
81     int ret = WaitingToDo(WAITING_DATA_MS, filePath, [](const string &path) {
82         int fd;
83         if (!access(path.c_str(), W_OK)) {
84             fd = open(path.c_str(), O_WRONLY | O_CLOEXEC);
85             if (fd >= 0) {
86                 close(fd);
87                 return RET_SUCCESS;
88             }
89         }
90         return RET_FAIL;
91     });
92     if (ret != RET_SUCCESS) {
93         return false;
94     }
95     if (access(filePath.c_str(), W_OK)) {
96         return false;
97     }
98     int fd = open(filePath.c_str(), O_WRONLY | O_CLOEXEC);
99     if (fd < 0) {
100         return false;
101     }
102     bool result = WriteStringToFile(fd, content);
103     close(fd);
104     return result;
105 }
106 
107 #ifdef DEBUG
RedirectStdStreamToLogFile()108 static void RedirectStdStreamToLogFile()
109 {
110     int ret = WaitingToDo(WAITING_DATA_MS, HILOG_FILE_DIR, [](const string &path) {
111         struct stat s;
112         if (stat(path.c_str(), &s) != -1) {
113             return RET_SUCCESS;
114         }
115         return RET_FAIL;
116     });
117     if (ret == RET_SUCCESS) {
118         const char *path = HILOG_FILE_DIR"hilogd_debug.txt";
119         int mask = O_WRONLY | O_APPEND | O_CREAT;
120         struct stat st;
121         if (stat(path, &st) == -1) {
122             mask |= O_CREAT;
123         }
124         int fd = open(path, mask, S_IWUSR | S_IWGRP);
125         if (fd > 0) {
126             g_fd = dup2(fd, fileno(stdout));
127         } else {
128             std::cout << "open file error: ";
129             PrintErrorno(errno);
130         }
131     }
132 }
133 #endif
134 
HilogdEntry()135 int HilogdEntry()
136 {
137     const int hilogFileMask = 0022;
138     umask(hilogFileMask);
139 
140 #ifdef DEBUG
141     RedirectStdStreamToLogFile();
142 #endif
143     std::signal(SIGINT, SigHandler);
144     HilogBuffer hilogBuffer;
145     LogCollector logCollector(hilogBuffer);
146 
147     // Start log_collector
148 #ifndef __RECV_MSG_WITH_UCRED_
149     auto onDataReceive = [&logCollector](std::vector<char>& data) {
150         logCollector.onDataRecv(data);
151     };
152 #else
153     auto onDataReceive = [&logCollector](const ucred& cred, std::vector<char>& data) {
154         logCollector.onDataRecv(cred, data);
155     };
156 #endif
157 
158     HilogInputSocketServer incomingLogsServer(onDataReceive);
159     if (incomingLogsServer.Init() < 0) {
160 #ifdef DEBUG
161         cout << "Failed to init input server socket ! ";
162         PrintErrorno(errno);
163 #endif
164     } else {
165 #ifdef DEBUG
166         cout << "Begin to listen !\n";
167 #endif
168         incomingLogsServer.RunServingThread();
169     }
170 
171     auto startupCheckTask = std::async(std::launch::async, [&hilogBuffer]() {
172         prctl(PR_SET_NAME, "hilogd.pst_res");
173         int ret = WaitingToDo(WAITING_DATA_MS, HILOG_FILE_DIR, [](const string &path) {
174             struct stat s;
175             if (stat(path.c_str(), &s) != -1) {
176                 return RET_SUCCESS;
177             }
178             return RET_FAIL;
179         });
180         if (ret == RET_SUCCESS) {
181             hilogBuffer.InitBuffLen();
182             RestorePersistJobs(hilogBuffer);
183         }
184     });
185 
186     bool kmsgEnable = IsKmsgSwitchOn();
187     if (kmsgEnable) {
188         LogKmsg& logKmsg = LogKmsg::GetInstance(hilogBuffer);
189         logKmsg.Start();
190     }
191 
192     auto cgroupWriteTask = std::async(std::launch::async, [&hilogBuffer]() {
193         prctl(PR_SET_NAME, "hilogd.cgroup_set");
194         string myPid = to_string(getpid());
195         (void)WriteStringToFile(myPid, SYSTEM_BG_STUNE);
196         (void)WriteStringToFile(myPid, SYSTEM_BG_CPUSET);
197         (void)WriteStringToFile(myPid, SYSTEM_BG_BLKIO);
198     });
199 
200     auto cmdExecuteTask = std::async(std::launch::async, [&logCollector, &hilogBuffer]() {
201         prctl(PR_SET_NAME, "hilogd.cmd");
202         CmdList controlCmdList {
203             IoctlCmd::PERSIST_START_RQST,
204             IoctlCmd::PERSIST_STOP_RQST,
205             IoctlCmd::PERSIST_QUERY_RQST,
206             IoctlCmd::BUFFERSIZE_GET_RQST,
207             IoctlCmd::BUFFERSIZE_SET_RQST,
208             IoctlCmd::STATS_QUERY_RQST,
209             IoctlCmd::STATS_CLEAR_RQST,
210             IoctlCmd::DOMAIN_FLOWCTRL_RQST,
211             IoctlCmd::LOG_REMOVE_RQST,
212             IoctlCmd::KMSG_ENABLE_RQST,
213         };
214         CmdExecutor controlExecutor(logCollector, hilogBuffer, controlCmdList, ("hilogd.control"));
215         controlExecutor.MainLoop(CONTROL_SOCKET_NAME);
216     });
217 
218     CmdList outputList {IoctlCmd::OUTPUT_RQST};
219     CmdExecutor outputExecutor(logCollector, hilogBuffer, outputList, ("hilogd.output"));
220     outputExecutor.MainLoop(OUTPUT_SOCKET_NAME);
221 
222     return 0;
223 }
224 } // namespace HiviewDFX
225 } // namespace OHOS
226 
main()227 int main()
228 {
229     (void)OHOS::HiviewDFX::HilogdEntry();
230     return 0;
231 }
232