Line data Source code
1 : /**
2 : * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "inc/sub_process_controller.h"
12 : #include "tsd_log.h"
13 : #include "tsd_scope_guard.h"
14 : #include "tsd/status.h"
15 : #include "tsd_util_func.h"
16 :
17 : namespace {
18 : constexpr uint64_t PROCESS_OPEN_MAX_ENV_CNT = 128UL;
19 : constexpr uint64_t PROCESS_OPEN_MAX_EXT_PARAM_CNT = 128UL;
20 : constexpr uint32_t MAX_PROCESS_PID_CNT = 1024U;
21 : constexpr uint32_t CLOSE_PID_PER_LOOP = 50U;
22 : } // namespace
23 :
24 : namespace tsd {
25 :
26 : SubProcessController::SubProcessController(
27 : TsdProcessController& tsdCtrl, DeviceCommAgent& commAgent, CapabilityManager& capabilityMgr,
28 : PackageManager& packageMgr, ProcessSharedContext& sharedCtx)
29 : : tsdCtrl_(tsdCtrl),
30 : commAgent_(commAgent),
31 : capabilityMgr_(capabilityMgr),
32 : packageMgr_(packageMgr),
33 : sharedCtx_(sharedCtx)
34 : {}
35 :
36 : bool SubProcessController::SetCommonOpenParamList(MessageContext& ctx, const ProcOpenArgs* const procArgs) const
37 : {
38 : if ((procArgs->envCnt > PROCESS_OPEN_MAX_ENV_CNT) || (procArgs->extParamCnt > PROCESS_OPEN_MAX_EXT_PARAM_CNT)) {
39 : TSD_ERROR("input param error envCnt:%llu, extParamCnt:%llu", procArgs->envCnt, procArgs->extParamCnt);
40 : return false;
41 : }
42 : try {
43 : ctx.subProcOpenType = static_cast<uint32_t>(procArgs->procType);
44 : if ((procArgs->filePath != nullptr) && (procArgs->pathLen != 0)) {
45 : const std::string filePath(procArgs->filePath, procArgs->pathLen);
46 : ctx.hasSubProcFilePath = true;
47 : ctx.subProcFilePath = filePath;
48 : TSD_INFO("filePath:%s", filePath.c_str());
49 : }
50 : if ((procArgs->procType == TSD_SUB_PROC_BUILTIN_UDF) || (procArgs->procType == TSD_SUB_PROC_UDF)) {
51 : for (uint64_t index = 0; index < procArgs->envCnt; index++) {
52 : const std::string envName(procArgs->envParaList[index].envName, procArgs->envParaList[index].nameLen);
53 : const std::string envValue(
54 : procArgs->envParaList[index].envValue, procArgs->envParaList[index].valueLen);
55 : TSD_INFO("input envName:%s, envValue:%s", envName.c_str(), envValue.c_str());
56 : ctx.subProcEnvList.emplace_back(envName, envValue);
57 : }
58 : }
59 : for (uint64_t cnt = 0; cnt < procArgs->extParamCnt; cnt++) {
60 : const std::string extParam(procArgs->extParamList[cnt].paramInfo, procArgs->extParamList[cnt].paramLen);
61 : TSD_INFO(
62 : "cnt:%llu, extra parameters:%s, len:%llu", cnt, extParam.c_str(), procArgs->extParamList[cnt].paramLen);
63 : ctx.subProcExtParamList.push_back(extParam);
64 : }
65 : } catch (std::exception& e) {
66 : TSD_ERROR("input str is invalid reason:%s", e.what());
67 : return false;
68 : }
69 : return true;
70 : }
71 :
72 : TSD_StatusT SubProcessController::ConstructCommonOpenMsg(HDCMessage& hdcMsg, const ProcOpenArgs* procArgs) const
73 : {
74 : MessageContext ctx = tsdCtrl_.BuildBaseMessageContext();
75 : if (!SetCommonOpenParamList(ctx, procArgs)) {
76 : TSD_ERROR("input param is error, SetCommonOpenParamList failed");
77 : return TSD_INTERNAL_ERROR;
78 : }
79 :
80 : std::string runtimePkgPath;
81 : packageMgr_.GetAscendLatestIntallPath(runtimePkgPath);
82 : if (!runtimePkgPath.empty()) {
83 : ctx.ascendInstallPath = runtimePkgPath;
84 : TSD_RUN_INFO("runtimePkgPath:%s", runtimePkgPath.c_str());
85 : }
86 :
87 : if (procArgs->procType == SubProcType::TSD_SUB_PROC_HCCP) {
88 : ctx.withSubProcLogLevel = true;
89 : }
90 : return HdcMessageBuilder::BuildCommonOpen(hdcMsg, ctx);
91 : }
92 :
93 : TSD_StatusT SubProcessController::SendCommonOpenMsg(const ProcOpenArgs* procArgs)
94 : {
95 : HDCMessage hdcMsg;
96 : if (ConstructCommonOpenMsg(hdcMsg, procArgs) != TSD_OK) {
97 : TSD_ERROR("construct open msg error");
98 : return TSD_INTERNAL_ERROR;
99 : }
100 : const TSD_StatusT ret = commAgent_.SendMsg(hdcMsg);
101 : if (ret != TSD_OK) {
102 : TSD_ERROR("send msg to device error");
103 : return TSD_INTERNAL_ERROR;
104 : }
105 : return TSD_OK;
106 : }
107 :
108 : TSD_StatusT SubProcessController::OpenSubProc(ProcOpenArgs* openArgs)
109 : {
110 : if (openArgs == nullptr) {
111 : TSD_ERROR("openArgs is null");
112 : return TSD_INTERNAL_ERROR;
113 : }
114 : if (openArgs->subPid == nullptr) {
115 : TSD_ERROR("openArgs->subPid is null");
116 : return TSD_INTERNAL_ERROR;
117 : }
118 :
119 : TSD_RUN_INFO("enter into ProcessOpenSubProc subtype:%u", static_cast<uint32_t>(openArgs->procType));
120 : if (!capabilityMgr_.CheckSubProcSupported(static_cast<SubProcType>(openArgs->procType))) {
121 : TSD_ERROR("ProcessOpenSubProc versionCheck failed, subtype[%u]", static_cast<uint32_t>(openArgs->procType));
122 : return TSD_INTERNAL_ERROR;
123 : }
124 :
125 : auto ret = tsdCtrl_.InitTsdClient();
126 : TSD_CHECK(ret == TSD_OK, ret, "Init hdc client failed.");
127 :
128 : ret = SendCommonOpenMsg(openArgs);
129 : TSD_CHECK(ret == TSD_OK, ret, "SendCommonOpenMsg failed.");
130 :
131 : ret = tsdCtrl_.WaitRsp(0U);
132 : TSD_CHECK(ret == TSD_OK, ret, "wait heterogeneous open msg rsp failed.");
133 :
134 : *(openArgs->subPid) = static_cast<pid_t>(sharedCtx_.openSubPid);
135 : if (openArgs->procType == SubProcType::TSD_SUB_PROC_HCCP) {
136 : tsdCtrl_.SetStartedHccp(true);
137 : tsdCtrl_.SetHccpPid(sharedCtx_.openSubPid);
138 : }
139 : TSD_RUN_INFO(
140 : "OpenSubProc success type:%u, pid:%u", static_cast<uint32_t>(openArgs->procType), sharedCtx_.openSubPid);
141 : return TSD_OK;
142 : }
143 :
144 : TSD_StatusT SubProcessController::CloseSubProc(const pid_t closePid)
145 : {
146 : if (closePid <= 0) {
147 : TSD_ERROR("input param is error");
148 : return TSD_INTERNAL_ERROR;
149 : }
150 : if (!capabilityMgr_.IsSupportCommonInterface(TSD_SUPPORT_HS_AISERVER_FEATURE_BIT)) {
151 : TSD_ERROR("cur device does not support heterogeneous AIServer");
152 : return TSD_INTERNAL_ERROR;
153 : }
154 : TSD_RUN_INFO("enter into ProcessCloseSubProc subpid:%d", closePid);
155 : TSD_CHECK_NULLPTR(
156 : commAgent_.GetDeviceComm(), TSD_INSTANCE_NOT_INITIALED, "[TsdClient] devCommClient_ is null in Close function");
157 : HDCMessage msg;
158 : MessageContext ctx = tsdCtrl_.BuildBaseMessageContext();
159 : ctx.closeSubProcPid = static_cast<uint32_t>(closePid);
160 : const TSD_StatusT buildRet = HdcMessageBuilder::BuildCloseSubProc(msg, ctx);
161 : TSD_CHECK(buildRet == TSD_OK, buildRet, "build TSD_CLOSE_SUB_PROC msg failed.");
162 :
163 : if (tsdCtrl_.IsStartedHccp() && (static_cast<uint32_t>(closePid) == tsdCtrl_.GetHccpPid())) {
164 : tsdCtrl_.SetStartedHccp(false);
165 : tsdCtrl_.SetHccpPid(0);
166 : }
167 :
168 : TSD_StatusT ret = commAgent_.SendMsg(msg);
169 : if (ret != TSD_OK) {
170 : TSD_ERROR("[TsdClient][deviceId=%u] send remove msg to device error", sharedCtx_.logicDeviceId);
171 : return TSD_INTERNAL_ERROR;
172 : }
173 : ret = tsdCtrl_.WaitRsp(0U);
174 : TSD_CHECK(ret == TSD_OK, ret, "Wait open response from device failed.");
175 : TSD_RUN_INFO("leave ProcessCloseSubProc subpid:%u", closePid);
176 : return TSD_OK;
177 : }
178 :
179 : TSD_StatusT SubProcessController::GetSubProcStatus(ProcStatusInfo* pidInfo, const uint32_t arrayLen)
180 : {
181 : if ((pidInfo == nullptr) || (arrayLen == 0U)) {
182 : TSD_ERROR("input param is error");
183 : return TSD_INTERNAL_ERROR;
184 : }
185 :
186 : TSD_DEBUG("enter into GetSubProcStatus");
187 : TSD_CHECK_NULLPTR(
188 : commAgent_.GetDeviceComm(), TSD_INSTANCE_NOT_INITIALED, "[TsdClient] devCommClient_ is null in Close function");
189 : HDCMessage msg;
190 : MessageContext ctx = tsdCtrl_.BuildBaseMessageContext();
191 : ctx.subProcPidList.reserve(static_cast<size_t>(arrayLen));
192 : for (uint32_t index = 0; index < arrayLen; index++) {
193 : ctx.subProcPidList.push_back(static_cast<uint32_t>(pidInfo[index].pid));
194 : }
195 : const TSD_StatusT buildRet = HdcMessageBuilder::BuildGetSubProcStatus(msg, ctx);
196 : TSD_CHECK(buildRet == TSD_OK, buildRet, "build TSD_GET_SUB_PROC_STATUS msg failed.");
197 : const ScopeGuard closeFileGuard([this]() {
198 : sharedCtx_.pidArry = nullptr;
199 : sharedCtx_.pidArryLen = 0U;
200 : });
201 : sharedCtx_.pidArry = pidInfo;
202 : sharedCtx_.pidArryLen = arrayLen;
203 : TSD_StatusT ret = commAgent_.SendMsg(msg);
204 : TSD_CHECK(ret == TSD_OK, ret, "send GetSubProcStatus msg to device failed.");
205 : ret = tsdCtrl_.WaitRsp(0U);
206 : TSD_CHECK(ret == TSD_OK, ret, "Wait GetSubProcStatus response from device failed.");
207 : TSD_DEBUG("leave GetSubProcStatus");
208 : return TSD_OK;
209 : }
210 :
211 : TSD_StatusT SubProcessController::GetSubProcListStatus(ProcStatusParam* pidInfo, const uint32_t arrayLen)
212 : {
213 : if ((pidInfo == nullptr) || (arrayLen == 0U) || (arrayLen > MAX_PROCESS_PID_CNT)) {
214 : TSD_ERROR("input param is error");
215 : return TSD_INTERNAL_ERROR;
216 : }
217 :
218 : TSD_INFO("enter into GetSubProcListStatus");
219 : TSD_CHECK_NULLPTR(commAgent_.GetDeviceComm(), TSD_INSTANCE_NOT_INITIALED, "[TsdClient] devCommClient_ is null");
220 : HDCMessage msg;
221 : MessageContext ctx = tsdCtrl_.BuildBaseMessageContext();
222 : ctx.subProcPidList.reserve(static_cast<size_t>(arrayLen));
223 : ctx.subProcTypeList.reserve(static_cast<size_t>(arrayLen));
224 : for (uint32_t index = 0; index < arrayLen; index++) {
225 : ctx.subProcPidList.push_back(static_cast<uint32_t>(pidInfo[index].pid));
226 : ctx.subProcTypeList.push_back(static_cast<uint32_t>(pidInfo[index].procType));
227 : }
228 : const TSD_StatusT buildRet = HdcMessageBuilder::BuildGetSubProcStatus(msg, ctx);
229 : TSD_CHECK(buildRet == TSD_OK, buildRet, "build TSD_GET_SUB_PROC_STATUS msg failed.");
230 : const ScopeGuard closeFileGuard([this]() {
231 : sharedCtx_.pidList = nullptr;
232 : sharedCtx_.pidArryLen = 0U;
233 : });
234 : sharedCtx_.pidList = pidInfo;
235 : sharedCtx_.pidArryLen = arrayLen;
236 : TSD_StatusT ret = commAgent_.SendMsg(msg);
237 : TSD_CHECK(ret == TSD_OK, ret, "send GetSubProcListStatus msg to device failed.");
238 : ret = tsdCtrl_.WaitRsp(0U);
239 : TSD_CHECK(ret == TSD_OK, ret, "Wait GetSubProcListStatus response from device failed.");
240 : TSD_INFO("leave GetSubProcListStatus");
241 : return TSD_OK;
242 : }
243 :
244 : TSD_StatusT SubProcessController::RemoveFileOnDevice(const char_t* const filePath, const uint64_t pathLen)
245 : {
246 : if ((filePath == nullptr) || (pathLen == 0UL) || (pathLen >= 4096UL)) {
247 : TSD_ERROR("input param is error");
248 : return TSD_INTERNAL_ERROR;
249 : }
250 : try {
251 : const std::string dstPath(filePath, pathLen);
252 : TSD_RUN_INFO("input dstpath:%s", dstPath.c_str());
253 : if (!CheckValidatePath(dstPath)) {
254 : TSD_ERROR("dstPath[%s] is not correct", dstPath.c_str());
255 : return TSD_INTERNAL_ERROR;
256 : }
257 : if (dstPath.find("..") != std::string::npos) {
258 : TSD_ERROR("input path:%s is error", dstPath.c_str());
259 : return TSD_INTERNAL_ERROR;
260 : }
261 : } catch (std::exception& e) {
262 : TSD_ERROR("input fileName is invalid reason:%s", e.what());
263 : return TSD_INTERNAL_ERROR;
264 : }
265 : if (!capabilityMgr_.IsSupportCommonInterface(TSD_SUPPORT_HS_AISERVER_FEATURE_BIT)) {
266 : TSD_ERROR("cur device does not support heterogeneous AIServer");
267 : return TSD_INTERNAL_ERROR;
268 : }
269 : TSD_CHECK_NULLPTR(
270 : commAgent_.GetDeviceComm(), TSD_INSTANCE_NOT_INITIALED, "[TsdClient] devCommClient_ is null in Close function");
271 : HDCMessage msg;
272 : const std::string remvePath(filePath, pathLen);
273 : MessageContext ctx = tsdCtrl_.BuildBaseMessageContext();
274 : ctx.removeFilePath = remvePath;
275 : TSD_StatusT ret = HdcMessageBuilder::BuildRemoveFile(msg, ctx);
276 : TSD_CHECK(ret == TSD_OK, ret, "build TSD_REMOVE_FILE msg failed.");
277 : ret = commAgent_.SendMsg(msg);
278 : if (ret != TSD_OK) {
279 : TSD_ERROR("[TsdClient][deviceId=%u] send remove msg to device error", sharedCtx_.logicDeviceId);
280 : return TSD_INTERNAL_ERROR;
281 : }
282 : ret = tsdCtrl_.WaitRsp(0U);
283 : TSD_CHECK(ret == TSD_OK, ret, "Wait open response from device failed.");
284 : return TSD_OK;
285 : }
286 :
287 : TSD_StatusT SubProcessController::CloseSubProcList(const ProcStatusParam* closeList, const uint32_t listSize)
288 : {
289 : TSD_RUN_INFO(
290 : "enter ExecuteClosePidList cnt:%u, tsdSupportLevel_:%u", listSize, capabilityMgr_.GetTsdSupportLevel());
291 : if ((listSize > MAX_PROCESS_PID_CNT) || (listSize == 0U) || (closeList == nullptr)) {
292 : TSD_ERROR("pid list size invalid:%u", listSize);
293 : return TSD_INTERNAL_ERROR;
294 : }
295 : if (commAgent_.GetDeviceComm() == nullptr) {
296 : TSD_RUN_INFO("device comm client is null, skip close sub proc list");
297 : return TSD_HDC_CLIENT_CLOSED_EXTERNAL;
298 : }
299 : if (TSD_BITMAP_GET(capabilityMgr_.GetTsdSupportLevel(), TSD_SUPPORT_CLOSE_LIST_BIT) == 0U) {
300 : TSD_StatusT singleCloseRet = TSD_OK;
301 : for (uint32_t index = 0U; index < listSize; index++) {
302 : if (CloseSubProc(closeList[index].pid) != TSD_OK) {
303 : singleCloseRet = TSD_INTERNAL_ERROR;
304 : TSD_ERROR("close pid:%d failed", closeList[index].pid);
305 : }
306 : }
307 : return singleCloseRet;
308 : }
309 :
310 : const uint32_t loopCnt = listSize / CLOSE_PID_PER_LOOP;
311 : const uint32_t reserveCnt = listSize % CLOSE_PID_PER_LOOP;
312 : for (uint32_t cnt = 0U; cnt < loopCnt; cnt++) {
313 : if (ExecuteClosePidList(closeList, cnt * CLOSE_PID_PER_LOOP, CLOSE_PID_PER_LOOP) != TSD_OK) {
314 : TSD_ERROR("ExecuteClosePidList failed cnt:%u", cnt);
315 : return TSD_INTERNAL_ERROR;
316 : }
317 : TSD_RUN_INFO("ExecuteClosePidList success cnt:%u", cnt);
318 : }
319 :
320 8 : if (reserveCnt > 0U) {
321 7 : if (ExecuteClosePidList(closeList, loopCnt * CLOSE_PID_PER_LOOP, reserveCnt) != TSD_OK) {
322 3 : TSD_ERROR("ExecuteClosePidList failed reserveCnt:%u", reserveCnt);
323 3 : return TSD_INTERNAL_ERROR;
324 : }
325 4 : TSD_RUN_INFO("ExecuteClosePidList success reserveCnt:%u", reserveCnt);
326 : }
327 : return TSD_OK;
328 : }
329 :
330 : TSD_StatusT SubProcessController::ExecuteClosePidList(
331 : const ProcStatusParam* closeList, const uint32_t startIndex, const uint32_t pidCnt)
332 : {
333 : if ((closeList == nullptr) || (pidCnt == 0U) || (pidCnt > MAX_PROCESS_PID_CNT)) {
334 : TSD_ERROR("input param is error");
335 : return TSD_INTERNAL_ERROR;
336 : }
337 :
338 : TSD_CHECK_NULLPTR(commAgent_.GetDeviceComm(), TSD_INSTANCE_NOT_INITIALED, "[TsdClient] devCommClient_ is null");
339 : HDCMessage msg;
340 : MessageContext ctx = tsdCtrl_.BuildBaseMessageContext();
341 : ctx.subProcPidList.reserve(static_cast<size_t>(pidCnt));
342 : ctx.subProcTypeList.reserve(static_cast<size_t>(pidCnt));
343 : for (uint32_t index = 0U; index < pidCnt; index++) {
344 : const uint32_t curPid = static_cast<uint32_t>(closeList[index + startIndex].pid);
345 : const uint32_t curType = static_cast<uint32_t>(closeList[index + startIndex].procType);
346 : ctx.subProcPidList.push_back(curPid);
347 : ctx.subProcTypeList.push_back(curType);
348 : TSD_INFO("add close subproc:%d, proctype:%u", closeList[index + startIndex].pid, curType);
349 : if (tsdCtrl_.IsStartedHccp() && (closeList[index + startIndex].procType == SubProcType::TSD_SUB_PROC_HCCP) &&
350 : (curPid == tsdCtrl_.GetHccpPid())) {
351 : tsdCtrl_.SetStartedHccp(false);
352 : tsdCtrl_.SetHccpPid(0);
353 : }
354 : }
355 : const TSD_StatusT buildRet = HdcMessageBuilder::BuildCloseSubProcList(msg, ctx);
356 : TSD_CHECK(buildRet == TSD_OK, buildRet, "build TSD_CLOSE_SUB_PROC_LIST msg failed.");
357 : TSD_StatusT ret = commAgent_.SendMsg(msg);
358 : if (ret != TSD_OK) {
359 : TSD_ERROR("[TsdClient][deviceId=%u] send close pid array msg to device error", sharedCtx_.logicDeviceId);
360 : return TSD_INTERNAL_ERROR;
361 : }
362 : ret = tsdCtrl_.WaitRsp(0U);
363 : TSD_CHECK(ret == TSD_OK, ret, "Wait close pid array response from device failed.");
364 : TSD_RUN_INFO("leave ExecuteClosePidList startindex:%u, cnt:%u", startIndex, pidCnt);
365 : return TSD_OK;
366 : }
367 :
368 : } // namespace tsd
|