[platform] Add serial number and model number to Mellanox PSU platform implementation (#7382)
#### Why I did it We want to add the ability for the command `show platform psustatus` to show the serial number and part number of the PSU devices on Mellanox platforms. This will be useful for data-center management of field replaceable units (FRUs) on switches. #### How I did it I implemented the platform 2.0 functions `get_model()` and `get_serial()` for the PSU in the mellanox platform API by referencing the sysfs nodes provided by the [hw-management](https://github.com/Azure/sonic-buildimage/tree/master/platform/mellanox/hw-management) module.
This commit is contained in:
parent
e52fdcfd72
commit
0bc0f98d48
@ -27,26 +27,40 @@ psu_list = []
|
|||||||
PSU_CURRENT = "current"
|
PSU_CURRENT = "current"
|
||||||
PSU_VOLTAGE = "voltage"
|
PSU_VOLTAGE = "voltage"
|
||||||
PSU_POWER = "power"
|
PSU_POWER = "power"
|
||||||
|
PSU_VPD = "vpd"
|
||||||
|
|
||||||
|
SN_VPD_FIELD = "SN_VPD_FIELD"
|
||||||
|
PN_VPD_FIELD = "PN_VPD_FIELD"
|
||||||
|
|
||||||
# in most platforms the file psuX_curr, psuX_volt and psuX_power contain current, voltage and power data respectively.
|
# in most platforms the file psuX_curr, psuX_volt and psuX_power contain current, voltage and power data respectively.
|
||||||
# but there are exceptions which will be handled by the following dictionary
|
# but there are exceptions which will be handled by the following dictionary
|
||||||
|
|
||||||
platform_dict_psu = {'x86_64-mlnx_msn3420-r0': 1, 'x86_64-mlnx_msn3700-r0': 1, 'x86_64-mlnx_msn3700c-r0': 1,
|
platform_dict_psu = {'x86_64-mlnx_msn3420-r0': 1, 'x86_64-mlnx_msn3700-r0': 1, 'x86_64-mlnx_msn3700c-r0': 1,
|
||||||
'x86_64-mlnx_msn3800-r0': 1, 'x86_64-mlnx_msn4600-r0': 1, 'x86_64-mlnx_msn4600c-r0': 1,
|
'x86_64-mlnx_msn3800-r0': 1, 'x86_64-mlnx_msn4600-r0': 1, 'x86_64-mlnx_msn4600c-r0': 1,
|
||||||
'x86_64-mlnx_msn4700-r0': 1, 'x86_64-mlnx_msn4410-r0': 1}
|
'x86_64-mlnx_msn4700-r0': 1, 'x86_64-mlnx_msn4410-r0': 1, 'x86_64-mlnx_msn2010-r0' : 2,
|
||||||
|
'x86_64-mlnx_msn2100-r0': 2}
|
||||||
|
|
||||||
psu_profile_list = [
|
psu_profile_list = [
|
||||||
# default filename convention
|
# default filename convention
|
||||||
{
|
{
|
||||||
PSU_CURRENT : "power/psu{}_curr",
|
PSU_CURRENT : "power/psu{}_curr",
|
||||||
PSU_VOLTAGE : "power/psu{}_volt",
|
PSU_VOLTAGE : "power/psu{}_volt",
|
||||||
PSU_POWER : "power/psu{}_power"
|
PSU_POWER : "power/psu{}_power",
|
||||||
|
PSU_VPD : "eeprom/psu{}_vpd"
|
||||||
},
|
},
|
||||||
# for 3420, 3700, 3700c, 3800, 4600c, 4700
|
# for 3420, 3700, 3700c, 3800, 4600c, 4700
|
||||||
{
|
{
|
||||||
PSU_CURRENT : "power/psu{}_curr",
|
PSU_CURRENT : "power/psu{}_curr",
|
||||||
PSU_VOLTAGE : "power/psu{}_volt_out2",
|
PSU_VOLTAGE : "power/psu{}_volt_out2",
|
||||||
PSU_POWER : "power/psu{}_power"
|
PSU_POWER : "power/psu{}_power",
|
||||||
|
PSU_VPD : "eeprom/psu{}_vpd"
|
||||||
|
},
|
||||||
|
# for fixed platforms 2100, 2010
|
||||||
|
{
|
||||||
|
PSU_CURRENT : "power/psu{}_curr",
|
||||||
|
PSU_VOLTAGE : "power/psu{}_volt_out2",
|
||||||
|
PSU_POWER : "power/psu{}_power",
|
||||||
|
PSU_VPD : None
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -73,6 +87,27 @@ class Psu(PsuBase):
|
|||||||
filemap = psu_profile_list[0]
|
filemap = psu_profile_list[0]
|
||||||
|
|
||||||
self.psu_data = DEVICE_DATA[platform]['psus']
|
self.psu_data = DEVICE_DATA[platform]['psus']
|
||||||
|
psu_vpd = filemap[PSU_VPD]
|
||||||
|
|
||||||
|
if psu_vpd is not None:
|
||||||
|
self.psu_vpd = os.path.join(self.psu_path, psu_vpd.format(self.index))
|
||||||
|
self.vpd_data = self._read_vpd_file(self.psu_vpd)
|
||||||
|
|
||||||
|
if PN_VPD_FIELD in self.vpd_data:
|
||||||
|
self.model = self.vpd_data[PN_VPD_FIELD]
|
||||||
|
else:
|
||||||
|
self.model = ""
|
||||||
|
logger.log_error("Fail to read PSU{} model number: No key {} in VPD {}".format(self.index, PN_VPD_FIELD, self.psu_vpd))
|
||||||
|
|
||||||
|
if SN_VPD_FIELD in self.vpd_data:
|
||||||
|
self.serial = self.vpd_data[SN_VPD_FIELD]
|
||||||
|
else:
|
||||||
|
self.serial = ""
|
||||||
|
logger.log_error("Fail to read PSU{} serial number: No key {} in VPD {}".format(self.index, SN_VPD_FIELD, self.psu_vpd))
|
||||||
|
|
||||||
|
else:
|
||||||
|
logger.log_info("Not reading PSU{} VPD data: Platform is fixed".format(self.index))
|
||||||
|
|
||||||
|
|
||||||
if not self.psu_data['hot_swappable']:
|
if not self.psu_data['hot_swappable']:
|
||||||
self.always_present = True
|
self.always_present = True
|
||||||
@ -122,6 +157,24 @@ class Psu(PsuBase):
|
|||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
|
|
||||||
|
def _read_vpd_file(self, filename):
|
||||||
|
"""
|
||||||
|
Read a vpd file parsed from eeprom with keys and values.
|
||||||
|
Returns a dictionary.
|
||||||
|
"""
|
||||||
|
result = {}
|
||||||
|
try:
|
||||||
|
if not os.path.exists(filename):
|
||||||
|
return result
|
||||||
|
with open(filename, 'r') as fileobj:
|
||||||
|
for line in fileobj.readlines():
|
||||||
|
key, val = line.split(":")
|
||||||
|
result[key.strip()] = val.strip()
|
||||||
|
except Exception as e:
|
||||||
|
logger.log_error("Fail to read VPD file {} due to {}".format(filename, repr(e)))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def _read_generic_file(self, filename, len):
|
def _read_generic_file(self, filename, len):
|
||||||
"""
|
"""
|
||||||
Read a generic file, returns the contents of the file
|
Read a generic file, returns the contents of the file
|
||||||
@ -137,6 +190,26 @@ class Psu(PsuBase):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def get_model(self):
|
||||||
|
"""
|
||||||
|
Retrieves the model number (or part number) of the device
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
string: Model/part number of device
|
||||||
|
"""
|
||||||
|
return self.model
|
||||||
|
|
||||||
|
|
||||||
|
def get_serial(self):
|
||||||
|
"""
|
||||||
|
Retrieves the serial number of the device
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
string: Serial number of device
|
||||||
|
"""
|
||||||
|
return self.serial
|
||||||
|
|
||||||
|
|
||||||
def get_powergood_status(self):
|
def get_powergood_status(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the operational status of power supply unit (PSU) defined
|
Retrieves the operational status of power supply unit (PSU) defined
|
||||||
|
Reference in New Issue
Block a user