Categorygithub.com/anatol/smart.go
modulepackage
0.0.0-20240606135530-b987830bbb40
Repository: https://github.com/anatol/smart.go.git
Documentation: pkg.go.dev

# README

smart.go

Smart.go is a pure Golang library to access disk low-level S.M.A.R.T. information. Smart.go tries to match functionality provided by smartctl but with golang API.

Currently this library support SATA, SCSI and NVMe drives. Different drive types provide different set of monitoring information and API reflects it.

At this point the library works at Linux and partially at MacOSX. We are looking for help with porting it to other platforms.

Example

Here is an example of code that demonstrates the library usage.

// skip the error handling for more compact API example
dev, _ := smart.OpenNVMe("/dev/nvme0n1")
c, nss, _ := dev.Identify()
fmt.Println("Model number: ", c.ModelNumber())
fmt.Println("Serial number: ", c.SerialNumber())
fmt.Println("Size: ", c.Tnvmcap.Val[0])

// namespace #1
ns := nss[0]
fmt.Println("Namespace 1 utilization: ", ns.Nuse*ns.LbaSize())

sm, _ := dev.ReadSMART()
fmt.Println("Temperature: ", sm.Temperature, "K")
// PowerOnHours is reported as 128-bit value and represented by this library as an array of uint64
fmt.Println("Power-on hours: ", sm.PowerOnHours.Val[0])
fmt.Println("Power cycles: ", sm.PowerCycles.Val[0])

The output looks like

Model number:  SAMSUNG MZVLB512HBJQ-000L7
Serial number:  S4ENNF0M741521
Size:  512110190592
Namespace 1 utilization:  387524902912
Temperature:  327 K
Power-on hours:  499
Power cycles:  1433

Here is an example of iterating over system's block devices:

block, err := ghw.Block()
if err != nil {
  panic(err)
}
for _, disk := range block.Disks {
        dev, err := smart.Open("/dev/" + disk.Name)
        if err != nil {
            // some devices (like dmcrypt) do not support SMART interface
            fmt.Println(err)
            continue
        }
        defer dev.Close()

        switch sm := dev.(type) {
        case *smart.SataDevice:
            data, err := sm.ReadSMARTData()
            attr, ok := data.Attrs[194]; ok { // attr.Name == "Temperature_Celsius"
                temp, min, max, overtempCounter, err := attr.ParseAsTemperature()
                // min/max/counter are optional
            }
        case *smart.ScsiDevice:
            _, _ = sm.Capacity()
        case *smart.NVMeDevice:
            _, _ = sm.ReadSMART()
        }
}

Reading generic SMART attributes.

smart.go provides API for easier access to the most commonly used device attributes.

dev, err := smart.Open("/dev/nvme0n1")
require.NoError(t, err)
defer dev.Close()

a, err := dev.ReadGenericAttributes()
require.NoError(t, err)

fmt.Println("The temperature is ", a.Temperature) // in Celsius
fmt.Println("Read block count ", a.Read)
fmt.Println("Written block count ", a.Written)
fmt.Println("Power Cycles count ", a.PowerCycles)
fmt.Println("Power On Hours ", a.PowerOnHours)

Credit

This project is inspired by https://github.com/dswarbrick/smart

# Packages

No description provided by the author
No description provided by the author

# Functions

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Constants

Online bit.
Prefailure bit.
formatting is hours = raw/120; minutes = (raw-120*hours)/2.
formatting is raw[0:48] in hex.
formatting is raw[0:56] in hex.
formatting is raw[0:64] in hex.
formatting is hours = raw[0:32]/60; minutes = raw[0:32]%60; optional raw[32:48] as ???.
formatting is hours = raw[32:64]; milliseconds = raw[0:32].
formatting is raw[32:48], raw[16:32], raw[0:16].
formatting is raw[0:6] and optional raw[16:32] as average.
formatting is raw[0:16] and optional raw[32:48], raw[16:32].
formatting is raw[24:48]/raw[0:24].
formatting is raw[32:56]/raw[0:32].
formatting is raw[0:24] and optional raw[40:48], raw[32:40], raw[24:32].
formatting is raw[0:48].
formatting is raw[0:56].
formatting is raw[0:64].
formatting is raw[40:48], raw[32:40], raw[24:32], raw[16:24], raw[8:16], raw[0:8].
formatting is hours = raw/3600; minutes = (raw-3600*hours)/60; seconds = raw%60.
formatting is temp = raw[0:32]/10 in Celsius.
formatting is too complicated.

# Variables

ErrOSUnsupported is returned on unsupported operating systems.

# Structs

AtaIdentifyDevice ATA IDENTIFY DEVICE struct.
No description provided by the author
AtaSmartAttrRaw individual SMART attribute (12 bytes).
SMART log address 01h.
SMART log address 00h.
No description provided by the author
AtaSmartPageRaw is page of 30 SMART attributes as per ATA spec.
SMART log address 06h.
AtaSmartThresholdEntry individual SMART attribute threshold (12 bytes).
No description provided by the author
AtaSmartThresholdsPageRaw is page of 30 SMART attributes thresholds as per ATA spec.
No description provided by the author
No description provided by the author
Identify Controller Data Structure (CNS 01h) The Identify Controller data structure is returned to the host for the controller processing the command.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
Uint128 is a stopgap until https:// github.com/golang/go/issues/9455 is implemented.

# Interfaces

No description provided by the author