anatol / smart.go

Pure-Go library to access drive's S.M.A.R.T. information

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

smart raw values support in AtaSmartAttr struct

rare-magma opened this issue · comments

commented

Hi,

Thanks for the great work on this project!

I have a question:
Is it possible to have the raw values available in the AtaSmartAttr struct?
I'm asking because in the case of querying for disk temperatures, the number present in the normalized value needs to be computed in order to reflect the real temperature.

See more details/context about this question here: xxxserxxx/gotop#221 (comment)

I read about the ATA raw values a bit. If it is a widely used feature then it seems like a reasonable idea to support it.

We should follow the same idea as smartmontool does here https://github.com/mirror/smartmontools/blob/b80deea933b2145a407f3b889fe927666d9bf495/atacmds.cpp#L1846

Also, the name "Raw" is a misnomer here, the field is really the opposite of raw, it is a "NormalizedValue".

I just pushed a commit that tries to implement the requested feature. Please check the ataattr branch. Try it and let me know your feedback.

commented

Great! Thanks for dedicating time to this request :)

I tried it but couldn't get it to work as expected, even tho the collected data seems correct.

To test this, I've used gotop, with the patch as described here(xxxserxxx/gotop#221), but pulling from the latest commit of a local version of smart.go's atattr branch.

Here's the relevant section of the code:

for _, disk := range block.Disks {
	dev, err := smart.Open("/dev/" + disk.Name)
	if err != nil {
		continue
	}
	defer dev.Close()

	switch sm := dev.(type) {
	case *smart.SataDevice:
		data, _ := sm.ReadSMARTData()
		for _, attr := range data.Attrs {
			if attr.Id == 194 {
				log.Print(disk.Name)
				log.Print(attr)
				log.Print(attr.ValueRaw)
				log.Print(attr.Current)
				value, _ := attr.ParseAsTemperature()
				log.Print(value)
				temps[disk.Name+"_"+disk.Model] = int(value)
			}
		}
	case *smart.NVMeDevice:
		data, _ := sm.ReadSMART()
		temps[disk.Name+"_"+disk.Model] = int(data.Temperature)
	default:
	}
}

log:

23:49:57 temp_nix.go:54: sda
23:49:57 temp_nix.go:55: {194 34 59 39 [41 0 0 0 61 0]  0 0}
23:49:57 temp_nix.go:56: 0
23:49:57 temp_nix.go:57: 59
23:49:57 temp_nix.go:59: 0

The number 41 in the inner array corresponds to the sda disk temperature reported by smartctl at the time of the execution.
Unfortunately the ValueRaw is reported as 0 as seen in the subsequent message, as well as the result of ParseAsTemperature()

Could you please post output of your disk's SMART data sudo smartctl -a /dev/sda

commented
sudo smartctl -a /dev/sda                                               ✔   silverblue !1 
[sudo] password for user: 
smartctl 7.3 2022-02-28 r5338 [x86_64-linux-5.17.13-300.fc36.x86_64] (local build)
Copyright (C) 2002-22, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Family:     Crucial/Micron Client SSDs
Device Model:     CT250MX500SSD1
Serial Number:    1949E22CD147
LU WWN Device Id: 5 00a075 1e22cd147
Firmware Version: M3CR023
User Capacity:    250,059,350,016 bytes [250 GB]
Sector Size:      512 bytes logical/physical
Rotation Rate:    Solid State Device
Form Factor:      2.5 inches
TRIM Command:     Available
Device is:        In smartctl database 7.3/5319
ATA Version is:   ACS-3 T13/2161-D revision 5
SATA Version is:  SATA 3.3, 6.0 Gb/s (current: 6.0 Gb/s)
Local Time is:    Tue Jun 14 00:22:51 2022 CEST
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:  (0x82)	Offline data collection activity
					was completed without error.
					Auto Offline Data Collection: Enabled.
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: 			(0x7b) SMART execute Offline immediate.
					Auto Offline data collection on/off support.
					Suspend Offline collection upon new
					command.
					Offline surface scan supported.
					Self-test supported.
					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: 	(  30) minutes.
