6
6
#
7
7
#############################################################################
8
8
import os
9
- import sys
10
- import re
11
9
import time
12
10
13
- if sys .version_info .major == 3 :
14
- from io import StringIO
15
- else :
16
- from cStringIO import StringIO
17
-
18
11
from sonic_py_common .logger import Logger
19
12
20
13
try :
21
14
from sonic_platform_base .sonic_eeprom import eeprom_tlvinfo
22
15
except ImportError as e :
23
16
raise ImportError (str (e ) + "- required module not found" )
24
17
25
- logger = Logger ()
18
+ from . utils import default_return
26
19
27
- #
28
- # CACHE_XXX stuffs are supposted to be moved to the base classes
29
- # since they are common for all vendors
30
- # they are defined in decode-syseeprom which might be removed in the future
31
- # currently we just copy them here
32
- #
33
- CACHE_ROOT = '/var/cache/sonic/decode-syseeprom'
34
- CACHE_FILE = 'syseeprom_cache'
20
+ logger = Logger ()
35
21
36
22
#
37
23
# this is mlnx-specific
41
27
42
28
class Eeprom (eeprom_tlvinfo .TlvInfoDecoder ):
43
29
RETRIES = 3
44
- EEPROM_DECODE_HEADLINES = 6
45
- EEPROM_DECODE_MAXITEM = 3
46
- EEPROM_DECODE_OFFSET = 0
47
- EEPROM_DECODE_CONTENT = 2
48
30
49
31
def __init__ (self ):
50
32
for attempt in range (self .RETRIES ):
@@ -53,95 +35,15 @@ def __init__(self):
53
35
else :
54
36
break
55
37
56
- if not (os .path .exists (EEPROM_SYMLINK ) \
57
- or os .path .isfile (os .path .join (CACHE_ROOT , CACHE_FILE ))):
58
- log_error ("Nowhere to read syseeprom from! No symlink or cache file found" )
38
+ if not os .path .exists (EEPROM_SYMLINK ):
39
+ logger .log_error ("Nowhere to read syseeprom from! No symlink or cache file found" )
59
40
raise RuntimeError ("No syseeprom symlink or cache file found" )
60
41
61
42
self .eeprom_path = EEPROM_SYMLINK
62
43
super (Eeprom , self ).__init__ (self .eeprom_path , 0 , '' , True )
63
- self ._eeprom_loaded = False
64
- self ._load_eeprom ()
65
- self ._eeprom_loaded = True
66
-
67
- def _load_eeprom (self ):
68
- cache_file = os .path .join (CACHE_ROOT , CACHE_FILE )
69
- if not os .path .exists (CACHE_ROOT ):
70
- try :
71
- os .makedirs (CACHE_ROOT )
72
- except :
73
- pass
74
- else :
75
- try :
76
- # Make sure first time always read eeprom data from hardware
77
- if os .path .exists (cache_file ):
78
- os .remove (cache_file )
79
- except Exception as e :
80
- logger .log_error ('Failed to remove cache file {} - {}' .format (cache_file , repr (e )))
81
-
82
- try :
83
- self .set_cache_name (cache_file )
84
- except :
85
- pass
86
-
87
- eeprom = self .read_eeprom ()
88
- if eeprom is None :
89
- return 0
90
-
91
- try :
92
- self .update_cache (eeprom )
93
- except :
94
- pass
95
-
96
- self ._base_mac = self .mgmtaddrstr (eeprom )
97
- if self ._base_mac is None :
98
- self ._base_mac = "Undefined."
99
- else :
100
- self ._base_mac = self ._base_mac .strip ('\0 ' )
101
-
102
- self ._serial_str = self .serial_number_str (eeprom )
103
- if self ._serial_str is None :
104
- self ._serial_str = "Undefined."
105
- else :
106
- self ._serial_str = self ._serial_str .strip ('\0 ' )
107
-
108
- self ._product_name = self .modelstr (eeprom )
109
- if self ._product_name is None :
110
- self ._product_name = "Undefined."
111
- else :
112
- self ._product_name = self ._product_name .strip ('\0 ' )
113
-
114
- self ._part_number = self .part_number_str (eeprom )
115
- if self ._part_number is None :
116
- self ._part_number = "Undefined."
117
- else :
118
- self ._part_number = self ._part_number .strip ('\0 ' )
119
-
120
- original_stdout = sys .stdout
121
- sys .stdout = StringIO ()
122
- self .decode_eeprom (eeprom )
123
- decode_output = sys .stdout .getvalue ()
124
- sys .stdout = original_stdout
125
-
126
- #parse decode_output into a dictionary
127
- decode_output .replace ('\0 ' , '' )
128
- lines = decode_output .split ('\n ' )
129
- lines = lines [self .EEPROM_DECODE_HEADLINES :]
130
- self ._eeprom_info_dict = dict ()
131
-
132
- for line in lines :
133
- try :
134
- match = re .search ('(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+[\s]*[\S]*)' , line )
135
- if match is not None :
136
- idx = match .group (1 )
137
- value = match .group (3 ).rstrip ('\0 ' )
138
-
139
- self ._eeprom_info_dict [idx ] = value
140
- except :
141
- pass
142
-
143
- return 0
44
+ self ._eeprom_info_dict = None
144
45
46
+ @default_return (return_value = 'Undefined.' )
145
47
def get_base_mac (self ):
146
48
"""
147
49
Retrieves the base MAC address for the chassis
@@ -150,43 +52,39 @@ def get_base_mac(self):
150
52
A string containing the MAC address in the format
151
53
'XX:XX:XX:XX:XX:XX'
152
54
"""
153
- if not self ._eeprom_loaded :
154
- self ._load_eeprom ()
155
- return self ._base_mac
156
-
55
+ return self ._get_eeprom_value (self ._TLV_CODE_MAC_BASE )
56
+
57
+ @default_return (return_value = 'Undefined.' )
157
58
def get_serial_number (self ):
158
59
"""
159
60
Retrieves the hardware serial number for the chassis
160
61
161
62
Returns:
162
63
A string containing the hardware serial number for this chassis.
163
64
"""
164
- if not self ._eeprom_loaded :
165
- self ._load_eeprom ()
166
- return self ._serial_str
65
+ return self ._get_eeprom_value (self ._TLV_CODE_SERIAL_NUMBER )
167
66
67
+ @default_return (return_value = 'Undefined.' )
168
68
def get_product_name (self ):
169
69
"""
170
70
Retrieves the hardware product name for the chassis
171
71
172
72
Returns:
173
73
A string containing the hardware product name for this chassis.
174
74
"""
175
- if not self ._eeprom_loaded :
176
- self ._load_eeprom ()
177
- return self ._product_name
75
+ return self ._get_eeprom_value (self ._TLV_CODE_PRODUCT_NAME )
178
76
77
+ @default_return (return_value = 'Undefined.' )
179
78
def get_part_number (self ):
180
79
"""
181
80
Retrieves the hardware part number for the chassis
182
81
183
82
Returns:
184
83
A string containing the hardware part number for this chassis.
185
84
"""
186
- if not self ._eeprom_loaded :
187
- self ._load_eeprom ()
188
- return self ._part_number
85
+ return self ._get_eeprom_value (self ._TLV_CODE_PART_NUMBER )
189
86
87
+ @default_return ({})
190
88
def get_system_eeprom_info (self ):
191
89
"""
192
90
Retrieves the full content of system EEPROM information for the chassis
@@ -196,6 +94,72 @@ def get_system_eeprom_info(self):
196
94
OCP ONIE TlvInfo EEPROM format and values are their corresponding
197
95
values.
198
96
"""
199
- if not self ._eeprom_loaded :
200
- self ._load_eeprom ()
97
+ if self ._eeprom_info_dict is None :
98
+ self ._eeprom_info_dict = {}
99
+
100
+ # Try get from DB first
101
+ db_initialized = self ._redis_hget ('EEPROM_INFO|State' , 'Initialized' )
102
+ if db_initialized == '1' :
103
+ code = self ._TLV_CODE_PRODUCT_NAME
104
+ while code <= self ._TLV_CODE_SERVICE_TAG :
105
+ value = self ._redis_hget ('EEPROM_INFO|{}' .format (hex (code )), 'Value' )
106
+ if value :
107
+ self ._eeprom_info_dict [hex (code )] = value
108
+ code += 1
109
+
110
+ # Handle vendor extension TLV
111
+ vendor_extension_tlv_code = hex (self ._TLV_CODE_VENDOR_EXT )
112
+ try :
113
+ vendor_extension_num = int (self ._redis_hget ('EEPROM_INFO|{}' .format (vendor_extension_tlv_code ), 'Num_vendor_ext' ))
114
+ except (ValueError , TypeError ):
115
+ vendor_extension_num = 0
116
+
117
+ if vendor_extension_num != 0 :
118
+ for i in range (vendor_extension_num ):
119
+ value = self ._redis_hget ('EEPROM_INFO|{}' .format (vendor_extension_tlv_code ), 'Value_{}' .format (i ))
120
+ if value :
121
+ if vendor_extension_tlv_code not in self ._eeprom_info_dict :
122
+ self ._eeprom_info_dict [vendor_extension_tlv_code ] = [value ]
123
+ else :
124
+ self ._eeprom_info_dict [vendor_extension_tlv_code ].append (value )
125
+
126
+ # Get CRC
127
+ value = self ._redis_hget ('EEPROM_INFO|{}' .format (hex (self ._TLV_CODE_CRC_32 )), 'Value' )
128
+ if value :
129
+ self ._eeprom_info_dict [hex (self ._TLV_CODE_CRC_32 )] = value
130
+ else :
131
+ eeprom = self .read_eeprom ()
132
+ visitor = EepromContentVisitor (self ._eeprom_info_dict )
133
+ self .visit_eeprom (eeprom , visitor )
201
134
return self ._eeprom_info_dict
135
+
136
+ def _get_eeprom_value (self , code ):
137
+ """Helper function to help get EEPROM data by code
138
+
139
+ Args:
140
+ code (int): EEPROM TLV code
141
+
142
+ Returns:
143
+ str: value of EEPROM TLV
144
+ """
145
+ eeprom_info_dict = self .get_system_eeprom_info ()
146
+ return eeprom_info_dict [hex (code )]
147
+
148
+
149
+ class EepromContentVisitor (eeprom_tlvinfo .EepromDefaultVisitor ):
150
+ def __init__ (self , content ):
151
+ self .content = content
152
+
153
+ def visit_tlv (self , name , code , length , value ):
154
+ if code != Eeprom ._TLV_CODE_VENDOR_EXT :
155
+ self .content [hex (code )] = value .rstrip ('\0 ' )
156
+ else :
157
+ if value :
158
+ value = value .rstrip ('\0 ' )
159
+ if value :
160
+ code = hex (code )
161
+ if code not in self .content :
162
+ self .content [code ] = [value ]
163
+ else :
164
+ self .content [code ].append (value )
165
+
0 commit comments