Skip to content

Commit

Permalink
[Mellanox] Enhance Platform API to support SN2201 - RJ45 ports and ne…
Browse files Browse the repository at this point in the history
…w components mgmt. (sonic-net#10377)

* Support new platform SN2201 and RJ45 port

Signed-off-by: Kebo Liu <kebol@nvidia.com>

* remove unused import and redundant function

Signed-off-by: Kebo Liu <kebol@nvidia.com>

* fix error introduced by rebase

Signed-off-by: Kebo Liu <kebol@nvidia.com>

* Revert the special handling of RJ45 ports (zhenggen-xu#56)

* Revert the special handling of RJ45 ports

sfp.py
sfp_event.py
chassis.py

Signed-off-by: Stephen Sun <stephens@nvidia.com>

* Remove deadcode

Signed-off-by: Stephen Sun <stephens@nvidia.com>

* Support CPLD update for SN2201

A new class is introduced, deriving from ComponentCPLD and overloading _install_firmware
Change _install_firmware from private (starting with __) to protected, making it overloadable

Signed-off-by: Stephen Sun <stephens@nvidia.com>

* Initialize component BIOS/CPLD

Signed-off-by: Stephen Sun <stephens@nvidia.com>

* Remove swb_amb which doesn't on DVT board any more

Signed-off-by: Stephen Sun <stephens@nvidia.com>

* Remove the unexisted sensor - switch board ambient - from platform.json

Signed-off-by: Stephen Sun <stephens@nvidia.com>

* Do not report error on receiving unknown status on RJ45 ports

Translate it to disconnect for RJ45 ports
Report error for xSFP ports

Signed-off-by: Stephen Sun <stephens@nvidia.com>

* Add reinit for RJ45 to avoid exception

Signed-off-by: Stephen Sun <stephens@nvidia.com>

Co-authored-by: Stephen Sun <5379172+stephenxs@users.noreply.github.com>
Co-authored-by: Stephen Sun <stephens@nvidia.com>
3 people authored Jun 21, 2022
1 parent fdc65d7 commit 7ac590b
Showing 15 changed files with 570 additions and 65 deletions.
3 changes: 0 additions & 3 deletions device/mellanox/x86_64-nvidia_sn2201-r0/platform.json
Original file line number Diff line number Diff line change
@@ -90,9 +90,6 @@
{
"name": "Ambient CPU Board Temp"
},
{
"name": "Ambient Switch Board Temp"
},
{
"name": "CPU Pack Temp"
},
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@
"component": {
"ONIE": { },
"SSD": { },
"BIOS": { },
"CPLD1": { },
"CPLD2": { }
}
33 changes: 25 additions & 8 deletions platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py
Original file line number Diff line number Diff line change
@@ -27,14 +27,17 @@
from sonic_py_common.logger import Logger
import os
from functools import reduce

from .utils import extract_RJ45_ports_index
from . import utils
from .device_data import DeviceDataManager
from .sfp import SFP, RJ45Port, deinitialize_sdk_handle
except ImportError as e:
raise ImportError (str(e) + "- required module not found")

MAX_SELECT_DELAY = 3600

RJ45_TYPE = "RJ45"

DMI_FILE = '/sys/firmware/dmi/entries/2-0/raw'
DMI_HEADER_LEN = 15
DMI_PRODUCT_NAME = "Product Name"
@@ -106,6 +109,10 @@ def __init__(self):
self.sfp_initialized_count = 0
self.sfp_event = None
self.reboot_cause_initialized = False

# Build the RJ45 port list from platform.json and hwsku.json
self.RJ45_port_list = extract_RJ45_ports_index()

logger.log_info("Chassis loaded successfully")

def __del__(self):
@@ -242,22 +249,31 @@ def initialize_single_sfp(self, index):

if not self._sfp_list[index]:
from .sfp import SFP
self._sfp_list[index] = SFP(index)
if self.RJ45_port_list and index in self.RJ45_port_list:
self._sfp_list[index] = RJ45Port(index)
else:
self._sfp_list[index] = SFP(index)
self.sfp_initialized_count += 1

def initialize_sfp(self):
if not self._sfp_list:
from .sfp import SFP
sfp_count = self.get_num_sfps()
for index in range(sfp_count):
sfp_module = SFP(index)
if self.RJ45_port_list and index in self.RJ45_port_list:
sfp_module = RJ45Port(index)
else:
sfp_module = SFP(index)
self._sfp_list.append(sfp_module)
self.sfp_initialized_count = sfp_count
elif self.sfp_initialized_count != len(self._sfp_list):
from .sfp import SFP
for index in range(len(self._sfp_list)):
if self._sfp_list[index] is None:
self._sfp_list[index] = SFP(index)
if self.RJ45_port_list and index in self.RJ45_port_list:
self._sfp_list[index] = RJ45Port(index)
else:
self._sfp_list[index] = SFP(index)
self.sfp_initialized_count = len(self._sfp_list)

def get_num_sfps(self):
@@ -324,7 +340,7 @@ def get_change_event(self, timeout=0):
# Initialize SFP event first
if not self.sfp_event:
from .sfp_event import sfp_event
self.sfp_event = sfp_event()
self.sfp_event = sfp_event(self.RJ45_port_list)
self.sfp_event.initialize()

wait_for_ever = (timeout == 0)
@@ -340,7 +356,8 @@ def get_change_event(self, timeout=0):
status = self.sfp_event.check_sfp_status(port_dict, error_dict, timeout)

if status:
self.reinit_sfps(port_dict)
if port_dict:
self.reinit_sfps(port_dict)
result_dict = {'sfp':port_dict}
if error_dict:
result_dict['sfp_error'] = error_dict
@@ -515,8 +532,8 @@ def initialize_components(self):
from .component import ComponentONIE, ComponentSSD, ComponentBIOS, ComponentCPLD
self._component_list.append(ComponentONIE())
self._component_list.append(ComponentSSD())
self._component_list.append(ComponentBIOS())
self._component_list.extend(ComponentCPLD.get_component_list())
self._component_list.append(DeviceDataManager.get_bios_component())
self._component_list.extend(DeviceDataManager.get_cpld_component_list())

def get_num_components(self):
"""
71 changes: 66 additions & 5 deletions platform/mellanox/mlnx-platform-api/sonic_platform/component.py
Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@
import glob
import tempfile
import subprocess
from sonic_py_common import device_info
if sys.version_info[0] > 2:
import configparser
else:
@@ -136,7 +137,17 @@ class ONIEUpdater(object):

ONIE_IMAGE_INFO_COMMAND = '/bin/bash {} -q -i'

# Upgrading fireware from ONIE is not supported from the beginning on some platforms, like SN2700.
# There is a logic to check the ONIE version in order to know whether it is supported.
# If it is not supported, we will not proceed and print some error message.
# For SN2201, upgrading fireware from ONIE is supported from day one so we do not need to check it.
PLATFORM_ALWAYS_SUPPORT_UPGRADE = ['x86_64-nvidia_sn2201-r0']

BIOS_UPDATE_FILE_EXT = '.rom'


def __init__(self):
self.platform = device_info.get_platform()

def __add_prefix(self, image_path):
if self.BIOS_UPDATE_FILE_EXT not in image_path:
@@ -336,6 +347,9 @@ def update_firmware(self, image_path, allow_reboot=True):
raise

def is_non_onie_firmware_update_supported(self):
if self.platform in self.PLATFORM_ALWAYS_SUPPORT_UPGRADE:
return True

current_version = self.get_onie_version()
_, _, major1, minor1, release1, _ = self.parse_onie_version(current_version)
version1 = int("{}{}{}".format(major1, minor1, release1))
@@ -698,6 +712,37 @@ def update_firmware(self, image_path):
self.__install_firmware(image_path)


class ComponentBIOSSN2201(Component):
COMPONENT_NAME = 'BIOS'
COMPONENT_DESCRIPTION = 'BIOS - Basic Input/Output System'

BIOS_VERSION_COMMAND = 'dmidecode -t0'

def __init__(self):
super(ComponentBIOSSN2201, self).__init__()

self.name = self.COMPONENT_NAME
self.description = self.COMPONENT_DESCRIPTION

def get_firmware_version(self):
cmd = self.BIOS_VERSION_COMMAND

try:
output = subprocess.check_output(cmd.split(),
stderr=subprocess.STDOUT,
universal_newlines=True).rstrip('\n')
except subprocess.CalledProcessError as e:
raise RuntimeError("Failed to get {} version: {}".format(self.name, str(e)))

match = re.search('Version: (.*)', output)
if match:
version = match.group(1)
else:
version = 'Unknown version'

return version


class ComponentCPLD(Component):
COMPONENT_NAME = 'CPLD{}'
COMPONENT_DESCRIPTION = 'CPLD - Complex Programmable Logic Device'
@@ -744,7 +789,7 @@ def __get_mst_device(self):

return mst_dev_list[0]

def __install_firmware(self, image_path):
def _install_firmware(self, image_path):
if not self._check_file_validity(image_path):
return False

@@ -830,9 +875,9 @@ def install_firmware(self, image_path):
burn_firmware = mpfa.get_metadata().get('firmware', 'burn')

print("INFO: Processing {} burn file: firmware install".format(self.name))
return self.__install_firmware(os.path.join(mpfa.get_path(), burn_firmware))
return self._install_firmware(os.path.join(mpfa.get_path(), burn_firmware))
else:
return self.__install_firmware(image_path)
return self._install_firmware(image_path)

def update_firmware(self, image_path):
with MPFAManager(image_path) as mpfa:
@@ -845,11 +890,11 @@ def update_firmware(self, image_path):
refresh_firmware = mpfa.get_metadata().get('firmware', 'refresh')

print("INFO: Processing {} burn file: firmware install".format(self.name))
if not self.__install_firmware(os.path.join(mpfa.get_path(), burn_firmware)):
if not self._install_firmware(os.path.join(mpfa.get_path(), burn_firmware)):
return

print("INFO: Processing {} refresh file: firmware update".format(self.name))
self.__install_firmware(os.path.join(mpfa.get_path(), refresh_firmware))
self._install_firmware(os.path.join(mpfa.get_path(), refresh_firmware))

@classmethod
def get_component_list(cls):
@@ -862,3 +907,19 @@ def get_component_list(cls):
component_list.append(cls(cpld_idx))

return component_list


class ComponentCPLDSN2201(ComponentCPLD):
CPLD_FIRMWARE_UPDATE_COMMAND = 'cpldupdate --gpio {} --uncustomized --print-progress'

def _install_firmware(self, image_path):
cmd = self.CPLD_FIRMWARE_UPDATE_COMMAND.format(image_path)

try:
print("INFO: Installing {} firmware update: path={}".format(self.name, image_path))
subprocess.check_call(cmd.split(), universal_newlines=True)
except subprocess.CalledProcessError as e:
print("ERROR: Failed to update {} firmware: {}".format(self.name, str(e)))
return False

return True
21 changes: 19 additions & 2 deletions platform/mellanox/mlnx-platform-api/sonic_platform/device_data.py
Original file line number Diff line number Diff line change
@@ -158,8 +158,7 @@
'thermal': {
"capability": {
"comex_amb": False,
"cpu_amb": True,
"swb_amb": True
"cpu_amb": True
}
}
},
@@ -281,3 +280,21 @@ def get_cpu_thermal_threshold(cls):
return None, None

return thermal_data.get('cpu_threshold', (None, None))

@classmethod
def get_bios_component(cls):
from .component import ComponentBIOS, ComponentBIOSSN2201
if cls.get_platform_name() in ['x86_64-nvidia_sn2201-r0']:
# For SN2201, special chass is required for handle BIOS
# Currently, only fetching BIOS version is supported
return ComponentBIOSSN2201()
return ComponentBIOS()

@classmethod
def get_cpld_component_list(cls):
from .component import ComponentCPLD, ComponentCPLDSN2201
if cls.get_platform_name() in ['x86_64-nvidia_sn2201-r0']:
# For SN2201, special chass is required for handle BIOS
# Currently, only fetching BIOS version is supported
return ComponentCPLDSN2201.get_component_list()
return ComponentCPLD.get_component_list()
355 changes: 324 additions & 31 deletions platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py

Large diffs are not rendered by default.

19 changes: 18 additions & 1 deletion platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py
Original file line number Diff line number Diff line change
@@ -50,6 +50,7 @@ class MockSxFd(object):
SDK_SFP_STATE_OUT = 0x2
SDK_SFP_STATE_ERR = 0x3
SDK_SFP_STATE_DIS = 0x4
SDK_SFP_STATE_UNKNOWN = 0x5

# SFP status used in this file only, will not expose to XCVRD
# STATUS_ERROR will be mapped to different status according to the error code
@@ -134,13 +135,17 @@ class sfp_event:
SX_OPEN_TIMEOUT = 5
SELECT_TIMEOUT = 1

def __init__(self):
def __init__(self, rj45_port_list=None):
self.swid = 0
self.handle = None

# Allocate SDK fd and user channel structures
self.rx_fd_p = new_sx_fd_t_p()
self.user_channel_p = new_sx_user_channel_t_p()
if rj45_port_list:
self.RJ45_port_set = set(rj45_port_list)
else:
self.RJ45_port_set = set()

def initialize(self):
swid_cnt_p = None
@@ -340,6 +345,7 @@ def on_pmpe(self, fd_p):
status = False
else:
status = True
unknown = False
pmpe_t = recv_info_p.event_info.pmpe
port_list_size = pmpe_t.list_size
logical_port_list = pmpe_t.log_port_list
@@ -354,8 +360,11 @@ def on_pmpe(self, fd_p):
logger.log_info("Receive PMPE disable event on module {}: status {}".format(module_id, module_state))
elif module_state == SDK_SFP_STATE_IN or module_state == SDK_SFP_STATE_OUT:
logger.log_info("Receive PMPE plug in/out event on module {}: status {}".format(module_id, module_state))
elif module_state == SDK_SFP_STATE_UNKNOWN:
unknown = True
else:
logger.log_error("Receive PMPE unknown event on module {}: status {}".format(module_id, module_state))

for i in range(port_list_size):
logical_port = sx_port_log_id_t_arr_getitem(logical_port_list, i)
rc = sx_api_port_device_get(self.handle, 1 , 0, port_attributes_list, port_cnt_p)
@@ -369,6 +378,14 @@ def on_pmpe(self, fd_p):
if label_port is not None:
label_port_list.append(label_port)

if unknown:
SFP_ports_with_unknown_event = set(label_port_list) - self.RJ45_port_set
if SFP_ports_with_unknown_event:
logger.log_error("Receive PMPE unknown event on module {}: status {}".format(module_id, module_state))
else:
# For RJ45 ports, we treat unknown as disconnect
module_state = SDK_SFP_STATE_DIS

delete_uint32_t_p(pkt_size_p)
delete_uint8_t_arr(pkt)
delete_sx_receive_info_t_p(recv_info_p)
59 changes: 58 additions & 1 deletion platform/mellanox/mlnx-platform-api/sonic_platform/utils.py
Original file line number Diff line number Diff line change
@@ -16,8 +16,18 @@
#
import functools
import subprocess
import json
import sys
import os
from sonic_py_common import device_info
from sonic_py_common.logger import Logger

HWSKU_JSON = 'hwsku.json'

PORT_INDEX_KEY = "index"
PORT_TYPE_KEY = "port_type"
RJ45_PORT_TYPE = "RJ45"

logger = Logger()


@@ -206,4 +216,51 @@ def run_command(command):
process = subprocess.Popen(command, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return process.communicate()[0].strip()
except Exception:
return None
return None


def load_json_file(filename, log_func=logger.log_error):
# load 'platform.json' or 'hwsku.json' file
data = None
try:
with open(filename) as fp:
try:
data = json.load(fp)
except json.JSONDecodeError:
if log_func:
log_func("failed to decode Json file.")
return data
except Exception as e:
if log_func:
log_func("error occurred while parsing json file: {}".format(sys.exc_info()[1]))
return None


def extract_RJ45_ports_index():
# Cross check 'platform.json' and 'hwsku.json' to extract the RJ45 port index if exists.
hwsku_path = device_info.get_path_to_hwsku_dir()
platform_file = device_info.get_path_to_port_config_file()
platform_dict = load_json_file(platform_file)['interfaces']
hwsku_file = os.path.join(hwsku_path, HWSKU_JSON)
hwsku_dict = load_json_file(hwsku_file)['interfaces']
port_name_to_index_map_dict = {}
RJ45_port_index_list = []

# Compose a interface name to index mapping from 'platform.json'
for i, (key, value) in enumerate(platform_dict.items()):
if PORT_INDEX_KEY in value:
index_raw = value[PORT_INDEX_KEY]
# The index could be "1" or "1, 1, 1, 1"
index = index_raw.split(',')[0]
port_name_to_index_map_dict[key] = index

if not bool(port_name_to_index_map_dict):
return None

# Check if "port_type" specified as "RJ45", if yes, add the port index to the list.
for i, (key, value) in enumerate(hwsku_dict.items()):
if key in port_name_to_index_map_dict and PORT_TYPE_KEY in value and value[PORT_TYPE_KEY] == RJ45_PORT_TYPE:
RJ45_port_index_list.append(int(port_name_to_index_map_dict[key])-1)

return RJ45_port_index_list if bool(RJ45_port_index_list) else None

2 changes: 2 additions & 0 deletions platform/mellanox/mlnx-platform-api/tests/test_chassis.py
Original file line number Diff line number Diff line change
@@ -28,9 +28,11 @@
modules_path = os.path.dirname(test_path)
sys.path.insert(0, modules_path)

import sonic_platform.chassis
from sonic_platform.chassis import Chassis
from sonic_platform.device_data import DeviceDataManager

sonic_platform.chassis.extract_RJ45_ports_index = mock.MagicMock(return_value=[])

class TestChassis:
"""Test class to test chassis.py. The test cases covers:
6 changes: 1 addition & 5 deletions platform/mellanox/mlnx-platform-api/tests/test_eeprom.py
Original file line number Diff line number Diff line change
@@ -30,11 +30,11 @@
from sonic_platform.chassis import Chassis
from sonic_platform.eeprom import Eeprom, EepromContentVisitor


class TestEeprom:
@patch('os.path.exists', MagicMock(return_value=True))
@patch('os.path.islink', MagicMock(return_value=True))
@patch('sonic_platform.eeprom.Eeprom.get_system_eeprom_info')
@patch('sonic_platform.chassis.extract_RJ45_ports_index', MagicMock(return_value=[]))
def test_chassis_eeprom(self, mock_eeprom_info):
mock_eeprom_info.return_value = {
hex(Eeprom._TLV_CODE_PRODUCT_NAME): 'MSN3420',
@@ -102,7 +102,3 @@ def test_eeprom_content_visitor(self):
v.visit_tlv('tlv3', Eeprom._TLV_CODE_VENDOR_EXT, 4, 'ext2')
assert content[hex(Eeprom._TLV_CODE_PRODUCT_NAME)] == 'MSN3420'
assert content[hex(Eeprom._TLV_CODE_VENDOR_EXT)] == ['ext1', 'ext2']




1 change: 1 addition & 0 deletions platform/mellanox/mlnx-platform-api/tests/test_led.py
Original file line number Diff line number Diff line change
@@ -35,6 +35,7 @@

class TestLed:
@mock.patch('sonic_platform.led.Led._wait_files_ready', mock.MagicMock(return_value=True))
@mock.patch('sonic_platform.chassis.extract_RJ45_ports_index', mock.MagicMock(return_value=True))
def test_chassis_led(self):
chassis = Chassis()
assert chassis._led is None
2 changes: 2 additions & 0 deletions platform/mellanox/mlnx-platform-api/tests/test_module.py
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@
modules_path = os.path.dirname(test_path)
sys.path.insert(0, modules_path)

import sonic_platform.chassis
from sonic_platform import utils
from sonic_platform.chassis import ModularChassis
from sonic_platform.device_data import DeviceDataManager
@@ -37,6 +38,7 @@ class TestModule:
def setup_class(cls):
DeviceDataManager.get_linecard_sfp_count = mock.MagicMock(return_value=2)
DeviceDataManager.get_linecard_count = mock.MagicMock(return_value=2)
sonic_platform.chassis.extract_RJ45_ports_index = mock.MagicMock(return_value=[])

def test_chassis_get_num_sfp(self):
chassis = ModularChassis()
4 changes: 3 additions & 1 deletion platform/mellanox/mlnx-platform-api/tests/test_sfp.py
Original file line number Diff line number Diff line change
@@ -53,8 +53,10 @@ def test_sfp_index(self, mock_max_port):
assert sfp.index == 5

@mock.patch('sonic_platform.sfp.SFP.read_eeprom', mock.MagicMock(return_value=None))
@mock.patch('sonic_platform.sfp.SFP._get_error_code')
@mock.patch('sonic_platform.sfp.SFP.shared_sdk_handle', mock.MagicMock(return_value=2))
@mock.patch('sonic_platform.sfp.SFP._get_module_info')
@mock.patch('sonic_platform.chassis.Chassis.get_num_sfps', mock.MagicMock(return_value=2))
@mock.patch('sonic_platform.chassis.extract_RJ45_ports_index', mock.MagicMock(return_value=[]))
def test_sfp_get_error_status(self, mock_get_error_code):
chassis = Chassis()

4 changes: 3 additions & 1 deletion platform/mellanox/mlnx-platform-api/tests/test_thermal.py
Original file line number Diff line number Diff line change
@@ -28,9 +28,11 @@
modules_path = os.path.dirname(test_path)
sys.path.insert(0, modules_path)

import sonic_platform.chassis
from sonic_platform.chassis import Chassis
from sonic_platform.device_data import DeviceDataManager

sonic_platform.chassis.extract_RJ45_ports_index = mock.MagicMock(return_value=[])

class TestThermal:
@mock.patch('os.path.exists', mock.MagicMock(return_value=True))
@@ -334,4 +336,4 @@ def test_get_cooling_level(self, mock_read_file):

mock_read_file.side_effect = ValueError('')
with pytest.raises(RuntimeError):
Thermal.get_cooling_level()
Thermal.get_cooling_level()
54 changes: 47 additions & 7 deletions platform/mellanox/mlnx-ssd-fw-update.sh
Original file line number Diff line number Diff line change
@@ -21,9 +21,8 @@
#= Global variable #
#=
#=====
VERSION="1.5"
VERSION="1.6"
#=====
SWITCH_SSD_DEV="/dev/sda"
UTIL_TITLE="This is MLNX SSD firmware update utility to read and write SSD FW. Version ${VERSION}"
DEPENDECIES=("smartctl" "sha256sum" "tar" "/bin/bash" "gpg" "sed" "realpath" "dirname")
TRUE="0"
@@ -37,6 +36,7 @@ DEBUG_MSG="DEBUG" # remove all instance after script is ready.
#=====
PKG_EXTRACTED=$FALSE
LOGGER_UTIL=$FALSE
SSD_DEV_NAME=""
SSD_FW_VER=""
SSD_DEVICE_MODEL=""
SSD_SERIAL=""
@@ -230,7 +230,7 @@ function get_ssd_fw_version() {
[ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; }

local device_fw_version
device_fw_version=$(smartctl -i $SWITCH_SSD_DEV | grep -Po "Firmware Version: +\K[^,]+")
device_fw_version=$(smartctl -i $SSD_DEV_NAME | grep -Po "Firmware Version: +\K[^,]+")
LOG_MSG "device_fw_version: $device_fw_version" ${DEBUG_MSG}
eval $1='$device_fw_version'
}
@@ -242,7 +242,7 @@ function get_ssd_device_model() {
[ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; }

local device_model_name
device_model_name=$(smartctl -i $SWITCH_SSD_DEV | grep -Po "Device Model: +\K[^,]+")
device_model_name=$(smartctl -i $SSD_DEV_NAME | grep -E "Device Model:|Model Number:" | awk '{$1=$2="";print $0}'| sed 's/^ *//g')
LOG_MSG "device_model_name: $device_model_name" ${DEBUG_MSG}
eval $1='$device_model_name'
}
@@ -254,7 +254,7 @@ function get_ssd_size() {
[ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; }

local device_size
device_size=$(smartctl -i $SWITCH_SSD_DEV | grep -Po "User Capacity:.+bytes \[\K[^ ]+")
device_size=$(smartctl -i $SSD_DEV_NAME | grep -E "User Capacity:|Size/Capacity" | awk -F '\[|\]' '{print $2}' | awk '{print $1}')
LOG_MSG "device_size: $device_size" ${DEBUG_MSG}
eval $1='$device_size'
}
@@ -266,16 +266,56 @@ function get_ssd_serial() {
[ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; }

local device_serial
device_serial=$(smartctl -i $SWITCH_SSD_DEV | grep -Po "Serial Number: +\K[^,]+")
device_serial=$(smartctl -i $SSD_DEV_NAME | grep -Po "Serial Number: +\K[^,]+")
LOG_MSG "device_serial: $device_serial" ${DEBUG_MSG}
eval $1='$device_serial'
}

#==============================================================================#
#= This function check if given argument is valid and return boolean result. #
# This function check SSD device name #
#
function get_ssd_device_name() {
[ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; }

non_rem_mount_disks=""
non_rem_mount_disks_count=0
mount_parts=$(cat /proc/partitions | grep -v "^major" | grep -v ram | awk '{{print $4}}')
for blk_dev_name in ${mount_parts}
do
blk_dev_link=$(find /sys/bus /sys/class /sys/block/ -name ${blk_dev_name})
for first_blk_dev_link in ${blk_dev_link}
do
if ls -l ${first_blk_dev_link} | grep -q virtual; then
continue
fi
if [ -e ${first_blk_dev_link}/removable ] ; then
if [ "0" = $(cat ${first_blk_dev_link}/removable) ] ; then
let non_rem_mount_disks_count=${non_rem_mount_disks_count}+1
if [ "1" == "${non_rem_mount_disks_count}" ] ; then
non_rem_mount_disks="${blk_dev_name}"
else
non_rem_mount_disks="${non_rem_mount_disks} ${blk_dev_name}"
fi
fi
fi
break
done
done
if [ "1" == "${non_rem_mount_disks_count}" ] ; then
device_name="/dev/${non_rem_mount_disks}"
else
$1="/dev/sda"
fi
LOG_MSG "device_name: $device_name" ${DEBUG_MSG}
eval $1='$device_name'
}

#==============================================================================#
#= This function check if given argument. #
#=
function get_ssd_info() {
LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG}
get_ssd_device_name SSD_DEV_NAME
get_ssd_fw_version SSD_FW_VER
get_ssd_device_model SSD_DEVICE_MODEL
get_ssd_serial SSD_SERIAL

0 comments on commit 7ac590b

Please sign in to comment.