Skip to content

Commit 3d57e0e

Browse files
[ssd_generic] Get health status from Remaining_Life_Left field for virtium SSD (sonic-net#344)
* [ssd_generic] Get health status from Remaining_Life_Left field for virtium SSD * Improve UT cover * Fix UT failure
1 parent 85c20cd commit 3d57e0e

File tree

2 files changed

+220
-5
lines changed

2 files changed

+220
-5
lines changed

sonic_platform_base/sonic_ssd/ssd_generic.py

+11-5
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,17 @@ def parse_virtium_info(self):
137137
self.temperature = self._parse_re('Temperature_Celsius\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info)
138138
nand_endurance = self._parse_re('NAND_Endurance\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info)
139139
avg_erase_count = self._parse_re('Average_Erase_Count\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info)
140-
try:
141-
self.health = 100 - (float(avg_erase_count) * 100 / float(nand_endurance))
142-
except (ValueError, ZeroDivisionError):
143-
pass
144-
140+
if nand_endurance != NOT_AVAILABLE and avg_erase_count != NOT_AVAILABLE:
141+
try:
142+
self.health = 100 - (float(avg_erase_count) * 100 / float(nand_endurance))
143+
except (ValueError, ZeroDivisionError):
144+
pass
145+
else:
146+
try:
147+
self.health = float(self._parse_re('Remaining_Life_Left\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info))
148+
except ValueError:
149+
pass
150+
145151
def fetch_vendor_ssd_info(self, diskdev, model):
146152
self.vendor_ssd_info = self._execute_shell(self.vendor_ssd_utility[model]["utility"].format(diskdev))
147153

tests/ssd_generic_test.py

+209
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,194 @@
344344
345345
"""
346346

347+
output_virtium_generic = """
348+
smartctl 7.2 2020-12-30 r5155 [x86_64-linux-5.10.0-12-2-amd64] (local build)
349+
Copyright (C) 2002-20, Bruce Allen, Christian Franke, www.smartmontools.org
350+
351+
=== START OF INFORMATION SECTION ===
352+
Device Model: VSFDM8XC240G-V11-T
353+
Serial Number: 60237-0037
354+
Firmware Version: 0913-000
355+
User Capacity: 240,057,409,536 bytes [240 GB]
356+
Sector Size: 512 bytes logical/physical
357+
Rotation Rate: Solid State Device
358+
Form Factor: 2.5 inches
359+
TRIM Command: Available, deterministic, zeroed
360+
Device is: Not in smartctl database [for details use: -P showall]
361+
ATA Version is: ACS-3 (minor revision not indicated)
362+
SATA Version is: SATA 3.2, 6.0 Gb/s (current: 6.0 Gb/s)
363+
Local Time is: Wed Feb 8 02:11:48 2023 UTC
364+
SMART support is: Available - device has SMART capability.
365+
SMART support is: Enabled
366+
367+
=== START OF READ SMART DATA SECTION ===
368+
SMART overall-health self-assessment test result: PASSED
369+
370+
General SMART Values:
371+
Offline data collection status: (0x00) Offline data collection activity
372+
was never started.
373+
Auto Offline Data Collection: Disabled.
374+
Self-test execution status: ( 0) The previous self-test routine completed
375+
without error or no self-test has ever
376+
been run.
377+
Total time to complete Offline
378+
data collection: ( 0) seconds.
379+
Offline data collection
380+
capabilities: (0x73) SMART execute Offline immediate.
381+
Auto Offline data collection on/off support.
382+
Suspend Offline collection upon new
383+
command.
384+
No Offline surface scan supported.
385+
Self-test supported.
386+
Conveyance Self-test supported.
387+
Selective Self-test supported.
388+
SMART capabilities: (0x0003) Saves SMART data before entering
389+
power-saving mode.
390+
Supports SMART auto save timer.
391+
Error logging capability: (0x01) Error logging supported.
392+
General Purpose Logging supported.
393+
Short self-test routine
394+
recommended polling time: ( 2) minutes.
395+
Extended self-test routine
396+
recommended polling time: ( 15) minutes.
397+
Conveyance self-test routine
398+
recommended polling time: ( 0) minutes.
399+
SCT capabilities: (0x0031) SCT Status supported.
400+
SCT Feature Control supported.
401+
SCT Data Table supported.
402+
403+
SMART Attributes Data Structure revision number: 1
404+
Vendor Specific SMART Attributes with Thresholds:
405+
ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE
406+
1 Raw_Read_Error_Rate 0x000b 100 100 000 Pre-fail Always - 0
407+
5 Reallocated_Sector_Ct 0x0013 100 100 000 Pre-fail Always - 0
408+
9 Power_On_Hours 0x0012 100 100 000 Old_age Always - 221
409+
12 Power_Cycle_Count 0x0012 100 100 000 Old_age Always - 156
410+
14 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 469427376
411+
15 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 468862128
412+
16 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 1436
413+
17 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 1436
414+
100 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 6823
415+
168 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 0
416+
170 Unknown_Attribute 0x0003 100 100 000 Pre-fail Always - 0
417+
172 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 0
418+
173 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 12
419+
174 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 155
420+
175 Program_Fail_Count_Chip 0x0012 100 100 000 Old_age Always - 1
421+
181 Program_Fail_Cnt_Total 0x0012 100 100 000 Old_age Always - 0
422+
187 Reported_Uncorrect 0x0012 100 100 000 Old_age Always - 0
423+
194 Temperature_Celsius 0x0023 066 048 000 Pre-fail Always - 34 (Min/Max 27/52)
424+
197 Current_Pending_Sector 0x0032 100 100 000 Old_age Always - 0
425+
198 Offline_Uncorrectable 0x0012 100 100 000 Old_age Always - 0
426+
199 UDMA_CRC_Error_Count 0x000b 100 100 000 Pre-fail Always - 0
427+
202 Unknown_SSD_Attribute 0x0012 000 000 000 Old_age Always - 0
428+
231 Unknown_SSD_Attribute 0x0013 100 100 000 Pre-fail Always - 100
429+
232 Available_Reservd_Space 0x0013 100 100 000 Pre-fail Always - 0
430+
234 Unknown_Attribute 0x000b 100 100 000 Pre-fail Always - 131292480
431+
235 Unknown_Attribute 0x000b 100 100 000 Pre-fail Always - 347463360
432+
241 Total_LBAs_Written 0x0012 100 100 000 Old_age Always - 302116658
433+
242 Total_LBAs_Read 0x0012 100 100 000 Old_age Always - 45606297
434+
247 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 347463360
435+
248 Unknown_Attribute 0x0012 100 100 000 Old_age Always - 1
436+
437+
SMART Error Log Version: 1
438+
No Errors Logged
439+
440+
SMART Self-test log structure revision number 1
441+
No self-tests have been logged. [To run self-tests, use: smartctl -t]
442+
443+
SMART Selective self-test log data structure revision number 1
444+
SPAN MIN_LBA MAX_LBA CURRENT_TEST_STATUS
445+
1 0 0 Not_testing
446+
2 0 0 Not_testing
447+
3 0 0 Not_testing
448+
4 0 0 Not_testing
449+
5 0 0 Not_testing
450+
Selective self-test flags (0x0):
451+
After scanning selected spans, do NOT read-scan remainder of disk.
452+
If Selective self-test is pending on power-up, resume after 0 minute delay.
453+
"""
454+
455+
output_virtium_vendor = """
456+
SMART attributes
457+
ID Attribute High Raw Low Raw Value Worst Threshold
458+
1 Raw_Read_Error_Rate 0 0 100 100 0
459+
5 Reserved_Attribute 0 0 100 100 0
460+
9 Power_On_Hours 0 221 100 100 0
461+
12 Power_Cycle_Count 0 156 100 100 0
462+
14 Reserved_Attribute 0 469427376 100 100 0
463+
15 Reserved_Attribute 0 468862128 100 100 0
464+
16 Reserved_Attribute 0 1436 100 100 0
465+
17 Reserved_Attribute 0 1436 100 100 0
466+
100 Reserved_Attribute 0 6823 100 100 0
467+
168 NAND_Endurance 0 0 100 100 0
468+
170 Reserved_Attribute 0 0 100 100 0
469+
172 Reserved_Attribute 0 0 100 100 0
470+
173 Reserved_Attribute 0 12 100 100 0
471+
174 Reserved_Attribute 0 155 100 100 0
472+
175 Reserved_Attribute 0 1 100 100 0
473+
181 Total_Program_Fail 0 0 100 100 0
474+
187 Uncorrectable_Error_Count 0 0 100 100 0
475+
194 Temperature_Celsius 52 34 66 48 0
476+
197 Current_Pending_Sector_Count 0 0 100 100 0
477+
198 Reserved_Attribute 0 0 100 100 0
478+
199 UDMA_CRC_Error_Count 0 0 100 100 0
479+
202 TRIM_Count 0 0 0 0 0
480+
231 Reserved_Attribute 0 100 100 100 0
481+
232 Reserved_Attribute 0 0 100 100 0
482+
234 Reserved_Attribute 0 131296768 100 100 0
483+
235 Reserved_Attribute 0 347463680 100 100 0
484+
241 Total_LBAs_Written 0 302116658 100 100 0
485+
242 Total_LBAs_Read 0 45608497 100 100 0
486+
247 Reserved_Attribute 0 347463680 100 100 0
487+
248 Remaining_Life_Left 0 1 100 100 0
488+
"""
489+
490+
output_virtium_no_remain_life = """
491+
SMART attributes
492+
ID Attribute High Raw Low Raw Value Worst Threshold
493+
1 Raw_Read_Error_Rate 0 0 100 100 70
494+
5 Reserved_Attribute 0 0 100 100 0
495+
9 Power_On_Hours 0 1288 100 100 0
496+
12 Power_Cycle_Count 0 106 100 100 0
497+
160 Uncorrectable_Sector_Count 0 0 100 100 0
498+
161 Valid_Spare_Block 0 267 100 100 0
499+
163 Reserved_Attribute 0 16 100 100 0
500+
164 Reserved_Attribute 0 243145 100 100 0
501+
165 Maximum_Erase_Count 0 194 100 100 0
502+
166 Reserved_Attribute 0 89 100 100 0
503+
167 Average_Erase_Count 0 116 100 100 0
504+
168 NAND_Endurance 0 20000 100 100 0
505+
177 Reserved_Attribute 0 775 100 100 50
506+
178 Reserved_Attribute 0 0 100 100 0
507+
181 Total_Program_Fail 0 0 100 100 0
508+
182 Total_Erase_Fail 0 0 100 100 0
509+
187 Uncorrectable_Error_Count 0 0 100 100 0
510+
192 Sudden_Power_Lost_Count 0 44 100 100 0
511+
194 Temperature_Celsius 0 35 100 100 0
512+
195 Hardware_ECC_Recovered 0 0 100 100 0
513+
196 Reallocated_Event_Count 0 0 100 100 16
514+
198 Reserved_Attribute 0 0 100 100 0
515+
199 UDMA_CRC_Error_Count 0 1 100 100 50
516+
232 Reserved_Attribute 0 100 100 100 0
517+
241 Total_LBAs_Written 0 63134 100 100 0
518+
242 Total_LBAs_Read 0 8235204 100 100 0
519+
248 Remaining_Life_Left 0 100 100 100 0
520+
249 Remaining_Spare_Block_Count 0 100 100 100 0
521+
"""
522+
523+
output_virtium_invalid_nand_endurance = """
524+
SMART attributes
525+
ID Attribute High Raw Low Raw Value Worst Threshold
526+
167 Average_Erase_Count 0 116 100 100 0
527+
168 NAND_Endurance 0 0 100 100 0
528+
"""
529+
530+
output_virtium_invalid_remain_life = """
531+
SMART attributes
532+
ID Attribute High Raw Low Raw Value Worst Threshold
533+
"""
534+
347535
class TestSsdGeneric:
348536
@mock.patch('sonic_platform_base.sonic_ssd.ssd_generic.SsdUtil._execute_shell', mock.MagicMock(return_value=output_nvme_ssd))
349537
def test_nvme_ssd(self):
@@ -412,3 +600,24 @@ def test_Innodisk_missing_names_ssd(self):
412600
assert(Innodisk_ssd.get_health() == '94')
413601
assert(Innodisk_ssd.get_temperature() == '39')
414602

603+
@mock.patch('sonic_platform_base.sonic_ssd.ssd_generic.SsdUtil._execute_shell')
604+
def test_virtium_ssd(self, mock_exec):
605+
mock_exec.side_effect = [output_virtium_generic, output_virtium_vendor]
606+
virtium_ssd = SsdUtil('/dev/sda')
607+
assert virtium_ssd.get_health() == 1
608+
assert virtium_ssd.get_model() == 'VSFDM8XC240G-V11-T'
609+
assert virtium_ssd.get_firmware() == "0913-000"
610+
assert virtium_ssd.get_temperature() == '34'
611+
assert virtium_ssd.get_serial() == "60237-0037"
612+
613+
mock_exec.side_effect = [output_virtium_generic, output_virtium_no_remain_life]
614+
virtium_ssd = SsdUtil('/dev/sda')
615+
assert virtium_ssd.get_health() == 99.42
616+
617+
mock_exec.side_effect = [output_virtium_generic, output_virtium_invalid_nand_endurance]
618+
virtium_ssd = SsdUtil('/dev/sda')
619+
assert virtium_ssd.get_health() == "N/A"
620+
621+
mock_exec.side_effect = [output_virtium_generic, output_virtium_invalid_remain_life]
622+
virtium_ssd = SsdUtil('/dev/sda')
623+
assert virtium_ssd.get_health() == "N/A"

0 commit comments

Comments
 (0)