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