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 "package_check_code_service.h"
12 : #include "package_manager.h"
13 : #include "tsd_log.h"
14 : #include "tsd/status.h"
15 : #include "tsd_scope_guard.h"
16 : #include "tsd_util_func.h"
17 : #include "env_internal_api.h"
18 :
19 : namespace tsd {
20 :
21 : namespace {
22 : constexpr uint32_t HELPER_PKG_LOAD_TIMEOUT = 10000U;
23 : constexpr uint32_t DRIVER_EXTEND_MAX_PROCESS_TIME = 140U;
24 :
25 : struct CheckCodeRspHandler {
26 : HDCMessage::MsgType msgType;
27 : void (*handle)(tsd::PackageCheckCodeService& svc, const HDCMessage& msg);
28 : };
29 :
30 2 : void HandleSingleCheckCodeRsp(tsd::PackageCheckCodeService& svc, const HDCMessage& msg, tsd::TsdLoadPackageType pkgType)
31 : {
32 2 : svc.peerCheckCode_[static_cast<uint32_t>(pkgType)] = msg.check_code();
33 2 : svc.pkgRspCode_ = ((msg.tsd_rsp_code() == 0U) ? tsd::ResponseCode::SUCCESS : tsd::ResponseCode::FAIL);
34 2 : }
35 :
36 1 : void HandleRuntimeCheckCodeRsp(tsd::PackageCheckCodeService& svc, const HDCMessage& msg)
37 : {
38 1 : HandleSingleCheckCodeRsp(svc, msg, tsd::TsdLoadPackageType::TSD_PKG_TYPE_RUNTIME);
39 1 : }
40 :
41 1 : void HandleDshapeCheckCodeRsp(tsd::PackageCheckCodeService& svc, const HDCMessage& msg)
42 : {
43 1 : HandleSingleCheckCodeRsp(svc, msg, tsd::TsdLoadPackageType::TSD_PKG_TYPE_DSHAPE);
44 1 : }
45 :
46 3 : void HandleMultiCheckCodeRsp(tsd::PackageCheckCodeService& svc, const HDCMessage& msg)
47 : {
48 3 : svc.peerCheckCode_[static_cast<uint32_t>(tsd::TsdLoadPackageType::TSD_PKG_TYPE_AICPU_KERNEL)] = msg.check_code();
49 3 : svc.peerCheckCode_[static_cast<uint32_t>(tsd::TsdLoadPackageType::TSD_PKG_TYPE_AICPU_EXTEND_KERNEL)] =
50 3 : msg.extendpkg_check_code();
51 3 : svc.peerCheckCode_[static_cast<uint32_t>(tsd::TsdLoadPackageType::TSD_PKG_TYPE_ASCENDCPP)] =
52 3 : msg.ascendcpppkg_check_code();
53 3 : }
54 :
55 : const CheckCodeRspHandler CHECK_CODE_RSP_HANDLERS[] = {
56 : {HDCMessage::TSD_GET_DEVICE_RUNTIME_CHECKCODE_RSP, HandleRuntimeCheckCodeRsp},
57 : {HDCMessage::TSD_GET_DEVICE_DSHAPE_CHECKCODE_RSP, HandleDshapeCheckCodeRsp},
58 : {HDCMessage::TSD_CHECK_PACKAGE_RETRY_RSP, HandleMultiCheckCodeRsp},
59 : {HDCMessage::TSD_CHECK_PACKAGE_RSP, HandleMultiCheckCodeRsp},
60 : };
61 : } // namespace
62 :
63 263 : PackageCheckCodeService::PackageCheckCodeService(
64 : PackageManager& mgr, DeviceCommAgent& commAgent, CapabilityManager& capabilityMgr, PackageEnvInfo& envInfo,
65 : PackageHashStore& hashStore, ResponseCode& pkgRspCode, bool& getCheckCodeRetrySupport,
66 263 : std::string& loadPackageErrorMsg)
67 263 : : mgr_(mgr),
68 263 : commAgent_(commAgent),
69 263 : capabilityMgr_(capabilityMgr),
70 263 : envInfo_(envInfo),
71 263 : hashStore_(hashStore),
72 263 : pkgRspCode_(pkgRspCode),
73 263 : getCheckCodeRetrySupport_(getCheckCodeRetrySupport),
74 263 : loadPackageErrorMsg_(loadPackageErrorMsg)
75 : {
76 8679 : for (uint32_t index = 0U; index < static_cast<uint32_t>(TsdLoadPackageType::TSD_PKG_TYPE_MAX); index++) {
77 8416 : peerCheckCode_[index] = 0U;
78 8416 : hostCheckCode_[index] = 0U;
79 : }
80 263 : }
81 :
82 12 : TSD_StatusT PackageCheckCodeService::InitTsdClient()
83 : {
84 12 : if (commAgent_.IsInit()) {
85 10 : TSD_INFO("[TsdClient] tsd client has already been initialized");
86 10 : return TSD_OK;
87 : }
88 2 : return commAgent_.InitTsdClient(envInfo_.IsAdcEnv());
89 : }
90 :
91 1 : TSD_StatusT PackageCheckCodeService::WaitPkgRsp(const uint32_t timeout, const bool ignoreRecvErr)
92 : {
93 1 : const TSD_StatusT ret = commAgent_.RecvData(ignoreRecvErr, timeout);
94 1 : if ((ret != TSD_OK) || (static_cast<uint32_t>(pkgRspCode_) != 0U)) {
95 1 : if (!ignoreRecvErr) {
96 1 : TSD_ERROR(
97 : "tsd package wait response fail, ret[%u], rspCode[%u]", static_cast<uint32_t>(ret),
98 : static_cast<uint32_t>(pkgRspCode_));
99 : }
100 1 : return TSD_INTERNAL_ERROR;
101 : }
102 0 : return TSD_OK;
103 : }
104 :
105 4 : TSD_StatusT PackageCheckCodeService::GetDeviceCheckCodeOnce(const HDCMessage& msg)
106 : {
107 4 : auto ret = commAgent_.SendMsg(msg);
108 4 : if (ret != TSD_OK) {
109 1 : TSD_ERROR("Send check_code search message failed.");
110 1 : return ret;
111 : }
112 :
113 3 : TSD_RUN_INFO(
114 : "[TsdClient][deviceId=%u] [sessionId=%u] wait package info response", envInfo_.GetLogicDeviceId(),
115 : commAgent_.GetSessionId());
116 3 : ret = commAgent_.RecvData();
117 3 : if (ret != TSD_OK) {
118 3 : TSD_RUN_INFO("not receive TSD_CHECK_PACKAGE rsp msg, just send pkg to server");
119 : }
120 3 : return TSD_OK;
121 : }
122 :
123 15 : TSD_StatusT PackageCheckCodeService::PrepareForCheckCode()
124 : {
125 15 : const TSD_StatusT ret = mgr_.InitTsdClient();
126 15 : if (ret != TSD_OK) {
127 3 : TSD_RUN_WARN("[PackageManager][deviceId=%u] init failed for send aicpu package", envInfo_.GetLogicDeviceId());
128 3 : if (ret >= TSD_SUBPROCESS_NUM_EXCEED_THE_LIMIT) {
129 1 : return ret;
130 : }
131 2 : return TSD_HDC_CREATE_SESSION_FAILED;
132 : }
133 12 : TSD_CHECK_NULLPTR(
134 : commAgent_.GetDeviceComm(), TSD_INSTANCE_NOT_FOUND, "[PackageManager] devCommClient_ is null in Open function");
135 11 : return TSD_OK;
136 : }
137 :
138 9 : TSD_StatusT PackageCheckCodeService::GetDeviceCheckCode()
139 : {
140 9 : if (mgr_.aicpuPackageExistInDevice_) {
141 2 : TSD_RUN_INFO(
142 : "[PackageManager][deviceId=%u] aicpu package already exist in device", envInfo_.GetLogicDeviceId());
143 2 : return TSD_AICPUPACKAGE_EXISTED;
144 : }
145 :
146 7 : TSD_StatusT ret = mgr_.PrepareForCheckCode();
147 7 : if (ret != TSD_OK) {
148 0 : return ret;
149 : }
150 14 : const ScopeGuard destroySessionGuard([this]() { this->commAgent_.ReleaseDeviceConnection(); });
151 :
152 7 : std::shared_ptr<VersionVerify> versionVerify = nullptr;
153 7 : (void)commAgent_.GetVersionVerify(versionVerify);
154 7 : TSD_CHECK_NULLPTR(versionVerify, TSD_INTERNAL_ERROR, "no VersionVerify available.");
155 :
156 7 : if (!versionVerify->SpecialFeatureCheck(HDCMessage::TSD_CHECK_PACKAGE)) {
157 1 : TSD_RUN_INFO("[TsdClient] Device does not support search check_code before send aicpu package.");
158 1 : mgr_.aicpuPackageExistInDevice_ = true;
159 1 : return TSD_OK;
160 : }
161 :
162 6 : MessageContext ctx{};
163 6 : ctx.logicDeviceId = envInfo_.GetLogicDeviceId();
164 6 : ctx.asan = IsAsanMmSysEnv();
165 6 : ctx.checkCode = hostCheckCode_[static_cast<uint32_t>(TsdLoadPackageType::TSD_PKG_TYPE_AICPU_KERNEL)];
166 6 : ctx.extendpkgCheckCode =
167 6 : hostCheckCode_[static_cast<uint32_t>(TsdLoadPackageType::TSD_PKG_TYPE_AICPU_EXTEND_KERNEL)];
168 6 : ctx.ascendcppCheckCode = hostCheckCode_[static_cast<uint32_t>(TsdLoadPackageType::TSD_PKG_TYPE_ASCENDCPP)];
169 6 : HDCMessage msg;
170 6 : if (HdcMessageBuilder::BuildCheckPackage(msg, ctx) != TSD_OK) {
171 0 : TSD_ERROR("build check package msg failed");
172 0 : return TSD_INTERNAL_ERROR;
173 : }
174 6 : SetHostCheckCode(msg, TsdLoadPackageType::TSD_PKG_TYPE_AICPU_KERNEL);
175 6 : SetHostCheckCode(msg, TsdLoadPackageType::TSD_PKG_TYPE_AICPU_EXTEND_KERNEL);
176 6 : SetHostCheckCode(msg, TsdLoadPackageType::TSD_PKG_TYPE_ASCENDCPP);
177 6 : if (mgr_.GetDeviceCheckCodeOnce(msg) != TSD_OK) {
178 3 : TSD_ERROR("get check code once failed.");
179 3 : return TSD_INTERNAL_ERROR;
180 : }
181 3 : mgr_.GetDeviceCheckCodeRetrySupport();
182 :
183 3 : mgr_.aicpuPackageExistInDevice_ = true;
184 :
185 3 : return TSD_OK;
186 7 : }
187 :
188 5 : void PackageCheckCodeService::GetDeviceCheckCodeRetrySupport()
189 : {
190 5 : std::shared_ptr<VersionVerify> versionVerify = nullptr;
191 5 : (void)commAgent_.GetVersionVerify(versionVerify);
192 5 : if (versionVerify == nullptr) {
193 2 : TSD_ERROR("no VersionVerify available.");
194 2 : return;
195 : }
196 3 : getCheckCodeRetrySupport_ = versionVerify->SpecialFeatureCheck(HDCMessage::TSD_CHECK_PACKAGE_RETRY);
197 5 : }
198 :
199 8 : TSD_StatusT PackageCheckCodeService::GetDeviceCheckCodeRetry(const HDCMessage& msg)
200 : {
201 8 : TSD_StatusT ret = mgr_.PrepareForCheckCode();
202 8 : if (ret != TSD_OK) {
203 4 : return ret;
204 : }
205 8 : const ScopeGuard destroySessionGuard([this]() { this->commAgent_.ReleaseDeviceConnection(); });
206 4 : if (mgr_.GetDeviceCheckCodeOnce(msg) != TSD_OK) {
207 2 : TSD_ERROR("get check code once failed.");
208 2 : return TSD_INTERNAL_ERROR;
209 : }
210 2 : return TSD_OK;
211 4 : }
212 :
213 18 : void PackageCheckCodeService::SetHostCheckCode(HDCMessage& msg, TsdLoadPackageType type)
214 : {
215 18 : const uint32_t packageType = static_cast<uint32_t>(type);
216 18 : if (envInfo_.packageName_[packageType].empty()) {
217 17 : return;
218 : }
219 1 : const std::string orgFile = envInfo_.packagePath_[packageType] + envInfo_.packageName_[packageType];
220 1 : hostCheckCode_[packageType] = CalFileSize(orgFile.c_str());
221 1 : switch (type) {
222 0 : case TsdLoadPackageType::TSD_PKG_TYPE_AICPU_KERNEL:
223 0 : msg.set_check_code(hostCheckCode_[packageType]);
224 0 : break;
225 1 : case TsdLoadPackageType::TSD_PKG_TYPE_AICPU_EXTEND_KERNEL:
226 1 : msg.set_extendpkg_check_code(hostCheckCode_[packageType]);
227 1 : break;
228 0 : case TsdLoadPackageType::TSD_PKG_TYPE_ASCENDCPP:
229 0 : msg.set_ascendcpppkg_check_code(hostCheckCode_[packageType]);
230 0 : break;
231 0 : default:
232 0 : break;
233 : }
234 1 : }
235 :
236 6 : TSD_StatusT PackageCheckCodeService::GetDeviceHsPkgCheckCode(
237 : const uint32_t checkCode, const HDCMessage::MsgType msgType, const bool beforeSendFlag,
238 : const MessageContext& baseCtx)
239 : {
240 6 : TSD_StatusT ret = mgr_.InitTsdClient();
241 6 : if (ret != TSD_OK) {
242 0 : TSD_ERROR("InitTsdClient failed");
243 0 : return TSD_INTERNAL_ERROR;
244 : }
245 6 : HDCMessage msg;
246 6 : MessageContext ctx = baseCtx;
247 6 : ctx.msgType = static_cast<uint32_t>(msgType);
248 6 : ctx.checkCode = checkCode;
249 6 : ctx.beforeSendPkg = beforeSendFlag;
250 6 : if (HdcMessageBuilder::BuildPackageCheckCode(msg, ctx) != TSD_OK) {
251 0 : TSD_ERROR("build package check code msg failed");
252 0 : return TSD_INTERNAL_ERROR;
253 : }
254 6 : ret = commAgent_.SendMsg(msg);
255 6 : if (ret != TSD_OK) {
256 2 : TSD_ERROR("Send runtime checkcode failed msgtype:%u.", static_cast<uint32_t>(msgType));
257 2 : commAgent_.ReleaseDeviceConnection();
258 2 : return TSD_INTERNAL_ERROR;
259 : }
260 4 : TSD_RUN_INFO(
261 : "[TsdClient][deviceId=%u] [sessionId=%u] wait package info response msgType:%u", envInfo_.GetLogicDeviceId(),
262 : commAgent_.GetSessionId(), static_cast<uint32_t>(msgType));
263 4 : ret = mgr_.WaitPkgRsp(HELPER_PKG_LOAD_TIMEOUT);
264 4 : if (ret != TSD_OK) {
265 0 : if (beforeSendFlag) {
266 0 : TSD_RUN_INFO("not receive TSD_CHECK_PACKAGE rsp msg, just send pkg to server");
267 : } else {
268 0 : TSD_ERROR("not receive TSD_CHECK_PACKAGE failed Msgtype:%u", static_cast<uint32_t>(msgType));
269 0 : return TSD_INTERNAL_ERROR;
270 : }
271 : }
272 4 : TSD_RUN_INFO("GetDeviceHsPkgCheckCode success Msgtype:%u", static_cast<uint32_t>(msgType));
273 4 : return TSD_OK;
274 6 : }
275 :
276 6 : TSD_StatusT PackageCheckCodeService::GetCannHsPkgCheckCode(
277 : const std::string& pkgPureName, const std::string& hostPkgHash, const MessageContext& baseCtx)
278 : {
279 6 : TSD_StatusT ret = mgr_.InitTsdClient();
280 6 : if (ret != TSD_OK) {
281 1 : TSD_ERROR("InitTsdClient failed");
282 1 : return TSD_INTERNAL_ERROR;
283 : }
284 :
285 5 : HDCMessage msg;
286 5 : MessageContext ctx = baseCtx;
287 5 : ctx.packageMaxProcessTime = DRIVER_EXTEND_MAX_PROCESS_TIME;
288 5 : ctx.packageWorkerType = static_cast<uint32_t>(PackageWorkerType::PACKAGE_WORKER_COMMON_SINK);
289 5 : ctx.packageType = static_cast<uint32_t>(TsdLoadPackageType::TSD_PKG_TYPE_COMMON_SINK);
290 5 : ctx.packageName = pkgPureName;
291 5 : ctx.hashCode = hostPkgHash;
292 5 : if (HdcMessageBuilder::BuildCannHsCheckCode(msg, ctx) != TSD_OK) {
293 0 : TSD_ERROR("build cann hs check code msg failed");
294 0 : return TSD_INTERNAL_ERROR;
295 : }
296 5 : ret = commAgent_.SendMsg(msg);
297 5 : if (ret != TSD_OK) {
298 0 : TSD_ERROR("Send cann hs check code failed");
299 0 : return TSD_INTERNAL_ERROR;
300 : }
301 :
302 5 : TSD_RUN_INFO(
303 : "[TsdClient][deviceId=%u] [sessionId=%u] wait cann package info response for %s", envInfo_.GetLogicDeviceId(),
304 : commAgent_.GetSessionId(), pkgPureName.c_str());
305 5 : ret = mgr_.WaitPkgRsp(DRIVER_EXTEND_MAX_PROCESS_TIME * 1000U);
306 5 : if (ret != TSD_OK) {
307 1 : TSD_ERROR("Wait response for package %s failed", pkgPureName.c_str());
308 1 : return TSD_INTERNAL_ERROR;
309 : }
310 4 : TSD_RUN_INFO("Get check code for package %s success", pkgPureName.c_str());
311 4 : return TSD_OK;
312 5 : }
313 :
314 2 : void PackageCheckCodeService::HandleNormalPackageCheckCodeRsp(const HDCMessage& msg)
315 : {
316 2 : const uint32_t packageType = static_cast<uint32_t>(msg.package_type());
317 2 : constexpr uint32_t packageTypeMax = static_cast<uint32_t>(TsdLoadPackageType::TSD_PKG_TYPE_MAX);
318 2 : if (packageType >= packageTypeMax) {
319 1 : TSD_ERROR("The package type is larger than the max, max=%u, type=%u", packageTypeMax, packageType);
320 1 : return;
321 : }
322 1 : if (packageType == static_cast<uint32_t>(TsdLoadPackageType::TSD_PKG_TYPE_COMMON_SINK)) {
323 0 : hashStore_.StoreAllPkgHashValue(msg);
324 : } else {
325 1 : peerCheckCode_[packageType] = msg.check_code();
326 : }
327 1 : mgr_.deviceIdle_ = msg.device_idle();
328 1 : if (!mgr_.deviceIdle_) {
329 0 : TSD_RUN_WARN("device has process is running, skip load driver extend package");
330 : }
331 1 : pkgRspCode_ = ((msg.tsd_rsp_code() == 0U) ? ResponseCode::SUCCESS : ResponseCode::FAIL);
332 1 : loadPackageErrorMsg_ = msg.error_info().error_log();
333 : }
334 :
335 1 : void PackageCheckCodeService::HandleCannHsCheckCodeRsp(const HDCMessage& msg)
336 : {
337 1 : if (msg.package_hash_code_list_size() == 0) {
338 0 : TSD_ERROR("Get package hash size from msg failed, is empty");
339 0 : return;
340 : }
341 1 : std::string pkgName = msg.package_hash_code_list(0).package_name();
342 1 : std::string deviceHashValue = msg.package_hash_code_list(0).hash_code();
343 1 : hashStore_.SetDeviceCommonSinkPackHashValue(pkgName, deviceHashValue);
344 1 : pkgRspCode_ = (msg.tsd_rsp_code() == 0U) ? ResponseCode::SUCCESS : ResponseCode::FAIL;
345 1 : TSD_INFO("Set check code for %s success. rsp=%u", pkgName.c_str(), pkgRspCode_);
346 1 : }
347 :
348 9 : void PackageCheckCodeService::SaveDeviceCheckCode(const HDCMessage& msg)
349 : {
350 9 : const HDCMessage::MsgType msgType = msg.type();
351 34 : for (const auto& handler : CHECK_CODE_RSP_HANDLERS) {
352 30 : if (handler.msgType == msgType) {
353 5 : handler.handle(*this, msg);
354 5 : if (msgType == HDCMessage::TSD_CHECK_PACKAGE_RSP) {
355 2 : capabilityMgr_.UpdateStateFromMsg(msg);
356 : }
357 5 : return;
358 : }
359 : }
360 4 : if (msgType == HDCMessage::TSD_GET_DEVICE_PACKAGE_CHECKCODE_NORMAL_RSP) {
361 2 : HandleNormalPackageCheckCodeRsp(msg);
362 2 : } else if (msgType == HDCMessage::TSD_GET_DEVICE_CANN_HS_CHECKCODE_RSP) {
363 1 : HandleCannHsCheckCodeRsp(msg);
364 : } else {
365 1 : TSD_RUN_INFO("msgType[%u] is not supported", static_cast<uint32_t>(msgType));
366 : }
367 : }
368 :
369 : } // namespace tsd
|