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_sender.h"
12 : #include "package_check_code_service.h"
13 : #include <string>
14 : #include <sys/file.h>
15 : #include "weak_ascend_hal.h"
16 : #include "error_manager.h"
17 : #include "env_internal_api.h"
18 : #include "tsd_log.h"
19 : #include "tsd_scope_guard.h"
20 : #include "tsd_util_func.h"
21 : #include "package_process_config.h"
22 : #include "hdc_message_builder.h"
23 :
24 : namespace {
25 : constexpr uint32_t INVALID_NUMBER = 0xFFFFFFFFU;
26 : constexpr uint32_t DRIVER_EXTEND_MAX_PROCESS_TIME = 140U;
27 : } // namespace
28 :
29 : namespace tsd {
30 :
31 365 : PackageSender::PackageSender(
32 : DeviceCommAgent& commAgent, CapabilityManager& capabilityMgr, PackageEnvInfo& envInfo, PackageHashStore& hashStore,
33 365 : PackageContext& ctx, PackageCheckCodeService& checkCodeSvc)
34 365 : : commAgent_(commAgent),
35 365 : capabilityMgr_(capabilityMgr),
36 365 : envInfo_(envInfo),
37 365 : hashStore_(hashStore),
38 365 : ctx_(ctx),
39 365 : checkCodeSvc_(checkCodeSvc)
40 365 : {}
41 :
42 18 : TSD_StatusT PackageSender::SendAICPUPackageSimple(
43 : const int32_t peerNode, const std::string& orgFile, const std::string& dstFile, bool useCannPath) const
44 : {
45 18 : TSD_RUN_INFO(
46 : "[TsdClient][deviceId=%u] no equal to begin send file[%s] to [%s]", envInfo_.GetLogicDeviceId(),
47 : orgFile.c_str(), dstFile.c_str());
48 18 : if (useCannPath) {
49 22 : const auto ret = drvHdcSendFileV2(
50 11 : peerNode, static_cast<int32_t>(envInfo_.GetLogicDeviceId()), orgFile.c_str(), dstFile.c_str(), nullptr);
51 11 : if (ret != DRV_ERROR_NONE) {
52 2 : TSD_ERROR(
53 : "[TsdClient][deviceId=%u] drvHdcSendFile file[%s] to [%s] failed ret = %d", envInfo_.GetLogicDeviceId(),
54 : orgFile.c_str(), dstFile.c_str(), ret);
55 2 : return TSD_INTERNAL_ERROR;
56 : }
57 : } else {
58 14 : const auto ret = drvHdcSendFile(
59 7 : peerNode, static_cast<int32_t>(envInfo_.GetLogicDeviceId()), orgFile.c_str(), dstFile.c_str(), nullptr);
60 7 : if (ret != DRV_ERROR_NONE) {
61 1 : TSD_ERROR(
62 : "[TsdClient][deviceId=%u] drvHdcSendFile file[%s] to [%s] failed ret = %d", envInfo_.GetLogicDeviceId(),
63 : orgFile.c_str(), dstFile.c_str(), ret);
64 1 : return TSD_INTERNAL_ERROR;
65 : }
66 : }
67 :
68 15 : TSD_RUN_INFO(
69 : "[TsdClient][deviceId=%u] hdc send file[%s] to [%s] success", envInfo_.GetLogicDeviceId(), orgFile.c_str(),
70 : dstFile.c_str());
71 15 : return TSD_OK;
72 : }
73 :
74 18 : TSD_StatusT PackageSender::SendMsgAndHostPackage(
75 : const int32_t peerNode, const std::string& orgFile, const std::string& dstFile, HDCMessage& msg,
76 : const std::function<bool(void)>& compareCallBack, bool useCannPath)
77 : {
78 18 : msg.set_wait_flag(false);
79 18 : TSD_StatusT ret = checkCodeSvc_.GetDeviceCheckCodeRetry(msg);
80 18 : if (ret != TSD_OK) {
81 3 : if (ret >= TSD_SUBPROCESS_NUM_EXCEED_THE_LIMIT) {
82 1 : return ret;
83 : }
84 2 : return TSD_INTERNAL_ERROR;
85 : }
86 15 : if (compareCallBack()) {
87 4 : TSD_INFO("host check and compare to device, no need to load package");
88 4 : return TSD_OK;
89 : }
90 :
91 11 : if (this->SendAICPUPackageSimple(peerNode, orgFile, dstFile, useCannPath) != TSD_OK) {
92 : REPORT_INPUT_ERROR("E39006", std::vector<std::string>(), std::vector<std::string>());
93 2 : return TSD_INTERNAL_ERROR;
94 : }
95 :
96 9 : msg.set_wait_flag(true);
97 9 : ret = checkCodeSvc_.GetDeviceCheckCodeRetry(msg);
98 9 : if (ret != TSD_OK) {
99 4 : if (ret >= TSD_SUBPROCESS_NUM_EXCEED_THE_LIMIT) {
100 2 : return ret;
101 : }
102 2 : return TSD_INTERNAL_ERROR;
103 : }
104 :
105 5 : return TSD_OK;
106 : }
107 :
108 20 : TSD_StatusT PackageSender::SendHostPackageComplex(
109 : const int32_t peerNode, const std::string& orgFile, const std::string& dstFile, HDCMessage& msg,
110 : const std::function<bool(void)>& compareCallBack, bool useCannPath)
111 : {
112 20 : if (envInfo_.GetHostSoPath().empty()) {
113 7 : return this->SendMsgAndHostPackage(peerNode, orgFile, dstFile, msg, compareCallBack, useCannPath);
114 : }
115 13 : const std::string mutexFileName = envInfo_.GetCurHostMutexFile(useCannPath);
116 13 : const std::string mutexFile = envInfo_.GetHostSoPath() + mutexFileName;
117 13 : TSD_RUN_INFO("get host mutex file:%s, logicDeviceId:%u", mutexFile.c_str(), envInfo_.GetLogicDeviceId());
118 13 : if (!CheckRealPath(mutexFile)) {
119 10 : TSD_INFO("Cannot get realpath of mutexFile[%s]", mutexFile.c_str());
120 10 : return this->SendMsgAndHostPackage(peerNode, orgFile, dstFile, msg, compareCallBack, useCannPath);
121 : }
122 3 : const int32_t fileData = open(mutexFile.c_str(), O_RDONLY);
123 3 : if (fileData < 0) {
124 2 : TSD_INFO("Opening qs so [%s] was not successful, reason[%s]", mutexFile.c_str(), SafeStrerror().c_str());
125 2 : return this->SendMsgAndHostPackage(peerNode, orgFile, dstFile, msg, compareCallBack, useCannPath);
126 : } else {
127 1 : TSD_INFO("Open qs so [%s] success", mutexFile.c_str());
128 : }
129 2 : const ScopeGuard fileDataGuard([&fileData]() { (void)close(fileData); });
130 1 : const int32_t flockRet = flock(fileData, LOCK_EX);
131 1 : if (flockRet == -1) {
132 1 : TSD_RUN_WARN(
133 : "File lock was not successful, ret[%d], errno[%d], reason[%s]", flockRet, errno, SafeStrerror().c_str());
134 : }
135 :
136 2 : const ScopeGuard fileLockGuard([&fileData]() { (void)flock(fileData, LOCK_UN); });
137 1 : return this->SendMsgAndHostPackage(peerNode, orgFile, dstFile, msg, compareCallBack, useCannPath);
138 13 : }
139 :
140 5 : TSD_StatusT PackageSender::SendAICPUPackage(const int32_t peerNode, const std::string& path)
141 : {
142 5 : constexpr uint32_t packageType = static_cast<uint32_t>(TsdLoadPackageType::TSD_PKG_TYPE_AICPU_KERNEL);
143 5 : if (envInfo_.GetPackageNameRef(packageType).empty()) {
144 0 : TSD_RUN_INFO(
145 : "[TsdClient][deviceId_=%u] aicpu package is not existed, skip send package", envInfo_.GetLogicDeviceId());
146 0 : return TSD_OK;
147 : }
148 :
149 5 : if (ctx_.hostCheckCode[packageType] == ctx_.peerCheckCode[packageType]) {
150 1 : TSD_RUN_INFO(
151 : "[TsdClient][deviceId_=%u] the checksum of host package[%u] is the same as device[%u], skip send package.",
152 : envInfo_.GetLogicDeviceId(), ctx_.hostCheckCode[packageType], ctx_.peerCheckCode[packageType]);
153 1 : return TSD_OK;
154 : }
155 :
156 4 : const std::string orgFile = envInfo_.GetPackagePathRef(packageType) + envInfo_.GetPackageNameRef(packageType);
157 : const std::string dstFile =
158 4 : path + "/" + std::to_string(commAgent_.GetProcSign().tgid) + "_" + envInfo_.GetPackageNameRef(packageType);
159 4 : if ((!ctx_.getCheckCodeRetrySupport) || (IsAsanMmSysEnv()) || (IsFpgaMmSysEnv())) {
160 1 : return this->SendAICPUPackageSimple(peerNode, orgFile, dstFile, false);
161 : } else {
162 3 : MessageContext ctx{};
163 3 : ctx.logicDeviceId = envInfo_.GetLogicDeviceId();
164 3 : ctx.checkCode = ctx_.hostCheckCode[packageType];
165 3 : ctx.packageType = packageType;
166 3 : HDCMessage msg;
167 3 : if (HdcMessageBuilder::BuildCheckPackageRetry(msg, ctx) != TSD_OK) {
168 1 : return TSD_INTERNAL_ERROR;
169 : }
170 4 : auto aicpuPkgCompareMethd = [this, packageType]() {
171 2 : if (ctx_.hostCheckCode[packageType] == ctx_.peerCheckCode[packageType]) {
172 0 : TSD_INFO(
173 : "[TsdClient] after lock, the checksum of aicpu package[%u] is same as device[%u], skip send",
174 : ctx_.hostCheckCode[packageType], ctx_.peerCheckCode[packageType]);
175 0 : return true;
176 : }
177 2 : return false;
178 2 : };
179 2 : return this->SendHostPackageComplex(peerNode, orgFile, dstFile, msg, aicpuPkgCompareMethd, false);
180 3 : }
181 4 : }
182 :
183 9 : TSD_StatusT PackageSender::SendCommonPackage(
184 : const int32_t peerNode, const std::string& path, const uint32_t packageType)
185 : {
186 9 : if (envInfo_.GetPackageNameRef(packageType).empty()) {
187 2 : TSD_RUN_INFO(
188 : "[TsdClient][deviceId_=%u] package is not existed, skip send, packageType[%u]", envInfo_.GetLogicDeviceId(),
189 : packageType);
190 2 : return TSD_OK;
191 : }
192 :
193 7 : uint32_t supportLevelName = INVALID_NUMBER;
194 7 : if (packageType == static_cast<uint32_t>(TsdLoadPackageType::TSD_PKG_TYPE_AICPU_EXTEND_KERNEL)) {
195 3 : supportLevelName = TSD_SUPPORT_EXTEND_PKG;
196 4 : } else if (packageType == static_cast<uint32_t>(TsdLoadPackageType::TSD_PKG_TYPE_ASCENDCPP)) {
197 3 : supportLevelName = TSD_SUPPORT_ASCENDCPP_PKG;
198 : } else {
199 1 : TSD_RUN_WARN("unsupported packageType:%u", packageType);
200 1 : return TSD_OK;
201 : }
202 6 : if (TSD_BITMAP_GET(capabilityMgr_.GetTsdSupportLevel(), supportLevelName) == 0U) {
203 1 : ctx_.hostCheckCode[packageType] = 0U;
204 1 : TSD_RUN_INFO(
205 : "[TsdClient][deviceId_=%u] device does not support, skip send, packageType[%u]",
206 : envInfo_.GetLogicDeviceId(), packageType);
207 1 : return TSD_OK;
208 : }
209 :
210 5 : if (ctx_.hostCheckCode[packageType] == ctx_.peerCheckCode[packageType]) {
211 2 : TSD_INFO(
212 : "[TsdClient][deviceId_=%u] the checksum of host package[%u] is same as device[%u], skip send package, "
213 : "packageType[%u]",
214 : envInfo_.GetLogicDeviceId(), ctx_.hostCheckCode[packageType], ctx_.peerCheckCode[packageType], packageType);
215 2 : return TSD_OK;
216 : }
217 :
218 3 : const std::string orgFile = envInfo_.GetPackagePathRef(packageType) + envInfo_.GetPackageNameRef(packageType);
219 : const std::string dstFile =
220 3 : path + "/" + std::to_string(commAgent_.GetProcSign().tgid) + "_" + envInfo_.GetPackageNameRef(packageType);
221 3 : TSD_INFO(
222 : "[TsdClient][deviceId=%u] hostCheckCode[%u] no equal to deviceCheckCode[%u], begin send file[%s] to [%s], "
223 : "packageType[%u]",
224 : envInfo_.GetLogicDeviceId(), ctx_.hostCheckCode[packageType], ctx_.peerCheckCode[packageType], orgFile.c_str(),
225 : dstFile.c_str(), packageType);
226 6 : const auto ret = drvHdcSendFile(
227 3 : peerNode, static_cast<int32_t>(envInfo_.GetLogicDeviceId()), orgFile.c_str(), dstFile.c_str(), nullptr);
228 3 : if (ret != DRV_ERROR_NONE) {
229 1 : TSD_ERROR(
230 : "[TsdClient][deviceId=%u] drvHdcSendFile file[%s] to [%s] failed, ret[%d], packageType[%u]",
231 : envInfo_.GetLogicDeviceId(), orgFile.c_str(), dstFile.c_str(), ret, packageType);
232 1 : ctx_.hostCheckCode[packageType] = 0U;
233 1 : return TSD_INTERNAL_ERROR;
234 : }
235 2 : TSD_INFO(
236 : "[TsdClient][deviceId=%u] hdc send file[%s] to [%s] success, packageType[%u]", envInfo_.GetLogicDeviceId(),
237 : orgFile.c_str(), dstFile.c_str(), packageType);
238 2 : return TSD_OK;
239 3 : }
240 :
241 9 : TSD_StatusT PackageSender::SendFileToDevice(
242 : const char_t* const filePath, const uint64_t pathLen, const char_t* const fileName, const uint64_t fileNameLen,
243 : const bool addPreFix) const
244 : {
245 9 : TSD_RUN_INFO(
246 : "[TsdClient] [deviceId=%u][pathLen=%llu] SendFileToDevice enter", envInfo_.GetLogicDeviceId(), pathLen);
247 9 : constexpr int32_t peerNode = 0;
248 9 : const std::string basePath = envInfo_.GetTrustedBasePath(false);
249 9 : std::string curPid;
250 9 : if (commAgent_.IsInit()) {
251 7 : curPid = std::to_string(commAgent_.GetProcSign().tgid);
252 : } else {
253 : process_sign processSign;
254 2 : const int32_t ret = drvGetProcessSign(&processSign);
255 2 : if (ret != DRV_ERROR_NONE) {
256 1 : TSD_ERROR("driver get process sign failed. ret[%d].", ret);
257 1 : return TSD_INTERNAL_ERROR;
258 : }
259 1 : curPid = std::to_string(processSign.tgid);
260 : }
261 8 : std::string curFile(fileName, fileNameLen);
262 8 : std::string dstFile = basePath + "/";
263 8 : if (addPreFix) {
264 8 : dstFile += curPid + "_";
265 : }
266 8 : dstFile += curFile;
267 8 : std::string orgPath(filePath, pathLen);
268 8 : std::string orgFile;
269 8 : if (!orgPath.empty() && orgPath.back() == '/') {
270 7 : orgFile = orgPath + curFile;
271 : } else {
272 1 : orgFile = orgPath + "/" + curFile;
273 : }
274 16 : const auto ret = drvHdcSendFile(
275 8 : peerNode, static_cast<int32_t>(envInfo_.GetLogicDeviceId()), orgFile.c_str(), dstFile.c_str(), nullptr);
276 8 : if (ret != DRV_ERROR_NONE) {
277 1 : TSD_ERROR(
278 : "[TsdClient][deviceId=%u] drvHdcSendFile file[%s] to [%s] failed, "
279 : "ret = %d",
280 : envInfo_.GetLogicDeviceId(), orgFile.c_str(), dstFile.c_str(), ret);
281 1 : return TSD_INTERNAL_ERROR;
282 : }
283 7 : TSD_RUN_INFO(
284 : "[TsdClient][deviceId=%u] hdc send file[%s] to [%s] success", envInfo_.GetLogicDeviceId(), orgFile.c_str(),
285 : dstFile.c_str());
286 7 : return TSD_OK;
287 9 : }
288 :
289 6 : TSD_StatusT PackageSender::CompareAndSendCommonSinkPkg(
290 : const std::string& pkgPureName, const std::string& hostPkgHash, const int32_t peerNode, const std::string& orgFile,
291 : const std::string& dstFile)
292 : {
293 6 : MessageContext ctx{};
294 6 : ctx.logicDeviceId = envInfo_.GetLogicDeviceId();
295 6 : ctx.packageName = pkgPureName;
296 6 : ctx.hashCode = hostPkgHash;
297 6 : const PluginPkgVersion pv = PackageProcessConfig::GetInstance()->GetHostPluginVersion(pkgPureName);
298 6 : ctx.hostPluginVersion.version = pv.version;
299 6 : ctx.hostPluginVersion.timestamp = pv.timestamp;
300 6 : ctx.packageWorkerType = static_cast<uint32_t>(PackageWorkerType::PACKAGE_WORKER_COMMON_SINK);
301 6 : ctx.packageMaxProcessTime = DRIVER_EXTEND_MAX_PROCESS_TIME;
302 6 : ctx.packageType = static_cast<uint32_t>(TsdLoadPackageType::TSD_PKG_TYPE_COMMON_SINK);
303 6 : HDCMessage msg;
304 6 : if (HdcMessageBuilder::BuildNormalCheckCode(msg, ctx) != TSD_OK) {
305 1 : TSD_ERROR("build normal check code msg failed");
306 1 : return TSD_INTERNAL_ERROR;
307 : }
308 4 : auto commonSinkPkgCompareMethd = [this, pkgPureName]() {
309 4 : if (hashStore_.IsCommonSinkHostAndDevicePkgSame(pkgPureName)) {
310 1 : TSD_INFO(
311 : "checksum of driver package[%s] is same as device[%u], idle[%d], skip send",
312 : hashStore_.GetHostCommonSinkPackHashValue(pkgPureName).c_str(), envInfo_.GetLogicDeviceId(),
313 : ctx_.deviceIdle);
314 1 : return true;
315 : }
316 3 : return false;
317 5 : };
318 5 : if (this->SendHostPackageComplex(peerNode, orgFile, dstFile, msg, commonSinkPkgCompareMethd, true) != TSD_OK) {
319 2 : TSD_ERROR("send common sink package to device failed");
320 2 : return TSD_INTERNAL_ERROR;
321 : }
322 3 : return TSD_OK;
323 6 : }
324 :
325 : } // namespace tsd
|