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 365 : SubProcessController::SubProcessController(
27 : TsdProcessController& tsdCtrl, DeviceCommAgent& commAgent, CapabilityManager& capabilityMgr,
28 365 : PackageManager& packageMgr, ProcessSharedContext& sharedCtx)
29 365 : : tsdCtrl_(tsdCtrl),
30 365 : commAgent_(commAgent),
31 365 : capabilityMgr_(capabilityMgr),
32 365 : packageMgr_(packageMgr),
33 365 : sharedCtx_(sharedCtx)
34 365 : {}
35 :
36 14 : bool SubProcessController::SetCommonOpenParamList(MessageContext& ctx, const ProcOpenArgs* const procArgs) const
37 : {
38 14 : 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 13 : ctx.subProcOpenType = static_cast<uint32_t>(procArgs->procType);
44 13 : if ((procArgs->filePath != nullptr) && (procArgs->pathLen != 0)) {
45 6 : const std::string filePath(procArgs->filePath, procArgs->pathLen);
46 6 : ctx.hasSubProcFilePath = true;
47 6 : ctx.subProcFilePath = filePath;
48 6 : TSD_INFO("filePath:%s", filePath.c_str());
49 6 : }
50 13 : if ((procArgs->procType == TSD_SUB_PROC_BUILTIN_UDF) || (procArgs->procType == TSD_SUB_PROC_UDF)) {
51 12 : for (uint64_t index = 0; index < procArgs->envCnt; index++) {
52 12 : const std::string envName(procArgs->envParaList[index].envName, procArgs->envParaList[index].nameLen);
53 : const std::string envValue(
54 6 : procArgs->envParaList[index].envValue, procArgs->envParaList[index].valueLen);
55 6 : TSD_INFO("input envName:%s, envValue:%s", envName.c_str(), envValue.c_str());
56 6 : ctx.subProcEnvList.emplace_back(envName, envValue);
57 6 : }
58 : }
59 22 : for (uint64_t cnt = 0; cnt < procArgs->extParamCnt; cnt++) {
60 9 : const std::string extParam(procArgs->extParamList[cnt].paramInfo, procArgs->extParamList[cnt].paramLen);
61 9 : TSD_INFO(
62 : "cnt:%llu, extra parameters:%s, len:%llu", cnt, extParam.c_str(), procArgs->extParamList[cnt].paramLen);
63 9 : ctx.subProcExtParamList.push_back(extParam);
64 9 : }
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 13 : return true;
70 : }
71 :
72 11 : TSD_StatusT SubProcessController::ConstructCommonOpenMsg(HDCMessage& hdcMsg, const ProcOpenArgs* procArgs) const
73 : {
74 11 : MessageContext ctx = tsdCtrl_.BuildBaseMessageContext();
75 11 : if (!SetCommonOpenParamList(ctx, procArgs)) {
76 1 : TSD_ERROR("input param is error, SetCommonOpenParamList failed");
77 1 : return TSD_INTERNAL_ERROR;
78 : }
79 :
80 10 : std::string runtimePkgPath;
81 10 : packageMgr_.GetAscendLatestIntallPath(runtimePkgPath);
82 10 : if (!runtimePkgPath.empty()) {
83 10 : ctx.ascendInstallPath = runtimePkgPath;
84 10 : TSD_RUN_INFO("runtimePkgPath:%s", runtimePkgPath.c_str());
85 : }
86 :
87 10 : if (procArgs->procType == SubProcType::TSD_SUB_PROC_HCCP) {
88 4 : ctx.withSubProcLogLevel = true;
89 : }
90 10 : return HdcMessageBuilder::BuildCommonOpen(hdcMsg, ctx);
91 11 : }
92 :
93 9 : TSD_StatusT SubProcessController::SendCommonOpenMsg(const ProcOpenArgs* procArgs)
94 : {
95 9 : HDCMessage hdcMsg;
96 9 : if (ConstructCommonOpenMsg(hdcMsg, procArgs) != TSD_OK) {
97 0 : TSD_ERROR("construct open msg error");
98 0 : return TSD_INTERNAL_ERROR;
99 : }
100 9 : const TSD_StatusT ret = commAgent_.SendMsg(hdcMsg);
101 9 : if (ret != TSD_OK) {
102 0 : TSD_ERROR("send msg to device error");
103 0 : return TSD_INTERNAL_ERROR;
104 : }
105 9 : return TSD_OK;
106 9 : }
107 :
108 16 : TSD_StatusT SubProcessController::OpenSubProc(ProcOpenArgs* openArgs)
109 : {
110 16 : if (openArgs == nullptr) {
111 2 : TSD_ERROR("openArgs is null");
112 2 : return TSD_INTERNAL_ERROR;
113 : }
114 14 : if (openArgs->subPid == nullptr) {
115 2 : TSD_ERROR("openArgs->subPid is null");
116 2 : return TSD_INTERNAL_ERROR;
117 : }
118 :
119 12 : TSD_RUN_INFO("enter into ProcessOpenSubProc subtype:%u", static_cast<uint32_t>(openArgs->procType));
120 12 : 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 11 : auto ret = tsdCtrl_.InitTsdClient();
126 11 : TSD_CHECK(ret == TSD_OK, ret, "Init hdc client failed.");
127 :
128 11 : ret = SendCommonOpenMsg(openArgs);
129 11 : TSD_CHECK(ret == TSD_OK, ret, "SendCommonOpenMsg failed.");
130 :
131 11 : ret = tsdCtrl_.WaitRsp(0U);
132 11 : TSD_CHECK(ret == TSD_OK, ret, "wait heterogeneous open msg rsp failed.");
133 :
134 11 : *(openArgs->subPid) = static_cast<pid_t>(sharedCtx_.openSubPid);
135 11 : if (openArgs->procType == SubProcType::TSD_SUB_PROC_HCCP) {
136 5 : tsdCtrl_.SetStartedHccp(true);
137 5 : tsdCtrl_.SetHccpPid(sharedCtx_.openSubPid);
138 : }
139 11 : TSD_RUN_INFO(
140 : "OpenSubProc success type:%u, pid:%u", static_cast<uint32_t>(openArgs->procType), sharedCtx_.openSubPid);
141 11 : return TSD_OK;
142 : }
143 :
144 6 : TSD_StatusT SubProcessController::CloseSubProc(const pid_t closePid)
145 : {
146 6 : if (closePid <= 0) {
147 2 : TSD_ERROR("input param is error");
148 2 : return TSD_INTERNAL_ERROR;
149 : }
150 4 : 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 4 : TSD_RUN_INFO("enter into ProcessCloseSubProc subpid:%d", closePid);
155 4 : TSD_CHECK_NULLPTR(
156 : commAgent_.GetDeviceComm(), TSD_INSTANCE_NOT_INITIALED, "[TsdClient] devCommClient_ is null in Close function");
157 4 : HDCMessage msg;
158 4 : MessageContext ctx = tsdCtrl_.BuildBaseMessageContext();
159 4 : ctx.closeSubProcPid = static_cast<uint32_t>(closePid);
160 4 : const TSD_StatusT buildRet = HdcMessageBuilder::BuildCloseSubProc(msg, ctx);
161 4 : TSD_CHECK(buildRet == TSD_OK, buildRet, "build TSD_CLOSE_SUB_PROC msg failed.");
162 :
163 4 : if (tsdCtrl_.IsStartedHccp() && (static_cast<uint32_t>(closePid) == tsdCtrl_.GetHccpPid())) {
164 1 : tsdCtrl_.SetStartedHccp(false);
165 1 : tsdCtrl_.SetHccpPid(0);
166 : }
167 :
168 4 : TSD_StatusT ret = commAgent_.SendMsg(msg);
169 4 : 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 4 : ret = tsdCtrl_.WaitRsp(0U);
174 4 : TSD_CHECK(ret == TSD_OK, ret, "Wait open response from device failed.");
175 4 : TSD_RUN_INFO("leave ProcessCloseSubProc subpid:%u", closePid);
176 4 : return TSD_OK;
177 4 : }
178 :
179 3 : TSD_StatusT SubProcessController::GetSubProcStatus(ProcStatusInfo* pidInfo, const uint32_t arrayLen)
180 : {
181 3 : if ((pidInfo == nullptr) || (arrayLen == 0U)) {
182 1 : TSD_ERROR("input param is error");
183 1 : return TSD_INTERNAL_ERROR;
184 : }
185 :
186 2 : TSD_DEBUG("enter into GetSubProcStatus");
187 2 : TSD_CHECK_NULLPTR(
188 : commAgent_.GetDeviceComm(), TSD_INSTANCE_NOT_INITIALED, "[TsdClient] devCommClient_ is null in Close function");
189 1 : HDCMessage msg;
190 1 : MessageContext ctx = tsdCtrl_.BuildBaseMessageContext();
191 1 : ctx.subProcPidList.reserve(static_cast<size_t>(arrayLen));
192 2 : for (uint32_t index = 0; index < arrayLen; index++) {
193 1 : ctx.subProcPidList.push_back(static_cast<uint32_t>(pidInfo[index].pid));
194 : }
195 1 : const TSD_StatusT buildRet = HdcMessageBuilder::BuildGetSubProcStatus(msg, ctx);
196 1 : TSD_CHECK(buildRet == TSD_OK, buildRet, "build TSD_GET_SUB_PROC_STATUS msg failed.");
197 0 : const ScopeGuard closeFileGuard([this]() {
198 1 : sharedCtx_.pidArry = nullptr;
199 1 : sharedCtx_.pidArryLen = 0U;
200 1 : });
201 1 : sharedCtx_.pidArry = pidInfo;
202 1 : sharedCtx_.pidArryLen = arrayLen;
203 1 : TSD_StatusT ret = commAgent_.SendMsg(msg);
204 1 : TSD_CHECK(ret == TSD_OK, ret, "send GetSubProcStatus msg to device failed.");
205 1 : ret = tsdCtrl_.WaitRsp(0U);
206 1 : TSD_CHECK(ret == TSD_OK, ret, "Wait GetSubProcStatus response from device failed.");
207 1 : TSD_DEBUG("leave GetSubProcStatus");
208 1 : return TSD_OK;
209 1 : }
210 :
211 2 : TSD_StatusT SubProcessController::GetSubProcListStatus(ProcStatusParam* pidInfo, const uint32_t arrayLen)
212 : {
213 2 : 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 2 : TSD_INFO("enter into GetSubProcListStatus");
219 2 : TSD_CHECK_NULLPTR(commAgent_.GetDeviceComm(), TSD_INSTANCE_NOT_INITIALED, "[TsdClient] devCommClient_ is null");
220 2 : HDCMessage msg;
221 2 : MessageContext ctx = tsdCtrl_.BuildBaseMessageContext();
222 2 : ctx.subProcPidList.reserve(static_cast<size_t>(arrayLen));
223 2 : ctx.subProcTypeList.reserve(static_cast<size_t>(arrayLen));
224 5 : for (uint32_t index = 0; index < arrayLen; index++) {
225 3 : ctx.subProcPidList.push_back(static_cast<uint32_t>(pidInfo[index].pid));
226 3 : ctx.subProcTypeList.push_back(static_cast<uint32_t>(pidInfo[index].procType));
227 : }
228 2 : const TSD_StatusT buildRet = HdcMessageBuilder::BuildGetSubProcStatus(msg, ctx);
229 2 : TSD_CHECK(buildRet == TSD_OK, buildRet, "build TSD_GET_SUB_PROC_STATUS msg failed.");
230 0 : const ScopeGuard closeFileGuard([this]() {
231 2 : sharedCtx_.pidList = nullptr;
232 2 : sharedCtx_.pidArryLen = 0U;
233 2 : });
234 2 : sharedCtx_.pidList = pidInfo;
235 2 : sharedCtx_.pidArryLen = arrayLen;
236 2 : TSD_StatusT ret = commAgent_.SendMsg(msg);
237 2 : TSD_CHECK(ret == TSD_OK, ret, "send GetSubProcListStatus msg to device failed.");
238 2 : ret = tsdCtrl_.WaitRsp(0U);
239 2 : TSD_CHECK(ret == TSD_OK, ret, "Wait GetSubProcListStatus response from device failed.");
240 2 : TSD_INFO("leave GetSubProcListStatus");
241 2 : return TSD_OK;
242 2 : }
243 :
244 4 : TSD_StatusT SubProcessController::RemoveFileOnDevice(const char_t* const filePath, const uint64_t pathLen)
245 : {
246 4 : 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 3 : const std::string dstPath(filePath, pathLen);
252 3 : TSD_RUN_INFO("input dstpath:%s", dstPath.c_str());
253 3 : if (!CheckValidatePath(dstPath)) {
254 0 : TSD_ERROR("dstPath[%s] is not correct", dstPath.c_str());
255 0 : return TSD_INTERNAL_ERROR;
256 : }
257 3 : 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 3 : } 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 3 : 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 2 : TSD_CHECK_NULLPTR(
270 : commAgent_.GetDeviceComm(), TSD_INSTANCE_NOT_INITIALED, "[TsdClient] devCommClient_ is null in Close function");
271 2 : HDCMessage msg;
272 2 : const std::string remvePath(filePath, pathLen);
273 2 : MessageContext ctx = tsdCtrl_.BuildBaseMessageContext();
274 2 : ctx.removeFilePath = remvePath;
275 2 : TSD_StatusT ret = HdcMessageBuilder::BuildRemoveFile(msg, ctx);
276 2 : TSD_CHECK(ret == TSD_OK, ret, "build TSD_REMOVE_FILE msg failed.");
277 2 : ret = commAgent_.SendMsg(msg);
278 2 : 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 2 : ret = tsdCtrl_.WaitRsp(0U);
283 2 : TSD_CHECK(ret == TSD_OK, ret, "Wait open response from device failed.");
284 2 : return TSD_OK;
285 2 : }
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) == 0U) {
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 9 : 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 0 : TSD_ERROR("ExecuteClosePidList failed cnt:%u", cnt);
315 0 : return TSD_INTERNAL_ERROR;
316 : }
317 2 : TSD_RUN_INFO("ExecuteClosePidList success cnt:%u", cnt);
318 : }
319 :
320 7 : if (ExecuteClosePidList(closeList, loopCnt * CLOSE_PID_PER_LOOP, reserveCnt) != TSD_OK) {
321 3 : TSD_ERROR("ExecuteClosePidList failed reserveCnt:%u", reserveCnt);
322 3 : return TSD_INTERNAL_ERROR;
323 : }
324 4 : TSD_RUN_INFO("ExecuteClosePidList success reserveCnt:%u", reserveCnt);
325 4 : return TSD_OK;
326 : }
327 :
328 9 : TSD_StatusT SubProcessController::ExecuteClosePidList(
329 : const ProcStatusParam* closeList, const uint32_t startIndex, const uint32_t pidCnt)
330 : {
331 9 : 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 9 : TSD_CHECK_NULLPTR(commAgent_.GetDeviceComm(), TSD_INSTANCE_NOT_INITIALED, "[TsdClient] devCommClient_ is null");
337 9 : HDCMessage msg;
338 9 : MessageContext ctx = tsdCtrl_.BuildBaseMessageContext();
339 9 : ctx.subProcPidList.reserve(static_cast<size_t>(pidCnt));
340 9 : ctx.subProcTypeList.reserve(static_cast<size_t>(pidCnt));
341 118 : for (uint32_t index = 0U; index < pidCnt; index++) {
342 109 : const uint32_t curPid = static_cast<uint32_t>(closeList[index + startIndex].pid);
343 109 : const uint32_t curType = static_cast<uint32_t>(closeList[index + startIndex].procType);
344 109 : ctx.subProcPidList.push_back(curPid);
345 109 : ctx.subProcTypeList.push_back(curType);
346 109 : TSD_INFO("add close subproc:%d, proctype:%u", closeList[index + startIndex].pid, curType);
347 112 : if (tsdCtrl_.IsStartedHccp() && (closeList[index + startIndex].procType == SubProcType::TSD_SUB_PROC_HCCP) &&
348 3 : (curPid == tsdCtrl_.GetHccpPid())) {
349 3 : tsdCtrl_.SetStartedHccp(false);
350 3 : tsdCtrl_.SetHccpPid(0);
351 : }
352 : }
353 9 : const TSD_StatusT buildRet = HdcMessageBuilder::BuildCloseSubProcList(msg, ctx);
354 9 : TSD_CHECK(buildRet == TSD_OK, buildRet, "build TSD_CLOSE_SUB_PROC_LIST msg failed.");
355 9 : TSD_StatusT ret = commAgent_.SendMsg(msg);
356 9 : if (ret != TSD_OK) {
357 1 : TSD_ERROR("[TsdClient][deviceId=%u] send close pid array msg to device error", sharedCtx_.logicDeviceId);
358 1 : return TSD_INTERNAL_ERROR;
359 : }
360 8 : ret = tsdCtrl_.WaitRsp(0U);
361 8 : TSD_CHECK(ret == TSD_OK, ret, "Wait close pid array response from device failed.");
362 6 : TSD_RUN_INFO("leave ExecuteClosePidList startindex:%u, cnt:%u", startIndex, pidCnt);
363 6 : return TSD_OK;
364 9 : }
365 :
366 : } // namespace tsd
|