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 33namespace OHOS { 34namespace SmartPerf { 35StartUpDelay::StartUpDelay() {} 36StartUpDelay::~StartUpDelay() {} 37void 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 if (result.find("OpenRecording failed") != std::string::npos) { 48 std::string str; 49 std::string traceFinishStr = "hitrace --trace_finish"; 50 SPUtils::LoadCmd(traceFinishStr, str); 51 SPUtils::LoadCmd(cmdString + traceName, result); 52 } 53} 54 55void StartUpDelay::GetHisysId() const 56{ 57 int time = 10; 58 sleep(time); 59 std::string str = ""; 60 std::string cmd = HISYSEVENT_CMD_MAP.at(HisyseventCmd::HISYSEVENT); 61 SPUtils::LoadCmd(cmd, str); 62 std::stringstream ss(str); 63 std::string line = ""; 64 getline(ss, line); 65 std::stringstream ssLine(line); 66 std::string word = ""; 67 std::string secondStr; 68 int count = 0; 69 int num = 2; 70 while (ssLine >> word) { 71 count++; 72 if (count == num) { 73 secondStr = word; 74 break; 75 } 76 } 77 std::string killCmd = CMD_COMMAND_MAP.at(CmdCommand::KILL_CMD); 78 SPUtils::LoadCmd(killCmd + secondStr, str); 79} 80 81void StartUpDelay::GetHisysIdAndKill() const 82{ 83 int time = 10; 84 sleep(time); 85 std::string str = ""; 86 std::string cmd = HISYSEVENT_CMD_MAP.at(HisyseventCmd::HISYS_PID); 87 SPUtils::LoadCmd(cmd, str); 88 std::stringstream ss(str); 89 std::vector<std::string> hisysIdVec; 90 std::string singleId; 91 while (ss >> singleId) { 92 hisysIdVec.push_back(singleId); 93 } 94 std::string killCmd = CMD_COMMAND_MAP.at(CmdCommand::KILL_CMD); 95 for (size_t i = 0; i < hisysIdVec.size(); i++) { 96 SPUtils::LoadCmd(killCmd + hisysIdVec[i], str); 97 } 98} 99bool StartUpDelay::GetSpTcp() 100{ 101 std::string resultPid; 102 std::string str; 103 std::string cmd = CMD_COMMAND_MAP.at(CmdCommand::PIDOF_SP); 104 SPUtils::LoadCmd(cmd, resultPid); 105 std::vector<std::string> vec; 106 std::string token; 107 size_t pos = 0; 108 while ((pos = resultPid.find(' ')) != std::string::npos) { 109 token = resultPid.substr(0, pos); 110 vec.push_back(token); 111 resultPid.erase(0, pos + 1); 112 } 113 if (vec.size() > 0) { 114 std::string killCmd = CMD_COMMAND_MAP.at(CmdCommand::KILL_CMD); 115 for (size_t i = 0; i < vec.size(); i++) { 116 SPUtils::LoadCmd(killCmd + vec[i], str); 117 } 118 } 119 return false; 120} 121 122bool StartUpDelay::GetSpClear() const 123{ 124 std::string resultPid; 125 std::string str; 126 std::string cmd = CMD_COMMAND_MAP.at(CmdCommand::PIDOF_SP); 127 SPUtils::LoadCmd("pidof SP_daemon", resultPid); 128 std::string token; 129 std::string curPid = std::to_string(getpid()); 130 std::stringstream ss(resultPid); 131 std::string killCmd = CMD_COMMAND_MAP.at(CmdCommand::KILL_CMD); 132 while (ss >> token) { 133 if (token != curPid) { 134 SPUtils::LoadCmd("kill " + token, str); 135 } 136 } 137 138 return false; 139} 140 141void StartUpDelay::ClearOldServer() const 142{ 143 std::string curPid = std::to_string(getpid()); 144 std::string commandServer = CMD_COMMAND_MAP.at(CmdCommand::SERVER_GREP); 145 std::string resultPidServer; 146 std::string commandEditorServer = CMD_COMMAND_MAP.at(CmdCommand::EDITOR_SERVER_GREP); 147 std::string resultPidEditorServer; 148 149 SPUtils::LoadCmdWithLinkBreak(commandServer, false, resultPidServer); 150 SPUtils::LoadCmdWithLinkBreak(commandEditorServer, false, resultPidEditorServer); 151 152 std::istringstream iss(resultPidServer + '\n' + resultPidEditorServer); 153 std::string resultLine; 154 std::string killResult; 155 std::string killCmd = CMD_COMMAND_MAP.at(CmdCommand::KILL_CMD); 156 while (std::getline(iss, resultLine)) { 157 if (resultLine.empty() || resultLine.find("sh -c") != std::string::npos) { 158 continue; 159 } 160 161 std::istringstream lineStream(resultLine); 162 std::string token; 163 164 int count = 0; 165 while (lineStream >> token) { 166 if (count == 1) { 167 break; 168 } 169 count++; 170 } 171 172 if (token != curPid) { 173 SPUtils::LoadCmd(killCmd + token, killResult); 174 LOGI("Find old server: %s, killed.", token.c_str()); 175 } 176 } 177} 178std::string StartUpDelay::ExecuteCommand(const std::string &command, const std::vector<std::string> &args) 179{ 180 std::string output = ""; 181 int pipefd[2]; 182 if (pipe(pipefd) == -1) { 183 LOGE("startup_delay::Failed to create pipe: %s", strerror(errno)); 184 return output; 185 } 186 pid_t pid = fork(); 187 if (pid == -1) { 188 LOGE("startup_delay::Failed to fork: %s", strerror(errno)); 189 close(pipefd[0]); 190 close(pipefd[1]); 191 return output; 192 } 193 if (pid == 0) { 194 close(pipefd[0]); 195 dup2(pipefd[1], STDOUT_FILENO); 196 close(pipefd[1]); 197 std::vector<char*> argv(args.size() + 1); 198 for (size_t i = 0; i < args.size(); ++i) { 199 argv[i] = const_cast<char*>(args[i].c_str()); 200 } 201 argv[args.size()] = nullptr; 202 execvp(command.c_str(), argv.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 229std::string StartUpDelay::GetPidByPkg(const std::string &curPkgName) 230{ 231 const std::string pidof = "pidof"; 232 const std::vector<std::string> args = {pidof, curPkgName}; 233 std::string resultProcId = ExecuteCommand(pidof, args); 234 if (!resultProcId.empty() && resultProcId.back() == '\n') { 235 resultProcId.pop_back(); 236 LOGI("startup_delay::output: (%s)", resultProcId.c_str()); 237 } 238 return resultProcId; 239} 240} 241} 242