From 67745c80e6feaff3810483c02a75335081f639a2 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Thu, 21 Sep 2023 20:24:42 +0800 Subject: [PATCH] Add new SSD type support (#390) (#396) Description Backport PR #390 to 202305 Add new SSD vendor "Swissbit" support Motivation and Context Add new SSD vendor "Swissbit" support How Has This Been Tested? Unit test Manual test --- sonic_platform_base/sonic_ssd/ssd_generic.py | 24 +++- tests/ssd_generic_test.py | 116 +++++++++++++++++++ 2 files changed, 137 insertions(+), 3 deletions(-) diff --git a/sonic_platform_base/sonic_ssd/ssd_generic.py b/sonic_platform_base/sonic_ssd/ssd_generic.py index 95ed5c332..9671a5189 100644 --- a/sonic_platform_base/sonic_ssd/ssd_generic.py +++ b/sonic_platform_base/sonic_ssd/ssd_generic.py @@ -23,6 +23,8 @@ # Set Vendor Specific IDs INNODISK_HEALTH_ID = 169 INNODISK_TEMPERATURE_ID = 194 +SWISSBIT_HEALTH_ID = 248 +SWISSBIT_TEMPERATURE_ID = 194 class SsdUtil(SsdBase): """ @@ -42,7 +44,8 @@ def __init__(self, diskdev): "InnoDisk" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, "M.2" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, "StorFly" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info }, - "Virtium" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info } + "Virtium" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info }, + "Swissbit" : { "utility" : SMARTCTL, "parser" : self.parse_swissbit_info }, } self.dev = diskdev @@ -78,6 +81,8 @@ def _parse_vendor(self): return model_short elif self.model.startswith('VSF'): return 'Virtium' + elif self.model.startswith('SFS'): + return 'Swissbit' else: return None @@ -124,7 +129,7 @@ def parse_innodisk_info(self): if self.vendor_ssd_info: self.health = self._parse_re('Health:\s*(.+?)%', self.vendor_ssd_info) self.temperature = self._parse_re('Temperature\s*\[\s*(.+?)\]', self.vendor_ssd_info) - + if self.health == NOT_AVAILABLE: health_raw = self.parse_id_number(INNODISK_HEALTH_ID) if health_raw == NOT_AVAILABLE: @@ -153,7 +158,20 @@ def parse_virtium_info(self): self.health = float(self._parse_re('Remaining_Life_Left\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info)) except ValueError: pass - + + def parse_swissbit_info(self): + if self.ssd_info: + health_raw = self.parse_id_number(SWISSBIT_HEALTH_ID) + if health_raw == NOT_AVAILABLE: + self.health = NOT_AVAILABLE + else: + self.health = health_raw.split()[-1] + temp_raw = self.parse_id_number(SWISSBIT_TEMPERATURE_ID) + if temp_raw == NOT_AVAILABLE: + self.temperature = NOT_AVAILABLE + else: + self.temperature = temp_raw.split()[-3] + def fetch_vendor_ssd_info(self, diskdev, model): self.vendor_ssd_info = self._execute_shell(self.vendor_ssd_utility[model]["utility"].format(diskdev)) diff --git a/tests/ssd_generic_test.py b/tests/ssd_generic_test.py index 630d59c6f..fbeb16fa0 100644 --- a/tests/ssd_generic_test.py +++ b/tests/ssd_generic_test.py @@ -532,6 +532,112 @@ ID Attribute High Raw Low Raw Value Worst Threshold """ +output_swissbit_vendor = """ +smartctl 7.2 2020-12-30 r5155 [x86_64-linux-5.10.0-23-2-amd64] (local build) +Copyright (C) 2002-20, Bruce Allen, Christian Franke, www.smartmontools.org + +=== START OF INFORMATION SECTION === +Device Model: SFSA160GM2AK2TO-I-8C-22K-STD +Serial Number: 00006022750795000010 +Firmware Version: SBR15004 +User Capacity: 160,041,885,696 bytes [160 GB] +Sector Size: 512 bytes logical/physical +Rotation Rate: Solid State Device +Form Factor: 2.5 inches +TRIM Command: Available, deterministic, zeroed +Device is: Not in smartctl database [for details use: -P showall] +ATA Version is: ACS-3 (minor revision not indicated) +SATA Version is: SATA 3.2, 6.0 Gb/s (current: 6.0 Gb/s) +Local Time is: Wed Aug 2 08:24:31 2023 UTC +SMART support is: Available - device has SMART capability. +SMART support is: Enabled + +=== START OF READ SMART DATA SECTION === +SMART overall-health self-assessment test result: PASSED + +General SMART Values: +Offline data collection status: (0x00) Offline data collection activity + was never started. + Auto Offline Data Collection: Disabled. +Self-test execution status: ( 0) The previous self-test routine completed + without error or no self-test has ever + been run. +Total time to complete Offline +data collection: ( 0) seconds. +Offline data collection +capabilities: (0x53) SMART execute Offline immediate. + Auto Offline data collection on/off support. + Suspend Offline collection upon new + command. + No Offline surface scan supported. + Self-test supported. + No Conveyance Self-test supported. + Selective Self-test supported. +SMART capabilities: (0x0003) Saves SMART data before entering + power-saving mode. + Supports SMART auto save timer. +Error logging capability: (0x01) Error logging supported. + General Purpose Logging supported. +Short self-test routine +recommended polling time: ( 2) minutes. +Extended self-test routine +recommended polling time: ( 15) minutes. +SCT capabilities: (0x0031) SCT Status supported. + SCT Feature Control supported. + SCT Data Table supported. + +SMART Attributes Data Structure revision number: 1 +Vendor Specific SMART Attributes with Thresholds: +ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE + 1 Raw_Read_Error_Rate 0x000b 100 100 000 Pre-fail Always - 0 + 5 Reallocated_Sector_Ct 0x0013 100 100 000 Pre-fail Always - 0 + 9 Power_On_Hours 0x0012 100 100 000 Old_age Always - 825 + 12 Power_Cycle_Count 0x0012 100 100 000 Old_age Always - 447 + 16 Unknown_Attribute 0x0112 100 100 001 Old_age Always - 4 + 17 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 30000 +160 Unknown_Attribute 0x0002 100 100 000 Old_age Always - 0 +161 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 15401195 +163 Unknown_Attribute 0x0003 100 100 000 Pre-fail Always - 33 +164 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 6506 +165 Unknown_Attribute 0x0002 100 100 000 Old_age Always - 38 +166 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 1 +167 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 4 +168 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 30000 +169 Unknown_Attribute 0x0003 100 100 000 Pre-fail Always - 421 +193 Unknown_SSD_Attribute 0x0012 100 100 000 Old_age Always - 0 +194 Temperature_Celsius 0x0023 100 100 000 Pre-fail Always - 25 (Min/Max 22/45) +195 Hardware_ECC_Recovered 0x0012 100 100 000 Old_age Always - 0 +196 Reallocated_Event_Count 0x0012 000 000 000 Old_age Always - 0 +198 Offline_Uncorrectable 0x0012 100 100 000 Old_age Always - 0 +199 UDMA_CRC_Error_Count 0x000b 100 100 000 Pre-fail Always - 0 +215 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 4275 +231 Unknown_SSD_Attribute 0x1913 100 100 025 Pre-fail Always - 100 +235 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 1302467136 +237 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 0 +241 Total_LBAs_Written 0x0012 100 100 000 Old_age Always - 1186450104 +242 Total_LBAs_Read 0x0012 100 100 000 Old_age Always - 2257141451 +243 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 0 +244 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 0 +248 Unknown_Attribute 0x0112 100 100 001 Old_age Always - 100 + +SMART Error Log Version: 1 +No Errors Logged + +SMART Self-test log structure revision number 1 +No self-tests have been logged. [To run self-tests, use: smartctl -t] + +SMART Selective self-test log data structure revision number 1 + SPAN MIN_LBA MAX_LBA CURRENT_TEST_STATUS + 1 0 0 Not_testing + 2 0 0 Not_testing + 3 0 0 Not_testing + 4 0 0 Not_testing + 5 0 0 Not_testing +Selective self-test flags (0x0): + After scanning selected spans, do NOT read-scan remainder of disk. +If Selective self-test is pending on power-up, resume after 0 minute delay. +""" + class TestSsdGeneric: @mock.patch('sonic_platform_base.sonic_ssd.ssd_generic.SsdUtil._execute_shell', mock.MagicMock(return_value=output_nvme_ssd)) def test_nvme_ssd(self): @@ -631,3 +737,13 @@ def test_virtium_ssd(self, mock_exec): mock_exec.side_effect = [output_virtium_generic, output_virtium_invalid_remain_life] virtium_ssd = SsdUtil('/dev/sda') assert virtium_ssd.get_health() == "N/A" + + @mock.patch('sonic_platform_base.sonic_ssd.ssd_generic.SsdUtil._execute_shell') + def test_swissbit_ssd(self, mock_exec): + mock_exec.return_value = output_swissbit_vendor + swissbit_ssd = SsdUtil('/dev/sda') + assert swissbit_ssd.get_health() == '100' + assert swissbit_ssd.get_model() == 'SFSA160GM2AK2TO-I-8C-22K-STD' + assert swissbit_ssd.get_firmware() == "SBR15004" + assert swissbit_ssd.get_temperature() == '25' + assert swissbit_ssd.get_serial() == "00006022750795000010"