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