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