• 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 "dump_manager_service.h"
16 #include <file_ex.h>
17 #include <if_system_ability_manager.h>
18 #include <ipc_skeleton.h>
19 #include <iservice_registry.h>
20 #include <string_ex.h>
21 #include <system_ability_definition.h>
22 #include <thread>
23 #include <unistd.h>
24 
25 #include "common.h"
26 #include "common/dumper_constant.h"
27 #include "dump_log_manager.h"
28 #include "hilog_wrapper.h"
29 #include "inner/dump_service_id.h"
30 #include "manager/dump_implement.h"
31 #include "raw_param.h"
32 #include "token_setproc.h"
33 using namespace std;
34 namespace OHOS {
35 namespace HiviewDFX {
36 namespace {
37 const std::string DUMPMGR_SERVICE_NAME = "HiDumperManagerService";
38 auto dumpManagerService = DelayedSpSingleton<DumpManagerService>::GetInstance();
39 const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(dumpManagerService.GetRefPtr());
40 static const int32_t STOP_WAIT = 3;
41 static const int32_t REQUEST_MAX = 2;
42 static const uint32_t REQUESTID_MAX = 100000;
43 } // namespace
DumpManagerService()44 DumpManagerService::DumpManagerService() : SystemAbility(DFX_SYS_HIDUMPER_ABILITY_ID, true)
45 {
46 }
47 
~DumpManagerService()48 DumpManagerService::~DumpManagerService()
49 {
50 }
51 
OnStart()52 void DumpManagerService::OnStart()
53 {
54     if (started_) {
55         DUMPER_HILOGE(MODULE_SERVICE, "error|it's ready, nothing to do.");
56         return;
57     }
58 
59     if (!Init()) {
60         DUMPER_HILOGE(MODULE_SERVICE, "error|init fail, nothing to do.");
61         return;
62     }
63 
64     if (eventRunner_ != nullptr) {
65         eventRunner_->Run();
66     }
67 
68     if (!Publish(DelayedSpSingleton<DumpManagerService>::GetInstance())) {
69         DUMPER_HILOGE(MODULE_SERVICE, "error|register to system ability manager failed.");
70         return;
71     }
72     started_ = true;
73 }
74 
OnStop()75 void DumpManagerService::OnStop()
76 {
77     if (!started_) {
78         return;
79     }
80     DUMPER_HILOGD(MODULE_SERVICE, "enter|");
81     blockRequest_ = true;
82     CancelAllRequest();
83     for (int i = 0; i < STOP_WAIT; i++) {
84         if (requestRawParamMap_.empty()) {
85             break;
86         }
87         sleep(1);
88     }
89     started_ = false;
90     blockRequest_ = false;
91     DUMPER_HILOGD(MODULE_SERVICE, "leave|");
92 }
93 
Dump(int32_t fd,const std::vector<std::u16string> & args)94 int32_t DumpManagerService::Dump(int32_t fd, const std::vector<std::u16string> &args)
95 {
96     std::string result = DUMPMGR_SERVICE_NAME;
97     if (!SaveStringToFd(fd, result)) {
98         DUMPER_HILOGE(MODULE_SERVICE, "DumpManagerService::Dump failed, save to fd failed.");
99         DUMPER_HILOGE(MODULE_SERVICE, "Dump Info:\n");
100         DUMPER_HILOGE(MODULE_SERVICE, "%{public}s", result.c_str());
101         return ERR_OK;
102     }
103     return ERR_OK;
104 }
105 
Request(std::vector<std::u16string> & args,int outfd)106 int32_t DumpManagerService::Request(std::vector<std::u16string> &args, int outfd)
107 {
108     if (blockRequest_) {
109         return DumpStatus::DUMP_FAIL;
110     }
111     if (!started_) {
112         return DumpStatus::DUMP_FAIL;
113     }
114     int sum = GetRequestSum();
115     DUMPER_HILOGD(MODULE_SERVICE, "debug|sum=%{public}d", sum);
116     if (sum >= REQUEST_MAX) {
117         return DumpStatus::DUMP_REQUEST_MAX;
118     } else if (sum == 0) {
119         DumpLogManager::Init();
120     }
121     DUMPER_HILOGD(MODULE_SERVICE, "enter|");
122     const std::shared_ptr<RawParam> rawParam = AddRequestRawParam(args, outfd);
123     int32_t ret = StartRequest(rawParam);
124     DUMPER_HILOGD(MODULE_SERVICE, "leave|ret=%{public}d", ret);
125     return ret;
126 }
127 
GetHandler() const128 std::shared_ptr<DumpEventHandler> DumpManagerService::GetHandler() const
129 {
130     return handler_;
131 }
132 
133 #ifdef DUMP_TEST_MODE // for mock test
SetTestMainFunc(DumpManagerServiceTestMainFunc testMainFunc)134 void DumpManagerService::SetTestMainFunc(DumpManagerServiceTestMainFunc testMainFunc)
135 {
136     testMainFunc_ = testMainFunc;
137 }
138 #endif // for mock test
139 
Init()140 bool DumpManagerService::Init()
141 {
142     if (!eventRunner_) {
143         eventRunner_ = AppExecFwk::EventRunner::Create(DUMPMGR_SERVICE_NAME);
144         if (eventRunner_ == nullptr) {
145             DUMPER_HILOGE(MODULE_SERVICE, "error|create EventRunner");
146             return false;
147         }
148     }
149     if (!handler_) {
150         handler_ = std::make_shared<DumpEventHandler>(eventRunner_, dumpManagerService);
151     }
152     handler_->SendEvent(DumpEventHandler::MSG_GET_CPU_INFO_ID, DumpEventHandler::GET_CPU_INFO_DELAY_TIME);
153     return true;
154 }
155 
GetRequestSum()156 int DumpManagerService::GetRequestSum()
157 {
158     unique_lock<mutex> lock(mutex_);
159     return requestRawParamMap_.size();
160 }
161 
AddRequestRawParam(std::vector<std::u16string> & args,int outfd)162 std::shared_ptr<RawParam> DumpManagerService::AddRequestRawParam(std::vector<std::u16string> &args, int outfd)
163 {
164     unique_lock<mutex> lock(mutex_);
165     uint32_t requestId = 0;
166     do { // find a requestId
167         requestId = GetRequestId();
168     } while (requestRawParamMap_.count(requestId) > 0);
169     int32_t calllingUid = IPCSkeleton::GetCallingUid();
170     int32_t calllingPid = IPCSkeleton::GetCallingPid();
171     auto calllingTokenID = IPCSkeleton::GetCallingTokenID();
172     SetFirstCallerTokenID(calllingTokenID);
173     DUMPER_HILOGD(MODULE_SERVICE, "debug|requestId=%{public}u, calllingUid=%{public}d, calllingPid=%{public}d",
174                   requestId, calllingUid, calllingPid);
175     std::shared_ptr<RawParam> requestHandle =
176         std::make_shared<RawParam>(calllingUid, calllingPid, requestId, args, outfd);
177     requestRawParamMap_.insert(std::make_pair(requestId, requestHandle));
178     return requestHandle;
179 }
180 
EraseRequestRawParam(const std::shared_ptr<RawParam> rawParam)181 void DumpManagerService::EraseRequestRawParam(const std::shared_ptr<RawParam> rawParam)
182 {
183     if (rawParam == nullptr) {
184         return;
185     }
186     DUMPER_HILOGD(MODULE_SERVICE, "enter|");
187     unique_lock<mutex> lock(mutex_);
188     uint32_t requestId = rawParam->GetRequestId();
189     DUMPER_HILOGD(MODULE_SERVICE, "debug|requestId=%{public}u", requestId);
190     if (requestRawParamMap_.count(requestId) > 0) {
191         requestRawParamMap_.erase(requestId);
192         DUMPER_HILOGD(MODULE_SERVICE, "debug|erase");
193     }
194     DUMPER_HILOGD(MODULE_SERVICE, "leave|");
195 }
196 
CancelAllRequest()197 void DumpManagerService::CancelAllRequest()
198 {
199     DUMPER_HILOGD(MODULE_SERVICE, "enter|");
200     unique_lock<mutex> lock(mutex_);
201     for (auto &requestIt : requestRawParamMap_) {
202         if (requestIt.second == nullptr) {
203             continue;
204         }
205         requestIt.second->Cancel();
206     }
207     DUMPER_HILOGD(MODULE_SERVICE, "leave|");
208 }
209 
GetRequestId()210 uint32_t DumpManagerService::GetRequestId()
211 {
212     requestIndex_ = (requestIndex_ + 1) % REQUESTID_MAX;
213     return requestIndex_;
214 }
215 
StartRequest(const std::shared_ptr<RawParam> rawParam)216 int32_t DumpManagerService::StartRequest(const std::shared_ptr<RawParam> rawParam)
217 {
218     RequestMain(rawParam);
219     return DumpStatus::DUMP_OK;
220 }
221 
RequestMain(const std::shared_ptr<RawParam> rawParam)222 void DumpManagerService::RequestMain(const std::shared_ptr<RawParam> rawParam)
223 {
224     DUMPER_HILOGD(MODULE_SERVICE, "enter|");
225     int argC = rawParam->GetArgc();
226     char **argV = rawParam->GetArgv();
227     std::string folder = DumpLogManager::CreateTmpFolder(rawParam->GetRequestId());
228     rawParam->SetFolder(folder);
229     if ((argC > 0) && (argV != nullptr)) {
230         DUMPER_HILOGD(MODULE_SERVICE, "debug|enter task, argC=%{public}d", argC);
231         for (int i = 0; i < argC; i++) {
232             DUMPER_HILOGD(MODULE_SERVICE, "debug|argV[%{public}d]=%{public}s", i, argV[i]);
233         }
234         DumpImplement::GetInstance().Main(argC, argV, rawParam);
235         DUMPER_HILOGD(MODULE_SERVICE, "debug|leave task");
236     }
237     DumpLogManager::EraseTmpFolder(rawParam->GetRequestId());
238     DumpLogManager::EraseLogs();
239     rawParam->CloseOutputFd();
240     EraseRequestRawParam(rawParam);
241     DUMPER_HILOGD(MODULE_SERVICE, "leave|");
242 }
243 } // namespace HiviewDFX
244 } // namespace OHOS
245