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