Line data Source code
1 : /**
2 : * Copyright (c) 2025 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 "topoinfo_ranktableParser_pub.h"
12 :
13 : #include <map>
14 : #include <vector>
15 : #include <string>
16 : #include <fstream>
17 : #include <algorithm>
18 : #include <unistd.h>
19 : #include <chrono>
20 : #include <iostream>
21 : #include <arpa/inet.h>
22 :
23 : #include "adapter_error_manager_pub.h"
24 : #include "json_utils.h"
25 :
26 : using namespace std;
27 : using namespace hccl;
28 :
29 : constexpr char TYPE_IP[] = "ip";
30 : constexpr char TYPE_NAME[] = "Name";
31 : constexpr char TYPE_ETH_NAME[] = "ethName";
32 :
33 : constexpr u32 SERVERID_MIN = 0; // 整形serverId最小值
34 : constexpr u32 SERVERID_MAX = 0xFFFFFFFF; // 整形serverId最大值
35 :
36 : constexpr u32 HCCL_RANKTABLE_TIMEOUT_S = (30 * 60); // 读取ranktable json文件超时时间30 * 60s
37 :
38 : const std::map<JsonUniqueInfoType, std::string> JsonInfoTypeNameMap = {
39 : {JsonUniqueInfoType::UNIQUE_INFO_TYPE_DEVICE_IP, "device_ip"},
40 : {JsonUniqueInfoType::UNIQUE_INFO_TYPE_BACKUP_DEVICE_IP, "backup_device_ip"},
41 : {JsonUniqueInfoType::UNIQUE_INFO_TYPE_SERVER_ID, "server_id"},
42 : {JsonUniqueInfoType::UNIQUE_INFO_TYPE_ETH_IP, "eth_ip"},
43 : {JsonUniqueInfoType::UNIQUE_INFO_TYPE_GROUP_NAME, "group_name"},
44 : {JsonUniqueInfoType::UNIQUE_INFO_TYPE_POD_NAME, "pod_name"},
45 : {JsonUniqueInfoType::UNIQUE_INFO_TYPE_ETH_NAME, "eth_name"},
46 : {JsonUniqueInfoType::UNIQUE_INFO_TYPE_SUPER_POD_ID, "super_pod_id"},
47 : {JsonUniqueInfoType::UNIQUE_INFO_NUM, "info_num"},
48 : };
49 :
50 391 : bool CheckFilePath(const std::string& filePath, const std::string& fileType)
51 : {
52 391 : HCCL_DEBUG("file_path:%s,file_type:%s", filePath.c_str(), fileType.c_str());
53 :
54 : /* 如果file_path是file_type类型的文件,则file_path是以file_type结尾的 */
55 391 : return filePath.find(fileType) + fileType.length() == filePath.length();
56 : }
57 :
58 391 : HcclResult GetFileName(const std::string& filePath, const std::string& fileType, std::string& fileName)
59 : {
60 391 : HCCL_DEBUG("file_path:%s,file_type:%s", filePath.c_str(), fileType.c_str());
61 :
62 391 : auto fi = filePath.find_last_of('/');
63 391 : if (fi != std::string::npos) {
64 391 : fileName = filePath.substr(fi + 1);
65 391 : fileName = fileName.substr(0, fileName.length() - fileType.length());
66 : }
67 :
68 391 : HCCL_DEBUG("get file_name:%s", fileName.c_str());
69 :
70 391 : return fileName.empty() ? HCCL_E_PARA : HCCL_SUCCESS;
71 : }
72 :
73 388 : HcclResult CheckAverageDev(u32 uDeviceNum, u32 uServerNum)
74 : {
75 388 : if (uServerNum == 0) {
76 0 : HCCL_ERROR("[Check][AverageDev]errNo[0x%016llx] server num is zero", HCOM_ERROR_CODE(HCCL_E_PARA));
77 0 : return HCCL_E_PARA;
78 : }
79 : // check the valid of average device per sever
80 388 : u32 averageDevice = uDeviceNum / uServerNum;
81 :
82 : // 如果device_num/server_num 不能被整除,报错
83 : // averageDevice不等于1 ,2,4,8... 报错
84 388 : if ((uDeviceNum % uServerNum)
85 388 : || ((averageDevice != AVERAGE_DEVICE_SIXTEEN) && (averageDevice != AVERAGE_DEVICE_EIGHT)
86 348 : && (averageDevice != AVERAGE_DEVICE_FOUR) && (averageDevice != AVERAGE_DEVICE_TWO)
87 182 : && (averageDevice != AVERAGE_DEVICE_ONE))) {
88 0 : HCCL_ERROR(
89 : "[Check][AverageDev]errNo[0x%016llx] device / server is invalid, uDeviceNum[%u], uServerNum[%u]",
90 : HCOM_ERROR_CODE(HCCL_E_PARA), uDeviceNum, uServerNum);
91 0 : return HCCL_E_PARA;
92 : }
93 :
94 388 : return HCCL_SUCCESS;
95 : }
96 :
97 1173 : TopoInfoRanktableParser::TopoInfoRanktableParser(const std::string& rankTableM, const std::string& identify)
98 1173 : : rankTableFile_(rankTableM),
99 1173 : identify_(identify),
100 1173 : statusCompleted_(false),
101 2346 : uniqueInfoCheckPool_(static_cast<u32>(JsonUniqueInfoType::UNIQUE_INFO_NUM)),
102 4690 : devMap_()
103 1172 : {}
104 :
105 1173 : TopoInfoRanktableParser::~TopoInfoRanktableParser() {}
106 :
107 391 : HcclResult TopoInfoRanktableParser::ReadFile(const std::string& readFile)
108 : {
109 391 : std::string fileType = ".json";
110 : // 获取文件名字
111 391 : HcclResult ret = GetFileName(readFile, fileType, fileName_);
112 391 : CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[Read][File]get file[%s] name error", readFile.c_str()), HCCL_E_PARA);
113 :
114 : // 已只读方式打开该文件
115 391 : std::ifstream infile(readFile.c_str(), std::ifstream::in);
116 391 : if (!infile) {
117 0 : RPT_INPUT_ERR(
118 : true, "EI0004", std::vector<std::string>({"ranktable_path", "error_reason"}),
119 : std::vector<std::string>({readFile.c_str(), "failed to open the file in read-only mode"}));
120 0 : HCCL_ERROR(
121 : "[%s][%s]errNo[0x%016llx],open file %s failed", LOG_KEYWORDS_INIT_GROUP.c_str(),
122 : LOG_KEYWORDS_RANKTABLE_CONFIG.c_str(), HCOM_ERROR_CODE(HCCL_E_INTERNAL), readFile.c_str());
123 0 : return HCCL_E_INTERNAL;
124 : } else {
125 391 : fileContent_.clear();
126 : try {
127 391 : infile >> fileContent_; // 将文件内容读取到json对象内
128 0 : } catch (...) {
129 0 : RPT_INPUT_ERR(
130 : true, "EI0004", std::vector<std::string>({"ranktable_path", "error_reason"}),
131 : std::vector<std::string>({readFile.c_str(), RANKTABLE_PARSE_ERROR_REASON}));
132 :
133 0 : HCCL_ERROR(
134 : "[%s][%s]errNo[0x%016llx] load file[%s] to json fail. please check json file!",
135 : LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_RANKTABLE_CONFIG.c_str(),
136 : HCOM_ERROR_CODE(HCCL_E_INTERNAL), readFile.c_str());
137 0 : infile.close();
138 0 : return HCCL_E_INTERNAL;
139 0 : }
140 : }
141 391 : infile.close();
142 391 : return HCCL_SUCCESS;
143 391 : }
144 :
145 391 : HcclResult TopoInfoRanktableParser::LoadFile(const std::string& file)
146 : {
147 391 : if (file.empty()) {
148 0 : HCCL_ERROR(
149 : "[%s][%s]errNo[0x%016llx] json file length is zero", LOG_KEYWORDS_INIT_GROUP.c_str(),
150 : LOG_KEYWORDS_RANKTABLE_CONFIG.c_str(), HCOM_ERROR_CODE(HCCL_E_PARA));
151 0 : return HCCL_E_PARA;
152 : }
153 391 : std::string fileType = ".json";
154 :
155 391 : if (!CheckFilePath(file, fileType)) {
156 0 : HCCL_ERROR(
157 : "[%s][%s]errNo[0x%016llx] path %s is not a valid %s file", LOG_KEYWORDS_INIT_GROUP.c_str(),
158 : LOG_KEYWORDS_RANKTABLE_CONFIG.c_str(), HCOM_ERROR_CODE(HCCL_E_INTERNAL), file.c_str(), fileType.c_str());
159 0 : return HCCL_E_INTERNAL;
160 : }
161 : // 打开该文件前,判断该文件路径是否有效 规范
162 391 : char realFile[PATH_MAX] = {0};
163 391 : if (realpath(file.c_str(), realFile) == nullptr) {
164 0 : HCCL_ERROR(
165 : "[%s][%s]errNo[0x%016llx] path %s is not a valid real path", LOG_KEYWORDS_INIT_GROUP.c_str(),
166 : LOG_KEYWORDS_RANKTABLE_CONFIG.c_str(), HCOM_ERROR_CODE(HCCL_E_PARA), file.c_str());
167 0 : return HCCL_E_PARA;
168 : }
169 391 : string strFilePath = std::string(realFile);
170 391 : const std::chrono::seconds TIMEOUT(HCCL_RANKTABLE_TIMEOUT_S);
171 391 : auto startTime = std::chrono::steady_clock::now();
172 :
173 : // load file and check the status
174 391 : HCCL_INFO("waiting for ranktable load complete...");
175 :
176 : // set timeout for status of file to be completed
177 : // 实验室场景下总是completed,cloud场景初始填入initlizing,kube补充完整后成为completed状态
178 : do {
179 391 : if ((std::chrono::steady_clock::now() - startTime) >= TIMEOUT) {
180 0 : HCCL_ERROR(
181 : "[%s][%s]errNo[0x%016llx] Load ranktable file[%s] timeout[%lld]s", LOG_KEYWORDS_INIT_GROUP.c_str(),
182 : LOG_KEYWORDS_RANKTABLE_CONFIG.c_str(), HCOM_ERROR_CODE(HCCL_E_TIMEOUT), strFilePath.c_str(), TIMEOUT);
183 0 : return HCCL_E_TIMEOUT;
184 : }
185 : // 读取文件内容
186 391 : HcclResult ret = ReadFile(strFilePath);
187 391 : CHK_PRT_RET(
188 : ret != HCCL_SUCCESS,
189 : HCCL_ERROR(
190 : "[%s][%s]read file[%s] error", LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_RANKTABLE_CONFIG.c_str(),
191 : strFilePath.c_str()),
192 : HCCL_E_PARA);
193 :
194 391 : CHK_RET(RefreshStatus());
195 :
196 390 : if (IsReady()) {
197 390 : break;
198 : }
199 :
200 0 : SalSleep(1); // 每间隔一段时间去检测文件是否ready
201 0 : } while (true);
202 :
203 390 : HCCL_INFO("ranktable is ready");
204 390 : return HCCL_SUCCESS;
205 391 : }
206 :
207 775 : HcclResult TopoInfoRanktableParser::LoadRankTableString(const std::string& string)
208 : {
209 775 : CHK_RET(LoadString(string));
210 775 : fileName_ = "rankTableString";
211 775 : CHK_RET(RefreshStatus());
212 :
213 776 : HCCL_INFO("ranktable is ready");
214 776 : return HCCL_SUCCESS;
215 : }
216 :
217 0 : HcclResult TopoInfoRanktableParser::LoadConfigString(const std::string& string)
218 : {
219 0 : CHK_RET(LoadString(string));
220 0 : fileName_ = "configString";
221 :
222 0 : HCCL_INFO("ranktable is ready");
223 0 : return HCCL_SUCCESS;
224 : }
225 :
226 775 : HcclResult TopoInfoRanktableParser::LoadString(const std::string& string)
227 : {
228 : // 入参检查
229 775 : if (string.empty()) {
230 0 : RPT_INPUT_ERR(
231 : true, "EI0004", std::vector<std::string>({"ranktable_path", "error_reason"}),
232 : std::vector<std::string>({string, "rankTable path is nullptr"}));
233 0 : HCCL_ERROR(
234 : "[%s][%s]errNo[0x%016llx] json string length is zero", LOG_KEYWORDS_INIT_GROUP.c_str(),
235 : LOG_KEYWORDS_RANKTABLE_CONFIG.c_str(), HCOM_ERROR_CODE(HCCL_E_PARA));
236 0 : return HCCL_E_PARA;
237 : }
238 775 : HCCL_INFO("waiting for json string load complete...");
239 : // 将字符串内容读取到json对象中
240 776 : HcclResult ret = JsonUtils::ParseInformation(fileContent_, string);
241 775 : RPT_INPUT_ERR(
242 : ret != HCCL_SUCCESS, "EI0004", std::vector<std::string>({"ranktable_path", "error_reason"}),
243 : std::vector<std::string>({string, "failed to parse rank table JSON content, the JSON format is incorrect"}));
244 775 : CHK_PRT_RET(
245 : ret != HCCL_SUCCESS,
246 : HCCL_ERROR(
247 : "[%s][%s]Failed to read the string %s into JSON.", LOG_KEYWORDS_INIT_GROUP.c_str(),
248 : LOG_KEYWORDS_RANKTABLE_CONFIG.c_str(), string.c_str()),
249 : ret);
250 775 : return HCCL_SUCCESS;
251 0 : }
252 :
253 0 : HcclResult TopoInfoRanktableParser::GetClusterInfo([[maybe_unused]] RankTable_t& clusterInfo) { return HCCL_SUCCESS; }
254 0 : HcclResult TopoInfoRanktableParser::GetClusterInfo(
255 : [[maybe_unused]] hccl::HcclCommParams& params, [[maybe_unused]] hccl::RankTable_t& rankTable)
256 : {
257 0 : return HCCL_SUCCESS;
258 : }
259 :
260 388 : HcclResult TopoInfoRanktableParser::Init()
261 : {
262 388 : HcclResult ret = LoadRankTableString(rankTableFile_);
263 388 : CHK_PRT_RET(
264 : ret != HCCL_SUCCESS, HCCL_ERROR("[Init][TopoInfoRanktableParser]load string[%s] error", fileName_.c_str()),
265 : ret);
266 :
267 388 : return HCCL_SUCCESS;
268 : }
269 :
270 391 : HcclResult TopoInfoRanktableParser::LoadFileInit(std::string& rankTableM)
271 : {
272 391 : HcclResult ret = LoadFile(rankTableFile_);
273 400 : RPT_INPUT_ERR(
274 : ret != HCCL_SUCCESS, "EI0004", std::vector<std::string>({"ranktable_path", "error_reason"}),
275 : std::vector<std::string>({rankTableFile_, RANKTABLE_PARSE_ERROR_REASON}));
276 :
277 391 : CHK_PRT_RET(
278 : ret != HCCL_SUCCESS,
279 : HCCL_ERROR(
280 : "[%s][%s]load file[%s] error", LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_RANKTABLE_CONFIG.c_str(),
281 : rankTableFile_.c_str()),
282 : ret);
283 :
284 390 : rankTableM = fileContent_.dump();
285 390 : return HCCL_SUCCESS;
286 1 : }
287 :
288 0 : HcclResult TopoInfoRanktableParser::SetIsInterSuperPodRetryEnable([[maybe_unused]] bool isRetryEnable)
289 : {
290 0 : return HCCL_SUCCESS;
291 : }
292 :
293 388 : HcclResult TopoInfoRanktableParser::GetRanktableVersion(std::string& version)
294 : {
295 : /* 查找json对象中是否有该属性, 不存在的属性不能直接访问 */
296 388 : if (fileContent_.find(CLUSTER_PROP_VERSION) == fileContent_.end()) {
297 387 : version = "Standard";
298 387 : HCCL_DEBUG("RankTableVersion is not found, Parser: %s", version.c_str());
299 : } else {
300 0 : CHK_RET(GetJsonProperty(fileContent_, CLUSTER_PROP_VERSION, version_, false));
301 0 : version = version_;
302 0 : HCCL_DEBUG("%s.json -> version: %s", fileName_.c_str(), version.c_str());
303 : }
304 388 : return HCCL_SUCCESS;
305 : }
306 :
307 1166 : HcclResult TopoInfoRanktableParser::RefreshStatus()
308 : {
309 1166 : std::string status = "";
310 1166 : CHK_RET(GetJsonProperty(fileContent_, "status", status, false));
311 1165 : HCCL_DEBUG("%s.json -> status: %s", fileName_.c_str(), status.c_str());
312 1166 : statusCompleted_ = (status == "completed");
313 1165 : return HCCL_SUCCESS;
314 1166 : }
315 :
316 390 : bool TopoInfoRanktableParser::IsReady() const { return this->statusCompleted_; }
317 :
318 1941 : HcclResult TopoInfoRanktableParser::GetJsonProperty(
319 : const nlohmann::json& obj, const char* propName, std::string& propValue, bool optionalProp) const
320 : {
321 : /* 查找json对象中是否有该属性, 不存在的属性不能直接访问 */
322 1941 : if (obj.find(propName) == obj.end()) {
323 1 : if (optionalProp) {
324 0 : HCCL_WARNING("json object has no property called %s", propName);
325 : } else {
326 8 : RPT_INPUT_ERR(
327 : true, "EI0017", std::vector<std::string>({"config"}),
328 : std::vector<std::string>({std::string(propName)}));
329 1 : HCCL_ERROR(
330 : "[%s][%s]json object has no property called %s", LOG_KEYWORDS_INIT_GROUP.c_str(),
331 : LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), propName);
332 : }
333 1 : return HCCL_E_NOT_FOUND;
334 : }
335 :
336 1938 : if (obj[propName].is_string()) {
337 1941 : propValue = obj[propName];
338 1940 : return HCCL_SUCCESS;
339 : } else {
340 0 : RPT_INPUT_ERR(
341 : true, "EI0017", std::vector<std::string>({"config"}), std::vector<std::string>({std::string(propName)}));
342 0 : HCCL_ERROR(
343 : "[Get][JsonProperty]errNo[0x%016llx] json object property value of Name[%s] is not string!",
344 : HCOM_ERROR_CODE(HCCL_E_PARA), propName);
345 0 : return HCCL_E_PARA;
346 : }
347 2 : }
348 :
349 388 : HcclResult TopoInfoRanktableParser::GetJsonProperty(
350 : const nlohmann::json& obj, const char* propName, nlohmann::json& propValue, bool optionalProp) const
351 : {
352 : /* 查找json对象中是否有该属性, 不存在的属性不能直接访问 */
353 388 : if (obj.find(propName) == obj.end()) {
354 0 : if (optionalProp) {
355 0 : HCCL_WARNING("json object has no property called %s", propName);
356 : } else {
357 0 : HCCL_ERROR("json object has no property called %s", propName);
358 : }
359 0 : return HCCL_E_NOT_FOUND;
360 : }
361 387 : propValue = obj[propName];
362 388 : CHK_PRT_RET(
363 : propValue.size() == 0, HCCL_ERROR("[Get][JsonProperty]get property[%s] size is zero", propName), HCCL_E_PARA);
364 388 : return HCCL_SUCCESS;
365 : }
366 :
367 6110 : HcclResult TopoInfoRanktableParser::GetJsonArrayMemberProperty(
368 : const nlohmann::json& obj, const u32 index, const char* propName, std::string& propValue, bool optionalProp) const
369 : {
370 6110 : if (!obj.is_array() || index >= obj.size()) {
371 2 : HCCL_ERROR(
372 : "[Get][JsonArrayMemberProperty]errNo[0x%016llx] index[%u] is out of json object range",
373 : HCOM_ERROR_CODE(HCCL_E_NOT_FOUND), index);
374 2 : return HCCL_E_PARA;
375 : }
376 :
377 6102 : nlohmann::json subObj = obj.at(index);
378 6060 : if (subObj.find(propName) == subObj.end()) {
379 2 : if (optionalProp) {
380 2 : HCCL_WARNING("json object index[%u] has no property called %s", index, propName);
381 : } else {
382 0 : RPT_INPUT_ERR(
383 : true, "EI0017", std::vector<std::string>({"config"}),
384 : std::vector<std::string>({std::string(propName)}));
385 0 : HCCL_ERROR("json object index[%u] has no property called %s", index, propName);
386 : }
387 2 : return HCCL_E_NOT_FOUND;
388 : }
389 6055 : if (subObj[propName].is_string()) {
390 6101 : propValue = subObj[propName];
391 6107 : return HCCL_SUCCESS;
392 : } else {
393 0 : RPT_INPUT_ERR(
394 : true, "EI0017", std::vector<std::string>({"config"}), std::vector<std::string>({std::string(propName)}));
395 0 : HCCL_ERROR(
396 : "[%s][%s]errNo[0x%016llx] json object property value of Name[%s] is not string!",
397 : LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), HCOM_ERROR_CODE(HCCL_E_PARA),
398 : propName);
399 0 : return HCCL_E_PARA;
400 : }
401 6109 : }
402 :
403 0 : HcclResult TopoInfoRanktableParser::GetJsonArrayMemberProperty(
404 : const nlohmann::json& obj, const u32 index, const char* propName, u32& propValue, bool optionalProp)
405 : {
406 0 : if (!obj.is_array() || index >= obj.size()) {
407 0 : HCCL_ERROR(
408 : "[Get][JsonArrayMemberProperty]errNo[0x%016llx] index[%u] is out of json object range",
409 : HCOM_ERROR_CODE(HCCL_E_NOT_FOUND), index);
410 0 : return HCCL_E_PARA;
411 : }
412 :
413 0 : nlohmann::json subObj = obj.at(index);
414 0 : if (subObj.find(propName) == subObj.end()) {
415 0 : if (optionalProp) {
416 0 : HCCL_WARNING("json object index[%u] has no property called %s", index, propName);
417 : } else {
418 0 : HCCL_ERROR("json object index[%u] has no property called %s", index, propName);
419 : }
420 0 : return HCCL_E_NOT_FOUND;
421 : }
422 0 : if (subObj[propName].is_number_unsigned()) {
423 0 : propValue = subObj[propName];
424 0 : return HCCL_SUCCESS;
425 : } else {
426 0 : HCCL_ERROR(
427 : "[Get][JsonArrayMemberProperty]errNo[0x%016llx] json object property value of Name[%s] is "
428 : "not unsigned int!",
429 : HCOM_ERROR_CODE(HCCL_E_PARA), propName);
430 0 : return HCCL_E_PARA;
431 : }
432 0 : }
433 :
434 1525 : HcclResult TopoInfoRanktableParser::GetJsonArrayMemberProperty(
435 : const nlohmann::json& obj, const u32 index, const char* propName, nlohmann::json& propValue,
436 : bool optionalProp) const
437 : {
438 1525 : if (!obj.is_array() || index >= obj.size()) {
439 0 : HCCL_ERROR(
440 : "[Get][JsonArrayMemberProperty]errNo[0x%016llx] index[%u] is out of json object range",
441 : HCOM_ERROR_CODE(HCCL_E_NOT_FOUND), index);
442 0 : return HCCL_E_PARA;
443 : }
444 :
445 1524 : nlohmann::json subObj = obj.at(index);
446 1515 : if (subObj.find(propName) == subObj.end()) {
447 0 : if (optionalProp) {
448 0 : HCCL_WARNING("json object index[%u] has no property called %s", index, propName);
449 : } else {
450 0 : HCCL_ERROR("json object index[%u] has no property called %s", index, propName);
451 : }
452 0 : return HCCL_E_NOT_FOUND;
453 : }
454 1515 : propValue = subObj[propName];
455 1518 : CHK_PRT_RET(
456 : propValue.size() == 0,
457 : HCCL_ERROR(
458 : "[Get][JsonArrayMemberProperty]get index[%u] property[%s] size is "
459 : "zero",
460 : index, propName),
461 : HCCL_E_PARA);
462 1518 : return HCCL_SUCCESS;
463 1518 : }
464 :
465 : /* 依据检查类型进行入参内容检查,并将检查选项转为strType带出以便后续信息打印 */
466 1528 : HcclResult TopoInfoRanktableParser::CheckUniquePara(
467 : const JsonUniqueInfoType& type, const std::string& value, string& strType) const
468 : {
469 1528 : auto it = JsonInfoTypeNameMap.find(type);
470 1525 : CHK_PRT_RET(
471 : it == JsonInfoTypeNameMap.end(),
472 : HCCL_ERROR(
473 : "[Get][JsonArrayMemberProperty][Check][UniquePara]errNo[0x%016llx] jsonUniqueInfoType[%d] "
474 : "is not in JsonInfoTypeNameMap",
475 : HCOM_ERROR_CODE(HCCL_E_PARA), type),
476 : HCCL_E_PARA);
477 1525 : strType = it->second;
478 1527 : switch (type) {
479 1139 : case JsonUniqueInfoType::UNIQUE_INFO_TYPE_DEVICE_IP:
480 : case JsonUniqueInfoType::UNIQUE_INFO_TYPE_BACKUP_DEVICE_IP:
481 : case JsonUniqueInfoType::UNIQUE_INFO_TYPE_ETH_IP: {
482 : /* 必须是一个有效的ip地址 */
483 1139 : HcclIpAddress ip(value);
484 1140 : if (ip.IsInvalid()) {
485 0 : RPT_INPUT_ERR(
486 : true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
487 : std::vector<std::string>({value, "IP", "a valid IP address"}));
488 0 : HCCL_ERROR(
489 : "[%s][%s]errNo[0x%016llx] ip[%s] is not a valid ip address", LOG_KEYWORDS_INIT_GROUP.c_str(),
490 : LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), HCOM_ERROR_CODE(HCCL_E_PARA), value.c_str());
491 0 : return HCCL_E_PARA;
492 : }
493 2280 : } break;
494 :
495 388 : case JsonUniqueInfoType::UNIQUE_INFO_TYPE_SERVER_ID:
496 : case JsonUniqueInfoType::UNIQUE_INFO_TYPE_GROUP_NAME:
497 : case JsonUniqueInfoType::UNIQUE_INFO_TYPE_SUPER_POD_ID:
498 : case JsonUniqueInfoType::UNIQUE_INFO_TYPE_POD_NAME: {
499 388 : if (value.length() > GROUP_NAME_MAX_LEN) {
500 0 : HCCL_ERROR(
501 : "[Check][UniquePara]errNo[0x%016llx] Name[%s] length[%lu] is too long",
502 : HCOM_ERROR_CODE(HCCL_E_PARA), value.c_str(), value.length());
503 0 : return HCCL_E_PARA;
504 : }
505 388 : } break;
506 :
507 0 : case JsonUniqueInfoType::UNIQUE_INFO_TYPE_ETH_NAME:
508 0 : break;
509 :
510 0 : default: {
511 0 : HCCL_ERROR(
512 : "[Check][UniquePara]errNo[0x%016llx] invalid unique info type[%d]", HCOM_ERROR_CODE(HCCL_E_PARA), type);
513 0 : return HCCL_E_PARA;
514 : } break;
515 : }
516 1528 : return HCCL_SUCCESS;
517 0 : }
518 :
519 1528 : HcclResult TopoInfoRanktableParser::CheckUniqueAndInsertPool(
520 : const JsonUniqueInfoType& type, const std::string& value, const JsonCheckOpType& opType)
521 : {
522 1528 : string strUniqueInfoType;
523 : /* 先依据type检查入参内容合法 */
524 1528 : CHK_RET(CheckUniquePara(type, value, strUniqueInfoType));
525 : /* 关键信息添加保存 */
526 1526 : auto srvIt = uniqueInfoCheckPool_[static_cast<u32>(type)].find(value);
527 1525 : if (opType == JsonCheckOpType::CHECK_OP_TYPE_INSERT) {
528 : /* JsonCheckOpType::CHECK_OP_TYPE_INSERT操作插入保存到资源池中,若资源池中存在则报错 */
529 1525 : if (srvIt != uniqueInfoCheckPool_[static_cast<u32>(type)].end()) {
530 14 : RPT_INPUT_ERR(
531 : true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
532 : std::vector<std::string>({value, " \"IP\" is repeate", "please check the ranktable"}));
533 1 : HCCL_ERROR(
534 : "[%s][%s]errNo[0x%016llx] [%s]:[%s] is already exist", LOG_KEYWORDS_INIT_GROUP.c_str(),
535 : LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), HCOM_ERROR_CODE(HCCL_E_PARA), strUniqueInfoType.c_str(),
536 : value.c_str());
537 1 : return HCCL_E_PARA;
538 : }
539 1524 : uniqueInfoCheckPool_[static_cast<u32>(type)].insert(value);
540 0 : } else if (opType == JsonCheckOpType::CHECK_OP_TYPE_FIND) {
541 : /* JsonCheckOpType::CHECK_OP_TYPE_FIND操作仅在资源池中查找是否存在,不存在报错 */
542 0 : if (srvIt == uniqueInfoCheckPool_[static_cast<u32>(type)].end()) {
543 0 : HCCL_ERROR(
544 : "[Check][UniqueAndInsertPool]errNo[0x%016llx] [%s]:[%s] is not exist", HCOM_ERROR_CODE(HCCL_E_PARA),
545 : strUniqueInfoType.c_str(), value.c_str());
546 0 : return HCCL_E_NOT_FOUND;
547 : }
548 : } else {
549 0 : HCCL_ERROR(
550 : "[Check][UniqueAndInsertPool]errNo[0x%016llx] invalid json check op Type[%d]", HCOM_ERROR_CODE(HCCL_E_PARA),
551 : opType);
552 0 : return HCCL_E_PARA;
553 : }
554 1526 : return HCCL_SUCCESS;
555 1529 : }
556 :
557 1138 : void TopoInfoRanktableParser::GenerateServerIdx(const std::string& serverId, u32& serverIdx)
558 : {
559 1138 : auto it = find(ServerIdRecord_.begin(), ServerIdRecord_.end(), serverId);
560 1135 : if (it == ServerIdRecord_.end()) {
561 401 : serverIdx = ServerIdRecord_.size();
562 401 : ServerIdRecord_.push_back(serverId);
563 : } else {
564 1468 : serverIdx = std::distance(ServerIdRecord_.begin(), it);
565 : }
566 1135 : }
567 :
568 0 : void TopoInfoRanktableParser::GenerateSuperPodIdx(const std::string& superPodId, u32& superPodIdx)
569 : {
570 0 : auto it = find(superPodRecord_.begin(), superPodRecord_.end(), superPodId);
571 0 : if (it == superPodRecord_.end()) {
572 0 : superPodIdx = superPodRecord_.size();
573 0 : superPodRecord_.push_back(superPodId);
574 : } else {
575 0 : superPodIdx = std::distance(superPodRecord_.begin(), it);
576 : }
577 0 : HCCL_INFO("GenerateSuperPodIdx superPodId[%s], superPodIdx[%u]", superPodId.c_str(), superPodIdx);
578 0 : }
579 :
580 1138 : HcclResult TopoInfoRanktableParser::ConvertIpAddress(const std::string& ipStr, HcclIpAddress& ipAddr)
581 : {
582 1138 : HcclResult ret = ipAddr.SetReadableAddress(ipStr);
583 1139 : RPT_INPUT_ERR(
584 : ret != HCCL_SUCCESS, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
585 : std::vector<std::string>({ipStr, "IP", "a valid IP address"}));
586 1139 : CHK_PRT_RET(
587 : ret != HCCL_SUCCESS,
588 : HCCL_ERROR(
589 : "[%s][%s]ipStr[%s] convert failed", LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_RANKTABLE_CHECK.c_str(),
590 : ipStr.c_str()),
591 : ret);
592 1139 : return ret;
593 0 : }
|