Skip to content

Commit fd4b140

Browse files
Junchao-Mellanoxmssonicbld
authored andcommitted
[Mellanox] Check system eeprom existence in a retry manner (sonic-net#13884)
- Why I did it On Mellanox platform, system EEPROM is a soft link provided by hw-management. There is chance that config-setup service accessing the EEPROM before hw-management creating it. It causes errors. The PR is aim to fix it. - How I did it Waiting EEPROM creation in platform API up to 10 seconds. - How to verify it Manual test
1 parent b51de79 commit fd4b140

File tree

4 files changed

+42
-4
lines changed

4 files changed

+42
-4
lines changed

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

+5-3
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@
3131
raise ImportError (str(e) + "- required module not found")
3232

3333
from .device_data import DeviceDataManager
34-
from .utils import default_return, is_host
34+
from .utils import default_return, is_host, wait_until
3535

3636
logger = Logger()
3737

3838
#
3939
# this is mlnx-specific
40-
# should this be moved to chass.py or here, which better?
40+
# should this be moved to chassis.py or here, which better?
4141
#
4242
EEPROM_SYMLINK = "/var/run/hw-management/eeprom/vpd_info"
4343
platform_name = DeviceDataManager.get_platform_name()
@@ -51,10 +51,12 @@
5151
os.makedirs(os.path.dirname(EEPROM_SYMLINK))
5252
subprocess.check_call(['/usr/bin/xxd', '-r', '-p', 'syseeprom.hex', EEPROM_SYMLINK], cwd=platform_path)
5353

54+
WAIT_EEPROM_READY_SEC = 10
55+
5456

5557
class Eeprom(eeprom_tlvinfo.TlvInfoDecoder):
5658
def __init__(self):
57-
if not os.path.exists(EEPROM_SYMLINK):
59+
if not wait_until(predict=os.path.exists, timeout=WAIT_EEPROM_READY_SEC, path=EEPROM_SYMLINK):
5860
logger.log_error("Nowhere to read syseeprom from! No symlink found")
5961
raise RuntimeError("No syseeprom symlink found")
6062

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

+19
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import subprocess
2020
import json
2121
import sys
22+
import time
2223
import os
2324
from sonic_py_common import device_info
2425
from sonic_py_common.logger import Logger
@@ -266,3 +267,21 @@ def extract_RJ45_ports_index():
266267

267268
return RJ45_port_index_list if bool(RJ45_port_index_list) else None
268269

270+
271+
def wait_until(predict, timeout, interval=1, *args, **kwargs):
272+
"""Wait until a condition become true
273+
274+
Args:
275+
predict (object): a callable such as function, lambda
276+
timeout (int): wait time in seconds
277+
interval (int, optional): interval to check the predict. Defaults to 1.
278+
279+
Returns:
280+
_type_: _description_
281+
"""
282+
while timeout > 0:
283+
if predict(*args, **kwargs):
284+
return True
285+
time.sleep(interval)
286+
timeout -= interval
287+
return False

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ def test_chassis_eeprom(self, mock_eeprom_info):
4949
assert chassis.get_serial() == 'MT2019X13878'
5050
assert chassis.get_system_eeprom_info() == mock_eeprom_info.return_value
5151

52+
@patch('sonic_platform.eeprom.wait_until', MagicMock(return_value=False))
5253
def test_eeprom_init(self):
5354
# Test symlink not exist, there is an exception
5455
with pytest.raises(RuntimeError):
@@ -83,7 +84,7 @@ def side_effect(key, field):
8384

8485
@patch('os.path.exists', MagicMock(return_value=True))
8586
@patch('os.path.islink', MagicMock(return_value=True))
86-
def test_get_system_eeprom_info_from_hardware(self):
87+
def test_get_system_eeprom_info_from_hardware(self):
8788
eeprom = Eeprom()
8889
eeprom.p = os.path.join(test_path, 'mock_eeprom_data')
8990
eeprom._redis_hget = MagicMock()

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

+16
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import os
1919
import pytest
2020
import sys
21+
import threading
22+
import time
2123
if sys.version_info.major == 3:
2224
from unittest import mock
2325
else:
@@ -125,3 +127,17 @@ def test_run_command(self):
125127
def test_extract_RJ45_ports_index(self):
126128
rj45_list = utils.extract_RJ45_ports_index()
127129
assert rj45_list is None
130+
131+
def test_wait_until(self):
132+
values = []
133+
assert utils.wait_until(lambda: len(values) == 0, timeout=1)
134+
assert not utils.wait_until(lambda: len(values) > 0, timeout=1)
135+
136+
def thread_func(items):
137+
time.sleep(3)
138+
items.append(0)
139+
140+
t = threading.Thread(target=thread_func, args=(values, ))
141+
t.start()
142+
assert utils.wait_until(lambda: len(values) > 0, timeout=5)
143+
t.join()

0 commit comments

Comments
 (0)