Skip to content

Commit 2773d29

Browse files
Junchao-Mellanoxjudyjoseph
authored andcommitted
[Mellanox] Fix issue: psu might use wrong voltage sysfs which causes invalid voltage value (#10231)
- Why I did it Fix issue: psu might use wrong voltage sysfs which causes invalid voltage value. The flow is like: 1. User power off a PSU 2. All sysfs files related to this PSU are removed 3. User did a reboot/config reload 4. PSU will use wrong sysfs as voltage node - How I did it Always try find an existing sysfs. - How to verify it Manual test
1 parent ef9df9e commit 2773d29

File tree

2 files changed

+52
-11
lines changed

2 files changed

+52
-11
lines changed

platform/mellanox/mlnx-platform-api/sonic_platform/psu.py

+46-11
Original file line numberDiff line numberDiff line change
@@ -200,16 +200,10 @@ class Psu(FixedPsu):
200200
def __init__(self, psu_index):
201201
super(Psu, self).__init__(psu_index)
202202

203-
psu_voltage_out2 = os.path.join(PSU_PATH, "power/psu{}_volt_out2".format(self.index))
204-
psu_voltage = os.path.join(PSU_PATH, "power/psu{}_volt".format(self.index))
205-
# Workaround for psu voltage sysfs file as the file name differs among platforms
206-
if os.path.exists(psu_voltage_out2):
207-
self.psu_voltage = psu_voltage_out2
208-
else:
209-
self.psu_voltage = psu_voltage
210-
self.psu_voltage_min = self.psu_voltage + "_min"
211-
self.psu_voltage_max = self.psu_voltage + "_max"
212-
self.psu_voltage_capability = self.psu_voltage + "_capability"
203+
self._psu_voltage = None
204+
self._psu_voltage_min = None
205+
self._psu_voltage_max = None
206+
self._psu_voltage_capability = None
213207

214208
self.psu_current = os.path.join(PSU_PATH, self.PSU_CURRENT.format(self.index))
215209
self.psu_power = os.path.join(PSU_PATH, self.PSU_POWER.format(self.index))
@@ -228,6 +222,47 @@ def __init__(self, psu_index):
228222
from .thermal import initialize_psu_thermal
229223
self._thermal_list = initialize_psu_thermal(psu_index, self.get_power_available_status)
230224

225+
@property
226+
def psu_voltage(self):
227+
if not self._psu_voltage:
228+
psu_voltage_out = os.path.join(PSU_PATH, "power/psu{}_volt_out2".format(self.index))
229+
if os.path.exists(psu_voltage_out):
230+
self._psu_voltage = psu_voltage_out
231+
else:
232+
psu_voltage_out = os.path.join(PSU_PATH, "power/psu{}_volt".format(self.index))
233+
if os.path.exists(psu_voltage_out):
234+
self._psu_voltage = psu_voltage_out
235+
236+
return self._psu_voltage
237+
238+
@property
239+
def psu_voltage_min(self):
240+
if not self._psu_voltage_min:
241+
psu_voltage = self.psu_voltage
242+
if psu_voltage:
243+
self._psu_voltage_min = psu_voltage + "_min"
244+
245+
return self._psu_voltage_min
246+
247+
@property
248+
def psu_voltage_max(self):
249+
if not self._psu_voltage_max:
250+
psu_voltage = self.psu_voltage
251+
if psu_voltage:
252+
self._psu_voltage_max = psu_voltage + "_max"
253+
254+
return self._psu_voltage_max
255+
256+
@property
257+
def psu_voltage_capability(self):
258+
if not self._psu_voltage_capability:
259+
psu_voltage = self.psu_voltage
260+
if psu_voltage:
261+
self._psu_voltage_capability = psu_voltage + "_capability"
262+
263+
return self._psu_voltage_capability
264+
265+
231266
def get_model(self):
232267
"""
233268
Retrieves the model number (or part number) of the device
@@ -272,7 +307,7 @@ def get_voltage(self):
272307
A float number, the output voltage in volts,
273308
e.g. 12.1
274309
"""
275-
if self.get_powergood_status():
310+
if self.get_powergood_status() and self.psu_voltage:
276311
# TODO: should we put log_func=None here? If not do this, when a PSU is back to power, some PSU related
277312
# sysfs may not ready, read_int_from_file would encounter exception and log an error.
278313
voltage = utils.read_int_from_file(self.psu_voltage, log_func=logger.log_info)

platform/mellanox/mlnx-platform-api/tests/test_psu.py

+6
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ def test_fixed_psu(self):
5050
assert psu.get_temperature() is None
5151
assert psu.get_temperature_high_threshold() is None
5252

53+
@mock.patch('os.path.exists', mock.MagicMock(return_value=True))
5354
def test_psu(self):
5455
psu = Psu(0)
5556
assert len(psu._fan_list) == 1
@@ -58,6 +59,8 @@ def test_psu(self):
5859
psu.psu_presence: 1,
5960
psu.psu_oper_status: 1,
6061
psu.psu_voltage: 10234,
62+
psu.psu_voltage_min: 9000,
63+
psu.psu_voltage_max: 12000,
6164
psu.psu_current: 20345,
6265
psu.psu_power: 30456,
6366
psu.psu_temp: 40567,
@@ -68,6 +71,7 @@ def mock_read_int_from_file(file_path, **kwargs):
6871
return mock_sysfs_content[file_path]
6972

7073
utils.read_int_from_file = mock_read_int_from_file
74+
utils.read_str_from_file = mock.MagicMock(return_value='min max')
7175
assert psu.get_presence() is True
7276
mock_sysfs_content[psu.psu_presence] = 0
7377
assert psu.get_presence() is False
@@ -84,6 +88,8 @@ def mock_read_int_from_file(file_path, **kwargs):
8488

8589
mock_sysfs_content[psu.psu_oper_status] = 1
8690
assert psu.get_voltage() == 10.234
91+
assert psu.get_voltage_high_threshold() == 12.0
92+
assert psu.get_voltage_low_threshold() == 9.0
8793
assert psu.get_current() == 20.345
8894
assert psu.get_power() == 0.030456
8995
assert psu.get_temperature() == 40.567

0 commit comments

Comments
 (0)