Populate Oem.Google.Devpath for Embedded Chassis
Embedded chassis cannot be modeled in UHM so they require a special field in Oem.Google.Devpath.
It seems like we can consistently model ALL embedded chassis to populate Oem.Google.Devpath.
In order to do this, we have to ensure we use the machine local devpath when populating this field so we have to pass the RootChassisLocationCode to all nodes.
#tlbmc
PiperOrigin-RevId: 763871286
Change-Id: Id60747351ed473e72352ec923890519a9a1045d6
diff --git a/tlbmc/configs/entity_config_json_impl.cc b/tlbmc/configs/entity_config_json_impl.cc
index 0f27345..1260a90 100644
--- a/tlbmc/configs/entity_config_json_impl.cc
+++ b/tlbmc/configs/entity_config_json_impl.cc
@@ -1924,6 +1924,10 @@
while (!node_queue.empty()) {
TopologyConfigNode* current_node = node_queue.front();
node_queue.pop();
+
+ // Always populate root chassis location code for all nodes.
+ current_node->set_root_chassis_location_code(root_chassis_location_code);
+
if (expected_nodes_traversed.contains(current_node->name())) {
expected_nodes_traversed.erase(current_node->name());
} else {
@@ -1955,7 +1959,9 @@
downstream_node_name);
// If node is Sub-Fru then we add :device to the devpath and then append
// the port label.
- if (downstream_node.fru_info().is_sub_fru()) {
+ if (downstream_node.fru_info().is_sub_fru() ||
+ downstream_node.location_context().location_type() ==
+ PART_LOCATION_TYPE_EMBEDDED) {
downstream_node.mutable_location_context()->set_devpath(
absl::StrCat(current_node->mutable_location_context()->devpath(),
":device:", port_config.port_label()));
diff --git a/tlbmc/redfish/data/stable_id.cc b/tlbmc/redfish/data/stable_id.cc
index 36a6e61..efb37ed 100644
--- a/tlbmc/redfish/data/stable_id.cc
+++ b/tlbmc/redfish/data/stable_id.cc
@@ -3,6 +3,7 @@
#include <string>
#include <vector>
+#include "absl/log/log.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
@@ -13,12 +14,40 @@
namespace milotic_tlbmc {
+std::string GetNodeLocalDevpath(const std::string& devpath,
+ const std::string& root_chassis_location_code) {
+ // If the root chassis location code is empty, then the devpath is already
+ // machine local.
+ if (root_chassis_location_code.empty()) {
+ return devpath;
+ }
+
+ // The root chassis location code should ALWAYS be the prefix of the devpath.
+ // If it is not, then we have an error and return the empty string.
+ if (!absl::StrContains(devpath,
+ absl::StrCat("/", root_chassis_location_code))) {
+ LOG(ERROR) << "Root chassis location code " << root_chassis_location_code
+ << " is not a prefix of the devpath " << devpath;
+ return "";
+ }
+
+ // If the beginning is not /phys, then replace the beginning devpath part with
+ // /phys.
+ return absl::StrCat("/phys",
+ // +1 here to include the first "/" in the devpath.
+ devpath.substr(root_chassis_location_code.size() + 1));
+}
+
StableId GetStableId(const TopologyConfigNode& topology_config_node) {
StableId stable_id;
const LocationContext& location_context =
topology_config_node.location_context();
std::string devpath = location_context.devpath();
+
+ stable_id.set_machine_local_devpath(GetNodeLocalDevpath(
+ devpath, topology_config_node.root_chassis_location_code()));
+
// Remove /phys from the devpath.
if (absl::StartsWith(devpath, "/phys")) {
devpath = devpath.substr(5);
diff --git a/tlbmc/redfish/data/stable_id.h b/tlbmc/redfish/data/stable_id.h
index 6b13528..e119d4a 100644
--- a/tlbmc/redfish/data/stable_id.h
+++ b/tlbmc/redfish/data/stable_id.h
@@ -1,12 +1,20 @@
#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_REDFISH_DATA_STABLE_ID_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_REDFISH_DATA_STABLE_ID_H_
+#include <string>
+
#include "topology_config.pb.h"
#include "stable_id.pb.h"
#include "resource.pb.h"
namespace milotic_tlbmc {
+// Machine local devpaths always begin with "/phys".
+// Any devpath that has a RootChassisLocationCode should be replaced with
+// "/phys/"
+std::string GetNodeLocalDevpath(const std::string& devpath,
+ const std::string& root_chassis_location_code);
+
// Returns the stable id from LocationContext.
StableId GetStableId(const TopologyConfigNode& topology_config_node);
diff --git a/tlbmc/redfish/routes/chassis.cc b/tlbmc/redfish/routes/chassis.cc
index 8a70c27..c9e40c9 100644
--- a/tlbmc/redfish/routes/chassis.cc
+++ b/tlbmc/redfish/routes/chassis.cc
@@ -156,9 +156,10 @@
resp.SetKeyInJsonBody(chassis_pointer / "ChassisType", chassis_type);
if (fru_ptr->attributes().chassis_properties().bmcnet()) {
- resp.SetKeyInJsonBody(chassis_pointer / "NetworkAdapters" / "@odata.id",
- milotic_tlbmc::CreateUrl(
- {"redfish", "v1", "Chassis", chassis_id, "NetworkAdapters"}));
+ resp.SetKeyInJsonBody(
+ chassis_pointer / "NetworkAdapters" / "@odata.id",
+ milotic_tlbmc::CreateUrl(
+ {"redfish", "v1", "Chassis", chassis_id, "NetworkAdapters"}));
}
// Support Chassis Reset Action only for Root Chassis.
@@ -277,6 +278,14 @@
"EmbeddedLocationContext",
stable_id.embedded_location_context());
}
+ // Populate special devpath field for embedded chassis.
+ if (stable_id.location_type() ==
+ PART_LOCATION_TYPE_EMBEDDED) {
+ resp.SetKeyInJsonBody(
+ chassis_pointer / "Location" / "Oem" / "Google" /
+ "Devpath",
+ stable_id.machine_local_devpath());
+ }
}
nlohmann::json::array_t child_chassis = CreateChildResourceLinksArray(
diff --git a/tlbmc/stable_id.proto b/tlbmc/stable_id.proto
index 84416e3..8fe276b 100644
--- a/tlbmc/stable_id.proto
+++ b/tlbmc/stable_id.proto
@@ -25,4 +25,5 @@
string part_location_context = 2;
string embedded_location_context = 3;
PartLocationType location_type = 4;
+ string machine_local_devpath = 5;
}