Conveyance self-test routine
recommended polling time: 	(   2) minutes.
SCT capabilities: 	      (0x0031)	SCT Status supported.
					SCT Feature Control supported.
					SCT Data Table supported.

SMART Attributes Data Structure revision number: 16
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x002f   100   100   000    Pre-fail  Always       -       0
  5 Reallocate_NAND_Blk_Cnt 0x0032   100   100   010    Old_age   Always       -       0
  9 Power_On_Hours          0x0032   100   100   000    Old_age   Always       -       9487
 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       1082
171 Program_Fail_Count      0x0032   100   100   000    Old_age   Always       -       0
172 Erase_Fail_Count        0x0032   100   100   000    Old_age   Always       -       0
173 Ave_Block-Erase_Count   0x0032   099   099   000    Old_age   Always       -       29
174 Unexpect_Power_Loss_Ct  0x0032   100   100   000    Old_age   Always       -       22
180 Unused_Reserve_NAND_Blk 0x0033   000   000   000    Pre-fail  Always       -       32
183 SATA_Interfac_Downshift 0x0032   100   100   000    Old_age   Always       -       0
184 Error_Correction_Count  0x0032   100   100   000    Old_age   Always       -       0
187 Reported_Uncorrect      0x0032   100   100   000    Old_age   Always       -       0
194 Temperature_Celsius     0x0022   060   039   000    Old_age   Always       -       40 (Min/Max 0/61)
196 Reallocated_Event_Count 0x0032   100   100   000    Old_age   Always       -       0
197 Current_Pending_ECC_Cnt 0x0032   100   100   000    Old_age   Always       -       0
198 Offline_Uncorrectable   0x0030   100   100   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x0032   100   100   000    Old_age   Always       -       0
202 Percent_Lifetime_Remain 0x0030   099   099   001    Old_age   Offline      -       1
206 Write_Error_Rate        0x000e   100   100   000    Old_age   Always       -       0
210 Success_RAIN_Recov_Cnt  0x0032   100   100   000    Old_age   Always       -       0
246 Total_LBAs_Written      0x0032   100   100   000    Old_age   Always       -       4462901253
247 Host_Program_Page_Count 0x0032   100   100   000    Old_age   Always       -       76055875
248 FTL_Program_Page_Count  0x0032   100   100   000    Old_age   Always       -       60142042

SMART Error Log Version: 1
Invalid Error Log index = 0x0d (T13/1321D rev 1c Section 8.41.6.8.2.2 gives valid range from 1 to 5)

SMART Self-test log structure revision number 1
Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
# 1  Short offline       Completed without error       00%      8587         -
# 2  Short offline       Completed without error       00%      8580         -
# 3  Short offline       Completed without error       00%      8568         -
# 4  Extended offline    Completed without error       00%      8553         -
# 5  Short offline       Completed without error       00%      8538         -
# 6  Short offline       Completed without error       00%      8512         -
# 7  Short offline       Completed without error       00%      8488         -
# 8  Short offline       Completed without error       00%      8473         -
# 9  Short offline       Completed without error       00%      8431         -
#10  Short offline       Completed without error       00%      8418         -
#11  Short offline       Completed without error       00%      8404         -
#12  Short offline       Completed without error       00%      8376         -
#13  Extended offline    Completed without error       00%      8359         -
#14  Short offline       Completed without error       00%      8346         -
#15  Short offline       Completed without error       00%      8334         -
#16  Short offline       Completed without error       00%      8290         -
#17  Short offline       Completed without error       00%      8276         -
#18  Short offline       Completed without error       00%      8256         -
#19  Short offline       Completed without error       00%      8251         -
#20  Short offline       Completed without error       00%      8241         -
#21  Extended offline    Completed without error       00%      8227         -

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.

Working on it.

Most likely value, _ := attr.ParseAsTemperature() returns error here. I suggest you to check all the places where smart returns errors and handle it.

I added a unit test for your configuration and proposed fix for your issue. Please pull the latest changes from ataattr branch and try it again.

@rare-magma had you chance to try the latest changes from ataattr branch?

commented

@anatol thanks for working on the latest changes, I'm testing it as we speak, I'll get back to you soon. The values reported by ParseAsTemperature() match the expected numbers (as reported by smartctl or hddtemp)