• 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 <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