Refactor: Make Processor config create a TopologyNode
To enforce the requirement that all objects with a devpath should have a TopologyConfigNode, we refactor the ParseProcessorConfig function to create a Fru object and TopologyConfigNode upon parsing a Processor config. This allows any object that needs the devpath of this i.e. IntelCpuSensors to be able to refer to the object and retrieve the devpath generated by topology.
Cpus may share a name i.e. CPU0 but be located on two separate chassis. Similar to fan in cl/817759813, we create a unique key for CPUs to avoid a conflict here and store the mapping in the topology object
#tlbmc
PiperOrigin-RevId: 819940072
Change-Id: Ie0aabaeae7cf4db8bc9205ee0f2b4553659417be
diff --git a/tlbmc/configs/entity_config_json_impl.cc b/tlbmc/configs/entity_config_json_impl.cc
index d8318a3..9f336a6 100644
--- a/tlbmc/configs/entity_config_json_impl.cc
+++ b/tlbmc/configs/entity_config_json_impl.cc
@@ -666,11 +666,6 @@
[](const std::string* id_1, const std::string* id_2) {
return *id_1 < *id_2;
});
- std::sort(node.mutable_children_processor_ids()->pointer_begin(),
- node.mutable_children_processor_ids()->pointer_end(),
- [](const std::string* id_1, const std::string* id_2) {
- return *id_1 < *id_2;
- });
std::sort(node.mutable_children_storage_ids()->pointer_begin(),
node.mutable_children_storage_ids()->pointer_end(),
[](const std::string* id_1, const std::string* id_2) {
@@ -1097,7 +1092,7 @@
return intel_cpu_sensor_config.status();
}
intel_cpu_sensor_config->mutable_entity_common_config()
- ->set_board_config_key(config_name_with_index);
+ ->set_board_config_key(config_name_with_index);
data.intel_cpu_sensor_configs.push_back(*intel_cpu_sensor_config);
}
@@ -1416,7 +1411,8 @@
}
absl::Status parse_processor_status =
- ParseProcessorConfig(element, topology_config_node);
+ ParseProcessorConfig(mutable_data, element, topology_config_node,
+ config_name_with_index);
if (!parse_processor_status.ok()) {
mutable_data.parsed_status = parse_processor_status;
return EntityConfigJsonImplData{
@@ -2518,7 +2514,9 @@
}
absl::Status EntityConfigJsonImpl::ParseProcessorConfig(
- const nlohmann::json& config, TopologyConfigNode& topology_config_node) {
+ EntityConfigJsonImplMutableData& mutable_data, const nlohmann::json& config,
+ TopologyConfigNode& topology_config_node,
+ std::string_view top_level_config_name) {
const std::string* type_str = GetValueAsString(config, "Type");
const bool* tlbmc_owned = GetValueAsBool(config, "TlbmcOwned");
IntelCpuSensorType intel_cpu_sensor_type = INTEL_CPU_SENSOR_TYPE0_UNKNOWN;
@@ -2537,7 +2535,47 @@
"Invalid config: Name field is not found for processor config");
}
- topology_config_node.add_children_processor_ids(*processor_id);
+ // Each processor should have a unique node name
+ std::string processor_node_name =
+ absl::StrFormat("%s_%s", top_level_config_name, *processor_id);
+
+ // Add processor to fru table.
+ Fru processor_fru;
+ processor_fru.mutable_attributes()->set_resource_type(
+ RESOURCE_TYPE_PROCESSOR);
+ processor_fru.mutable_attributes()->set_key(processor_node_name);
+ processor_fru.mutable_attributes()->set_status(Status::STATUS_READY);
+
+ // Processor should be its own Topology Node as it has its own machine level
+ // devpath
+ TopologyConfigNode processor_node;
+ processor_node.set_name(*processor_id);
+ processor_node.mutable_fru_info()->set_fru_key(processor_node_name);
+ processor_node.set_config_key(processor_node_name);
+
+ // Add topology port configs for upstream and downstream
+ PortConfig chassis_to_processor_port_config;
+ chassis_to_processor_port_config.set_port_type(PORT_TYPE_DOWNSTREAM);
+ chassis_to_processor_port_config.set_port_name(processor_node_name);
+ chassis_to_processor_port_config.set_port_label(
+ absl::AsciiStrToUpper(*processor_id));
+ topology_config_node.mutable_port_configs()->insert(
+ {processor_node_name, std::move(chassis_to_processor_port_config)});
+
+ PortConfig processor_to_chassis_port_config;
+ processor_to_chassis_port_config.set_port_type(PORT_TYPE_UPSTREAM);
+ processor_to_chassis_port_config.set_port_name(processor_node_name);
+ *processor_node.add_upstream_port_configs() =
+ std::move(processor_to_chassis_port_config);
+
+ // The config name and the fru key are identical.
+ mutable_data.topology_config.mutable_topology_config_nodes()->insert(
+ {processor_node_name, std::move(processor_node)});
+ mutable_data.topology_config.mutable_fru_configs()->insert(
+ {processor_node_name, processor_node_name});
+ mutable_data.fru_table.mutable_key_to_fru()->insert(
+ {processor_node_name, std::move(processor_fru)});
+
return absl::OkStatus();
}
@@ -2561,6 +2599,10 @@
} else if (downstream_fru.attributes().resource_type() == RESOURCE_TYPE_FAN) {
current_node.mutable_children_fans()->insert(
{downstream_node.name(), downstream_node.config_key()});
+ } else if (downstream_fru.attributes().resource_type() ==
+ RESOURCE_TYPE_PROCESSOR) {
+ current_node.mutable_children_processors()->insert(
+ {downstream_node.name(), downstream_node.config_key()});
}
// Link current node <- downstream node.
diff --git a/tlbmc/configs/entity_config_json_impl.h b/tlbmc/configs/entity_config_json_impl.h
index 61c2270..a8d18b1 100644
--- a/tlbmc/configs/entity_config_json_impl.h
+++ b/tlbmc/configs/entity_config_json_impl.h
@@ -349,7 +349,9 @@
const nlohmann::json& config, bool is_detected);
static absl::Status ParseProcessorConfig(
- const nlohmann::json& config, TopologyConfigNode& topology_config_node);
+ EntityConfigJsonImplMutableData& mutable_data,
+ const nlohmann::json& config, TopologyConfigNode& topology_config_node,
+ std::string_view top_level_config_name);
static absl::Status ParseFanConfig(
EntityConfigJsonImplMutableData& mutable_data,
diff --git a/tlbmc/redfish/routes/chassis.cc b/tlbmc/redfish/routes/chassis.cc
index 9b4c0b3..09f1752 100644
--- a/tlbmc/redfish/routes/chassis.cc
+++ b/tlbmc/redfish/routes/chassis.cc
@@ -341,9 +341,19 @@
all_cables.size());
}
- nlohmann::json::array_t child_processors = CreateChildResourceLinksArray(
- topology_config_node_ptr->children_processor_ids(),
- RESOURCE_TYPE_PROCESSOR);
+ // Processors are stored as a map to avoid conflicting processor ids on
+ // different chassis. We must iterate over the map to get all keys.
+ ::google::protobuf::RepeatedPtrField<std::string> processor_ids;
+ for (const auto& [processor_id, _] :
+ topology_config_node_ptr->children_processors()) {
+ processor_ids.Add(std::string(processor_id));
+ }
+ std::sort(processor_ids.pointer_begin(), processor_ids.pointer_end(),
+ [](const std::string* id_1, const std::string* id_2) {
+ return *id_1 < *id_2;
+ });
+ nlohmann::json::array_t child_processors =
+ CreateChildResourceLinksArray(processor_ids, RESOURCE_TYPE_PROCESSOR);
if (!child_processors.empty()) {
resp.SetKeyInJsonBody(chassis_pointer / "Links" / "Processors",
child_processors);
diff --git a/tlbmc/topology_config.proto b/tlbmc/topology_config.proto
index 6560bcb..9a06254 100644
--- a/tlbmc/topology_config.proto
+++ b/tlbmc/topology_config.proto
@@ -67,10 +67,11 @@
// TODO(b/409103531): Generalize associations in tlBMC data model.
repeated string children_chassis_ids = 10;
repeated string children_cable_ids = 11;
- repeated string children_processor_ids = 12;
repeated string children_storage_ids = 13;
repeated string children_assembly_ids = 16;
- // Fan names may not always be unique. This will map fan name to fan node key.
+ // These resource names may not always be unique. These will map name to
+ // topology node key.
+ map<string, string> children_processors = 12;
map<string, string> children_fans = 20;
// Only chassis and cable are possible parents.
repeated string parent_chassis_ids = 17;