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 #include <thread>
16 #include <cstdio>
17 #include <ios>
18 #include <vector>
19 #include <iostream>
20 #include <fstream>
21 #include <sstream>
22 #include <regex>
23 #include <sys/wait.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 #include <sys/types.h>
27 #include <sys/wait.h>
28 #include "include/startup_delay.h"
29 #include "include/sp_utils.h"
30 #include "include/sp_log.h"
31 #include "include/common.h"
32
33 namespace OHOS {
34 namespace SmartPerf {
35 std::vector<std::string> g_pidParams;
StartUpDelay()36 StartUpDelay::StartUpDelay() {}
~StartUpDelay()37 StartUpDelay::~StartUpDelay() {}
GetTrace(const std::string & traceName) const38 void StartUpDelay::GetTrace(const std::string &traceName) const
39 {
40 std::string result;
41 std::string cmdString;
42 if (SPUtils::IsHmKernel()) {
43 cmdString = CMD_COMMAND_MAP.at(CmdCommand::HITRACE_1024);
44 } else {
45 cmdString = CMD_COMMAND_MAP.at(CmdCommand::HITRACE_2048);
46 }
47 SPUtils::LoadCmd(cmdString + traceName, result);
48 LOGD("GetTrace : %s", (cmdString + traceName).c_str());
49 if (result.find("OpenRecording failed") != std::string::npos) {
50 std::string str;
51 std::string traceFinishStr = "hitrace --trace_finish";
52 SPUtils::LoadCmd(traceFinishStr, str);
53 SPUtils::LoadCmd(cmdString + traceName, result);
54 }
55 }
56
GetHisysId() const57 void StartUpDelay::GetHisysId() const
58 {
59 int time = 10;
60 sleep(time);
61 std::string str = "";
62 std::string cmd = HISYSEVENT_CMD_MAP.at(HisyseventCmd::HISYSEVENT);
63 SPUtils::LoadCmd(cmd, str);
64 std::stringstream ss(str);
65 std::string line = "";
66 getline(ss, line);
67 std::stringstream ssLine(line);
68 std::string word = "";
69 std::string secondStr;
70 int count = 0;
71 int num = 2;
72 while (ssLine >> word) {
73 count++;
74 if (count == num) {
75 secondStr = word;
76 break;
77 }
78 }
79 std::string killCmd = CMD_COMMAND_MAP.at(CmdCommand::KILL_CMD);
80 SPUtils::LoadCmd(killCmd + secondStr, str);
81 }
82
GetHisysIdAndKill() const83 void StartUpDelay::GetHisysIdAndKill() const
84 {
85 int time = 10;
86 sleep(time);
87 std::string str = "";
88 std::string cmd = HISYSEVENT_CMD_MAP.at(HisyseventCmd::HISYS_PID);
89 SPUtils::LoadCmd(cmd, str);
90 std::stringstream ss(str);
91 std::vector<std::string> hisysIdVec;
92 std::string singleId;
93 while (ss >> singleId) {
94 hisysIdVec.push_back(singleId);
95 }
96 std::string killCmd = CMD_COMMAND_MAP.at(CmdCommand::KILL_CMD);
97 for (size_t i = 0; i < hisysIdVec.size(); i++) {
98 SPUtils::LoadCmd(killCmd + hisysIdVec[i], str);
99 }
100 }
GetSpTcp() const101 bool StartUpDelay::GetSpTcp() const
102 {
103 std::string resultPid;
104 std::string str;
105 std::string cmd = CMD_COMMAND_MAP.at(CmdCommand::PIDOF_SP);
106 SPUtils::LoadCmd(cmd, resultPid);
107 std::vector<std::string> vec;
108 std::string token;
109 size_t pos = 0;
110 while ((pos = resultPid.find(' ')) != std::string::npos) {
111 token = resultPid.substr(0, pos);
112 vec.push_back(token);
113 resultPid.erase(0, pos + 1);
114 }
115 if (vec.size() > 0) {
116 std::string killCmd = CMD_COMMAND_MAP.at(CmdCommand::KILL_CMD);
117 for (size_t i = 0; i < vec.size(); i++) {
118 SPUtils::LoadCmd(killCmd + vec[i], str);
119 }
120 }
121 return false;
122 }
123
GetSpClear() const124 bool StartUpDelay::GetSpClear() const
125 {
126 std::string resultPid;
127 std::string str;
128 std::string cmd = CMD_COMMAND_MAP.at(CmdCommand::PIDOF_SP);
129 SPUtils::LoadCmd("pidof SP_daemon", resultPid);
130 std::string token;
131 std::string curPid = std::to_string(getpid());
132 std::stringstream ss(resultPid);
133 std::string killCmd = CMD_COMMAND_MAP.at(CmdCommand::KILL_CMD);
134 while (ss >> token) {
135 if (token != curPid) {
136 SPUtils::LoadCmd("kill " + token, str);
137 }
138 }
139
140 return false;
141 }
142
ClearOldServer() const143 void StartUpDelay::ClearOldServer() const
144 {
145 std::string curPid = std::to_string(getpid());
146 std::string commandServer = CMD_COMMAND_MAP.at(CmdCommand::SERVER_GREP);
147 std::string resultPidServer;
148 std::string commandEditorServer = CMD_COMMAND_MAP.at(CmdCommand::EDITOR_SERVER_GREP);
149 std::string resultPidEditorServer;
150
151 SPUtils::LoadCmdWithLinkBreak(commandServer, false, resultPidServer);
152 SPUtils::LoadCmdWithLinkBreak(commandEditorServer, false, resultPidEditorServer);
153
154 std::istringstream iss(resultPidServer + '\n' + resultPidEditorServer);
155 std::string resultLine;
156 std::string killResult;
157 std::string killCmd = CMD_COMMAND_MAP.at(CmdCommand::KILL_CMD);
158 while (std::getline(iss, resultLine)) {
159 if (resultLine.empty() || resultLine.find("sh -c") != std::string::npos) {
160 continue;
161 }
162
163 std::istringstream lineStream(resultLine);
164 std::string token;
165
166 int count = 0;
167 while (lineStream >> token) {
168 if (count == 1) {
169 break;
170 }
171 count++;
172 }
173
174 if (token != curPid) {
175 SPUtils::LoadCmd(killCmd + token, killResult);
176 LOGD("Find old server: %s, killed.", token.c_str());
177 }
178 }
179 }
ExecuteCommand(const std::vector<const char * > & args) const180 std::string StartUpDelay::ExecuteCommand(const std::vector<const char*> &args) const
181 {
182 std::string output = "";
183 int pipefd[2];
184 if (pipe(pipefd) == -1) {
185 LOGE("startup_delay::Failed to create pipe: %s", strerror(errno));
186 return output;
187 }
188 pid_t pid = fork();
189 if (pid == -1) {
190 LOGE("startup_delay::Failed to fork: %s", strerror(errno));
191 close(pipefd[0]);
192 close(pipefd[1]);
193 return output;
194 }
195 if (pid == 0) {
196 close(pipefd[0]);
197 dup2(pipefd[1], STDOUT_FILENO);
198 close(pipefd[1]);
199 if (args.empty() || args[0] == nullptr) {
200 LOGE("startup_delay::Invalid commd");
201 return output;
202 }
203 execvp(args[0], const_cast<char* const*>(args.data()));
204 LOGE("startup_delay::Failed to execute pid: %s", strerror(errno));
205 _exit(EXIT_FAILURE);
206 }
207 close(pipefd[1]);
208 char buf[1024];
209 ssize_t nread;
210 while ((nread = read(pipefd[0], buf, sizeof(buf) - 1)) > 0) {
211 if (nread == sizeof(buf) - 1) {
212 LOGE("startup_delay::Buffer overflow: %s", strerror(errno));
213 break;
214 }
215 buf[nread] = '\0';
216 output.append(buf);
217 }
218 if (nread == -1) {
219 LOGE("startup_delay::Failed to read from pipe: %s", strerror(errno));
220 }
221 close(pipefd[0]);
222 int status;
223 if (waitpid(pid, &status, 0) == -1) {
224 LOGE("startup_delay::Failed to wait for child process: %s", strerror(errno));
225 return output;
226 }
227 return output;
228 }
229
GetPidByPkg(const std::string & curPkgName,std::string * pids) const230 std::string StartUpDelay::GetPidByPkg(const std::string &curPkgName, std::string* pids) const
231 {
232 std::vector<const char*> args = {"pidof", curPkgName.c_str()};
233 args.push_back(nullptr);
234 std::string resultProcId = ExecuteCommand(args);
235 LOGD("StartUpDelay::resultProcId(%s)", resultProcId.c_str());
236 if (!resultProcId.empty()) {
237 if (resultProcId.back() == '\n') {
238 resultProcId.pop_back();
239 }
240 g_pidParams.clear();
241 SPUtils::StrSplit(resultProcId, " ", g_pidParams);
242 pids == nullptr ? "" : *pids = resultProcId;
243 size_t endpos = resultProcId.find(" ");
244 if (endpos != std::string::npos) {
245 resultProcId = resultProcId.substr(0, endpos);
246 }
247 LOGD("startup_delay::output: (%s) (%s)", resultProcId.c_str(),
248 pids == nullptr ? resultProcId.c_str() : pids->c_str());
249 }
250 return resultProcId;
251 }
252
GetPidParams() const253 std::vector<std::string> StartUpDelay::GetPidParams() const
254 {
255 return g_pidParams;
256 }
257 }
258 }
259