• 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     }
61 }
62 
WriteStringToFile(int fd,const std::string & content)63 static bool WriteStringToFile(int fd, const std::string& content)
64 {
65     const char *p = content.data();
66     size_t remaining = content.size();
67     while (remaining > 0) {
68         ssize_t n = write(fd, p, remaining);
69         if (n == -1) {
70             return false;
71         }
72         p += n;
73         remaining -= static_cast<size_t>(n);
74     }
75     return true;
76 }
77 
WriteStringToFile(const std::string & content,const std::string & filePath)78 static bool WriteStringToFile(const std::string& content, const std::string& filePath)
79 {
80     int ret = WaitingToDo(WAITING_DATA_MS, filePath, [](const string &path) {
81         int fd;
82         if (!access(path.c_str(), W_OK)) {
83             fd = open(path.c_str(), O_WRONLY | O_CLOEXEC);
84             if (fd >= 0) {
85                 close(fd);
86                 return RET_SUCCESS;
87             }
88         }
89         return RET_FAIL;
90     });
91     if (ret != RET_SUCCESS) {
92         return false;
93     }
94     if (access(filePath.c_str(), W_OK)) {
95         return false;
96     }
97     int fd = open(filePath.c_str(), O_WRONLY | O_CLOEXEC);
98     if (fd < 0) {
99         return false;
100     }
101     bool result = WriteStringToFile(fd, content);
102     close(fd);
103     return result;
104 }
105 
106 #ifdef DEBUG
RedirectStdStreamToLogFile()107 static void RedirectStdStreamToLogFile()
108 {
109     int ret = WaitingToDo(WAITING_DATA_MS, HILOG_FILE_DIR, [](const string &path) {
110         struct stat s;
111         if (stat(path.c_str(), &s) != -1) {
112             return RET_SUCCESS;
113         }
114         return RET_FAIL;
115     });
116     if (ret == RET_SUCCESS) {
117         const char *path = HILOG_FILE_DIR"hilogd_debug.txt";
118         int mask = O_WRONLY | O_APPEND | O_CREAT;
119         struct stat st;
120         if (stat(path, &st) == -1) {
121             mask |= O_CREAT;
122         }
123         int fd = open(path, mask, S_IWUSR | S_IWGRP);
124         if (fd > 0) {
125             g_fd = dup2(fd, fileno(stdout));
126         } else {
127             std::cout << "open file error: ";
128             PrintErrorno(errno);
129         }
130     }
131 }
132 #endif
133 
HilogdEntry()134 int HilogdEntry()
135 {
136     const int hilogFileMask = 0022;
137     umask(hilogFileMask);
138 
139 #ifdef DEBUG
140     RedirectStdStreamToLogFile();
141 #endif
142     std::signal(SIGINT, SigHandler);
143     HilogBuffer hilogBuffer;
144     LogCollector logCollector(hilogBuffer);
145 
146     // Start log_collector
147 #ifndef __RECV_MSG_WITH_UCRED_
148     auto onDataReceive = [&logCollector](std::vector<char>& data, int dataLen) {
149         logCollector.onDataRecv(data, dataLen);
150     };
151 #else
152     auto onDataReceive = [&logCollector](const ucred& cred, std::vector<char>& data, int dataLen) {
153         logCollector.onDataRecv(cred, data, dataLen);
154     };
155 #endif
156 
157     HilogInputSocketServer incomingLogsServer(onDataReceive);
158     if (incomingLogsServer.Init() < 0) {
159 #ifdef DEBUG
160         cout << "Failed to init input server socket ! ";
161         PrintErrorno(errno);
162 #endif
163     } else {
164 #ifdef DEBUG
165         cout << "Begin to listen !\n";
166 #endif
167         incomingLogsServer.RunServingThread();
168     }
169 
170     auto startupCheckTask = std::async(std::launch::async, [&hilogBuffer]() {
171         prctl(PR_SET_NAME, "hilogd.pst_res");
172         int ret = WaitingToDo(WAITING_DATA_MS, HILOG_FILE_DIR, [](const string &path) {
173             struct stat s;
174             if (stat(path.c_str(), &s) != -1) {
175                 return RET_SUCCESS;
176             }
177             return RET_FAIL;
178         });
179         if (ret == RET_SUCCESS) {
180             hilogBuffer.InitBuffLen();
181             RestorePersistJobs(hilogBuffer);
182         }
183     });
184 
185     bool kmsgEnable = IsKmsgSwitchOn();
186     if (kmsgEnable) {
187         LogKmsg& logKmsg = LogKmsg::GetInstance(hilogBuffer);
188         logKmsg.Start();
189     }
190 
191     auto cgroupWriteTask = std::async(std::launch::async, [&hilogBuffer]() {
192         prctl(PR_SET_NAME, "hilogd.cgroup_set");
193         string myPid = to_string(getpid());
194         (void)WriteStringToFile(myPid, SYSTEM_BG_STUNE);
195         (void)WriteStringToFile(myPid, SYSTEM_BG_CPUSET);
196         (void)WriteStringToFile(myPid, SYSTEM_BG_BLKIO);
197     });
198 
199     auto cmdExecuteTask = std::async(std::launch::async, [&logCollector, &hilogBuffer]() {
200         prctl(PR_SET_NAME, "hilogd.cmd");
201         CmdList controlCmdList {
202             IoctlCmd::PERSIST_START_RQST,
203             IoctlCmd::PERSIST_STOP_RQST,
204             IoctlCmd::PERSIST_QUERY_RQST,
205             IoctlCmd::BUFFERSIZE_GET_RQST,
206             IoctlCmd::BUFFERSIZE_SET_RQST,
207             IoctlCmd::STATS_QUERY_RQST,
208             IoctlCmd::STATS_CLEAR_RQST,
209             IoctlCmd::DOMAIN_FLOWCTRL_RQST,
210             IoctlCmd::LOG_REMOVE_RQST,
211             IoctlCmd::KMSG_ENABLE_RQST,
212         };
213         CmdExecutor controlExecutor(logCollector, hilogBuffer, controlCmdList, ("hilogd.control"));
214         controlExecutor.MainLoop(CONTROL_SOCKET_NAME);
215     });
216 
217     CmdList outputList {IoctlCmd::OUTPUT_RQST};
218     CmdExecutor outputExecutor(logCollector, hilogBuffer, outputList, ("hilogd.output"));
219     outputExecutor.MainLoop(OUTPUT_SOCKET_NAME);
220 
221     return 0;
222 }
223 } // namespace HiviewDFX
224 } // namespace OHOS
225 
main()226 int main()
227 {
228     (void)OHOS::HiviewDFX::HilogdEntry();
229     return 0;
230 }
231