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 1172 : : rankTableFile_(rankTableM),
99 1173 : identify_(identify),
100 1173 : statusCompleted_(false),
101 2346 : uniqueInfoCheckPool_(static_cast<u32>(JsonUniqueInfoType::UNIQUE_INFO_NUM)),
102 4690 : devMap_()
103 1173 : {}
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 776 : HcclResult TopoInfoRanktableParser::LoadRankTableString(const std::string& string)
208 : {
209 776 : 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 776 : HcclResult TopoInfoRanktableParser::LoadString(const std::string& string)
227 : {
228 : // 入参检查
229 776 : 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 776 : 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(RankTable_t& clusterInfo) { return HCCL_SUCCESS; }
254 0 : HcclResult TopoInfoRanktableParser::GetClusterInfo(hccl::HcclCommParams& params, hccl::RankTable_t& rankTable)
255 : {
256 0 : return HCCL_SUCCESS;
257 : }
258 :
259 388 : HcclResult TopoInfoRanktableParser::Init()
260 : {
261 388 : HcclResult ret = LoadRankTableString(rankTableFile_);
262 388 : CHK_PRT_RET(
263 : ret != HCCL_SUCCESS, HCCL_ERROR("[Init][TopoInfoRanktableParser]load string[%s] error", fileName_.c_str()),
264 : ret);
265 :
266 388 : return HCCL_SUCCESS;
267 : }
268 :
269 391 : HcclResult TopoInfoRanktableParser::LoadFileInit(std::string& rankTableM)
270 : {
271 391 : HcclResult ret = LoadFile(rankTableFile_);
272 400 : RPT_INPUT_ERR(
273 : ret != HCCL_SUCCESS, "EI0004", std::vector<std::string>({"ranktable_path", "error_reason"}),
274 : std::vector<std::string>({rankTableFile_, RANKTABLE_PARSE_ERROR_REASON}));
275 :
276 391 : CHK_PRT_RET(
277 : ret != HCCL_SUCCESS,
278 : HCCL_ERROR(
279 : "[%s][%s]load file[%s] error", LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_RANKTABLE_CONFIG.c_str(),
280 : rankTableFile_.c_str()),
281 : ret);
282 :
283 390 : rankTableM = fileContent_.dump();
284 390 : return HCCL_SUCCESS;
285 1 : }
286 :
287 0 : HcclResult TopoInfoRanktableParser::SetIsInterSuperPodRetryEnable(bool isRetryEnable) { return HCCL_SUCCESS; }
288 :
289 388 : HcclResult TopoInfoRanktableParser::GetRanktableVersion(std::string& version)
290 : {
291 : /* 查找json对象中是否有该属性, 不存在的属性不能直接访问 */
292 388 : if (fileContent_.find(CLUSTER_PROP_VERSION) == fileContent_.end()) {
293 388 : version = "Standard";
294 388 : HCCL_DEBUG("RankTableVersion is not found, Parser: %s", version.c_str());
295 : } else {
296 0 : CHK_RET(GetJsonProperty(fileContent_, CLUSTER_PROP_VERSION, version_, false));
297 0 : version = version_;
298 0 : HCCL_DEBUG("%s.json -> version: %s", fileName_.c_str(), version.c_str());
299 : }
300 388 : return HCCL_SUCCESS;
301 : }
302 :
303 1166 : HcclResult TopoInfoRanktableParser::RefreshStatus()
304 : {
305 1166 : std::string status = "";
306 1166 : CHK_RET(GetJsonProperty(fileContent_, "status", status, false));
307 1166 : HCCL_DEBUG("%s.json -> status: %s", fileName_.c_str(), status.c_str());
308 1166 : statusCompleted_ = (status == "completed");
309 1166 : return HCCL_SUCCESS;
310 1167 : }
311 :
312 390 : bool TopoInfoRanktableParser::IsReady() const { return this->statusCompleted_; }
313 :
314 1942 : HcclResult TopoInfoRanktableParser::GetJsonProperty(
315 : const nlohmann::json& obj, const char* propName, std::string& propValue, bool optionalProp) const
316 : {
317 : /* 查找json对象中是否有该属性, 不存在的属性不能直接访问 */
318 1942 : if (obj.find(propName) == obj.end()) {
319 1 : if (optionalProp) {
320 0 : HCCL_WARNING("json object has no property called %s", propName);
321 : } else {
322 8 : RPT_INPUT_ERR(
323 : true, "EI0017", std::vector<std::string>({"config"}),
324 : std::vector<std::string>({std::string(propName)}));
325 1 : HCCL_ERROR(
326 : "[%s][%s]json object has no property called %s", LOG_KEYWORDS_INIT_GROUP.c_str(),
327 : LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), propName);
328 : }
329 1 : return HCCL_E_NOT_FOUND;
330 : }
331 :
332 1940 : if (obj[propName].is_string()) {
333 1941 : propValue = obj[propName];
334 1941 : return HCCL_SUCCESS;
335 : } else {
336 0 : RPT_INPUT_ERR(
337 : true, "EI0017", std::vector<std::string>({"config"}), std::vector<std::string>({std::string(propName)}));
338 0 : HCCL_ERROR(
339 : "[Get][JsonProperty]errNo[0x%016llx] json object property value of Name[%s] is not string!",
340 : HCOM_ERROR_CODE(HCCL_E_PARA), propName);
341 0 : return HCCL_E_PARA;
342 : }
343 2 : }
344 :
345 388 : HcclResult TopoInfoRanktableParser::GetJsonProperty(
346 : const nlohmann::json& obj, const char* propName, nlohmann::json& propValue, bool optionalProp) const
347 : {
348 : /* 查找json对象中是否有该属性, 不存在的属性不能直接访问 */
349 388 : if (obj.find(propName) == obj.end()) {
350 0 : if (optionalProp) {
351 0 : HCCL_WARNING("json object has no property called %s", propName);
352 : } else {
353 0 : HCCL_ERROR("json object has no property called %s", propName);
354 : }
355 0 : return HCCL_E_NOT_FOUND;
356 : }
357 388 : propValue = obj[propName];
358 387 : CHK_PRT_RET(
359 : propValue.size() == 0, HCCL_ERROR("[Get][JsonProperty]get property[%s] size is zero", propName), HCCL_E_PARA);
360 387 : return HCCL_SUCCESS;
361 : }
362 :
363 6111 : HcclResult TopoInfoRanktableParser::GetJsonArrayMemberProperty(
364 : const nlohmann::json& obj, const u32 index, const char* propName, std::string& propValue, bool optionalProp) const
365 : {
366 6111 : if (!obj.is_array() || index >= obj.size()) {
367 2 : HCCL_ERROR(
368 : "[Get][JsonArrayMemberProperty]errNo[0x%016llx] index[%u] is out of json object range",
369 : HCOM_ERROR_CODE(HCCL_E_NOT_FOUND), index);
370 2 : return HCCL_E_PARA;
371 : }
372 :
373 6107 : nlohmann::json subObj = obj.at(index);
374 6085 : if (subObj.find(propName) == subObj.end()) {
375 2 : if (optionalProp) {
376 2 : HCCL_WARNING("json object index[%u] has no property called %s", index, propName);
377 : } else {
378 0 : RPT_INPUT_ERR(
379 : true, "EI0017", std::vector<std::string>({"config"}),
380 : std::vector<std::string>({std::string(propName)}));
381 0 : HCCL_ERROR("json object index[%u] has no property called %s", index, propName);
382 : }
383 2 : return HCCL_E_NOT_FOUND;
384 : }
385 6076 : if (subObj[propName].is_string()) {
386 6109 : propValue = subObj[propName];
387 6105 : return HCCL_SUCCESS;
388 : } else {
389 0 : RPT_INPUT_ERR(
390 : true, "EI0017", std::vector<std::string>({"config"}), std::vector<std::string>({std::string(propName)}));
391 0 : HCCL_ERROR(
392 : "[%s][%s]errNo[0x%016llx] json object property value of Name[%s] is not string!",
393 : LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), HCOM_ERROR_CODE(HCCL_E_PARA),
394 : propName);
395 0 : return HCCL_E_PARA;
396 : }
397 6107 : }
398 :
399 0 : HcclResult TopoInfoRanktableParser::GetJsonArrayMemberProperty(
400 : const nlohmann::json& obj, const u32 index, const char* propName, u32& propValue, bool optionalProp)
401 : {
402 0 : if (!obj.is_array() || index >= obj.size()) {
403 0 : HCCL_ERROR(
404 : "[Get][JsonArrayMemberProperty]errNo[0x%016llx] index[%u] is out of json object range",
405 : HCOM_ERROR_CODE(HCCL_E_NOT_FOUND), index);
406 0 : return HCCL_E_PARA;
407 : }
408 :
409 0 : nlohmann::json subObj = obj.at(index);
410 0 : if (subObj.find(propName) == subObj.end()) {
411 0 : if (optionalProp) {
412 0 : HCCL_WARNING("json object index[%u] has no property called %s", index, propName);
413 : } else {
414 0 : HCCL_ERROR("json object index[%u] has no property called %s", index, propName);
415 : }
416 0 : return HCCL_E_NOT_FOUND;
417 : }
418 0 : if (subObj[propName].is_number_unsigned()) {
419 0 : propValue = subObj[propName];
420 0 : return HCCL_SUCCESS;
421 : } else {
422 0 : HCCL_ERROR(
423 : "[Get][JsonArrayMemberProperty]errNo[0x%016llx] json object property value of Name[%s] is "
424 : "not unsigned int!",
425 : HCOM_ERROR_CODE(HCCL_E_PARA), propName);
426 0 : return HCCL_E_PARA;
427 : }
428 0 : }
429 :
430 1525 : HcclResult TopoInfoRanktableParser::GetJsonArrayMemberProperty(
431 : const nlohmann::json& obj, const u32 index, const char* propName, nlohmann::json& propValue,
432 : bool optionalProp) const
433 : {
434 1525 : if (!obj.is_array() || index >= obj.size()) {
435 0 : HCCL_ERROR(
436 : "[Get][JsonArrayMemberProperty]errNo[0x%016llx] index[%u] is out of json object range",
437 : HCOM_ERROR_CODE(HCCL_E_NOT_FOUND), index);
438 0 : return HCCL_E_PARA;
439 : }
440 :
441 1524 : nlohmann::json subObj = obj.at(index);
442 1524 : if (subObj.find(propName) == subObj.end()) {
443 0 : if (optionalProp) {
444 0 : HCCL_WARNING("json object index[%u] has no property called %s", index, propName);
445 : } else {
446 0 : HCCL_ERROR("json object index[%u] has no property called %s", index, propName);
447 : }
448 0 : return HCCL_E_NOT_FOUND;
449 : }
450 1524 : propValue = subObj[propName];
451 1524 : CHK_PRT_RET(
452 : propValue.size() == 0,
453 : HCCL_ERROR(
454 : "[Get][JsonArrayMemberProperty]get index[%u] property[%s] size is "
455 : "zero",
456 : index, propName),
457 : HCCL_E_PARA);
458 1524 : return HCCL_SUCCESS;
459 1524 : }
460 :
461 : /* 依据检查类型进行入参内容检查,并将检查选项转为strType带出以便后续信息打印 */
462 1528 : HcclResult TopoInfoRanktableParser::CheckUniquePara(
463 : const JsonUniqueInfoType& type, const std::string& value, string& strType) const
464 : {
465 1528 : auto it = JsonInfoTypeNameMap.find(type);
466 1527 : CHK_PRT_RET(
467 : it == JsonInfoTypeNameMap.end(),
468 : HCCL_ERROR(
469 : "[Get][JsonArrayMemberProperty][Check][UniquePara]errNo[0x%016llx] jsonUniqueInfoType[%d] "
470 : "is not in JsonInfoTypeNameMap",
471 : HCOM_ERROR_CODE(HCCL_E_PARA), type),
472 : HCCL_E_PARA);
473 1527 : strType = it->second;
474 1528 : switch (type) {
475 1140 : case JsonUniqueInfoType::UNIQUE_INFO_TYPE_DEVICE_IP:
476 : case JsonUniqueInfoType::UNIQUE_INFO_TYPE_BACKUP_DEVICE_IP:
477 : case JsonUniqueInfoType::UNIQUE_INFO_TYPE_ETH_IP: {
478 : /* 必须是一个有效的ip地址 */
479 1140 : HcclIpAddress ip(value);
480 1140 : if (ip.IsInvalid()) {
481 0 : RPT_INPUT_ERR(
482 : true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
483 : std::vector<std::string>({value, "IP", "a valid IP address"}));
484 0 : HCCL_ERROR(
485 : "[%s][%s]errNo[0x%016llx] ip[%s] is not a valid ip address", LOG_KEYWORDS_INIT_GROUP.c_str(),
486 : LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), HCOM_ERROR_CODE(HCCL_E_PARA), value.c_str());
487 0 : return HCCL_E_PARA;
488 : }
489 2280 : } break;
490 :
491 388 : case JsonUniqueInfoType::UNIQUE_INFO_TYPE_SERVER_ID:
492 : case JsonUniqueInfoType::UNIQUE_INFO_TYPE_GROUP_NAME:
493 : case JsonUniqueInfoType::UNIQUE_INFO_TYPE_SUPER_POD_ID:
494 : case JsonUniqueInfoType::UNIQUE_INFO_TYPE_POD_NAME: {
495 388 : if (value.length() > GROUP_NAME_MAX_LEN) {
496 0 : HCCL_ERROR(
497 : "[Check][UniquePara]errNo[0x%016llx] Name[%s] length[%lu] is too long",
498 : HCOM_ERROR_CODE(HCCL_E_PARA), value.c_str(), value.length());
499 0 : return HCCL_E_PARA;
500 : }
501 388 : } break;
502 :
503 0 : case JsonUniqueInfoType::UNIQUE_INFO_TYPE_ETH_NAME:
504 0 : break;
505 :
506 0 : default: {
507 0 : HCCL_ERROR(
508 : "[Check][UniquePara]errNo[0x%016llx] invalid unique info type[%d]", HCOM_ERROR_CODE(HCCL_E_PARA), type);
509 0 : return HCCL_E_PARA;
510 : } break;
511 : }
512 1528 : return HCCL_SUCCESS;
513 0 : }
514 :
515 1528 : HcclResult TopoInfoRanktableParser::CheckUniqueAndInsertPool(
516 : const JsonUniqueInfoType& type, const std::string& value, const JsonCheckOpType& opType)
517 : {
518 1528 : string strUniqueInfoType;
519 : /* 先依据type检查入参内容合法 */
520 1528 : CHK_RET(CheckUniquePara(type, value, strUniqueInfoType));
521 : /* 关键信息添加保存 */
522 1528 : auto srvIt = uniqueInfoCheckPool_[static_cast<u32>(type)].find(value);
523 1527 : if (opType == JsonCheckOpType::CHECK_OP_TYPE_INSERT) {
524 : /* JsonCheckOpType::CHECK_OP_TYPE_INSERT操作插入保存到资源池中,若资源池中存在则报错 */
525 1527 : if (srvIt != uniqueInfoCheckPool_[static_cast<u32>(type)].end()) {
526 14 : RPT_INPUT_ERR(
527 : true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
528 : std::vector<std::string>({value, " \"IP\" is repeate", "please check the ranktable"}));
529 1 : HCCL_ERROR(
530 : "[%s][%s]errNo[0x%016llx] [%s]:[%s] is already exist", LOG_KEYWORDS_INIT_GROUP.c_str(),
531 : LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), HCOM_ERROR_CODE(HCCL_E_PARA), strUniqueInfoType.c_str(),
532 : value.c_str());
533 1 : return HCCL_E_PARA;
534 : }
535 1526 : uniqueInfoCheckPool_[static_cast<u32>(type)].insert(value);
536 0 : } else if (opType == JsonCheckOpType::CHECK_OP_TYPE_FIND) {
537 : /* JsonCheckOpType::CHECK_OP_TYPE_FIND操作仅在资源池中查找是否存在,不存在报错 */
538 0 : if (srvIt == uniqueInfoCheckPool_[static_cast<u32>(type)].end()) {
539 0 : HCCL_ERROR(
540 : "[Check][UniqueAndInsertPool]errNo[0x%016llx] [%s]:[%s] is not exist", HCOM_ERROR_CODE(HCCL_E_PARA),
541 : strUniqueInfoType.c_str(), value.c_str());
542 0 : return HCCL_E_NOT_FOUND;
543 : }
544 : } else {
545 0 : HCCL_ERROR(
546 : "[Check][UniqueAndInsertPool]errNo[0x%016llx] invalid json check op Type[%d]", HCOM_ERROR_CODE(HCCL_E_PARA),
547 : opType);
548 0 : return HCCL_E_PARA;
549 : }
550 1525 : return HCCL_SUCCESS;
551 1528 : }
552 :
553 1138 : void TopoInfoRanktableParser::GenerateServerIdx(const std::string& serverId, u32& serverIdx)
554 : {
555 1138 : auto it = find(ServerIdRecord_.begin(), ServerIdRecord_.end(), serverId);
556 1137 : if (it == ServerIdRecord_.end()) {
557 400 : serverIdx = ServerIdRecord_.size();
558 400 : ServerIdRecord_.push_back(serverId);
559 : } else {
560 1473 : serverIdx = std::distance(ServerIdRecord_.begin(), it);
561 : }
562 1137 : }
563 :
564 0 : void TopoInfoRanktableParser::GenerateSuperPodIdx(const std::string& superPodId, u32& superPodIdx)
565 : {
566 0 : auto it = find(superPodRecord_.begin(), superPodRecord_.end(), superPodId);
567 0 : if (it == superPodRecord_.end()) {
568 0 : superPodIdx = superPodRecord_.size();
569 0 : superPodRecord_.push_back(superPodId);
570 : } else {
571 0 : superPodIdx = std::distance(superPodRecord_.begin(), it);
572 : }
573 0 : HCCL_INFO("GenerateSuperPodIdx superPodId[%s], superPodIdx[%u]", superPodId.c_str(), superPodIdx);
574 0 : }
575 :
576 1138 : HcclResult TopoInfoRanktableParser::ConvertIpAddress(const std::string& ipStr, HcclIpAddress& ipAddr)
577 : {
578 1138 : HcclResult ret = ipAddr.SetReadableAddress(ipStr);
579 1139 : RPT_INPUT_ERR(
580 : ret != HCCL_SUCCESS, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
581 : std::vector<std::string>({ipStr, "IP", "a valid IP address"}));
582 1139 : CHK_PRT_RET(
583 : ret != HCCL_SUCCESS,
584 : HCCL_ERROR(
585 : "[%s][%s]ipStr[%s] convert failed", LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_RANKTABLE_CHECK.c_str(),
586 : ipStr.c_str()),
587 : ret);
588 1139 : return ret;
589 0 : }
|