Documentation
¶
Overview ¶
Package smartmontools provides Go bindings for interacting with smartmontools and collecting S.M.A.R.T. data from storage devices.
The root package is a thin facade over the shared domain model in the types sub-package and the default exec backend in backends/exec. NewClient creates a Client that delegates SMART operations to a pluggable Backend implementation. By default it uses ExecBackend, which shells out to the smartctl binary. Alternative backends can be supplied with WithBackend.
Features ¶
- Device scanning and discovery
- SMART health status checking
- Detailed SMART attribute reading
- Disk type detection (SSD, HDD, NVMe, Unknown)
- Rotation rate (RPM) information for HDDs
- Temperature monitoring
- Power-on time tracking
- Self-test execution and progress monitoring
- Device information retrieval
- SMART support detection and management
- Self-test availability checking
- Standby mode detection for ATA-family devices
- Efficient SMART monitoring with minimal disk I/O
Backend Layout ¶
The default smartctl-backed implementation lives in github.com/dianlight/smartmontools-go/backends/exec. Shared types and interfaces live in github.com/dianlight/smartmontools-go/types; the root package re-exports them as type aliases for a flat, ergonomic API surface.
An alternative purego FFI backend lives in github.com/dianlight/smartmontools-go/backends/lib (LibBackend). It loads a pre-built smartmon wrapper shared library at runtime using ebitengine/purego, avoiding process-spawn overhead and the smartctl binary dependency.
LibBackend (D1 — SDK wrapper via purego) ¶
LibBackend loads libsmartmon_go.so (Linux) or libsmartmon_go.dylib (macOS) at runtime. The shared library is a thin C++ wrapper that links against the pre-built libsmartmon.a static library published in github.com/dianlight/smartmontools-sdk releases.
Build the wrapper library once with the provided setup script:
scripts/setup-lib-backend.sh
The script downloads the correct SDK archive for the current platform, installs the missing smartmon_config.h, and compiles the wrapper into backends/lib/sdk/libsmartmon_go.{so,dylib}.
Library Resolution Order ¶
New() resolves the library path in the following order:
- The path provided by [libbackend.WithLibraryPath].
- SMARTMON_LIB_PATH environment variable — if the file exists at that path it is used directly. If SMARTMON_LIB_PATH is set but the file is absent a warning is logged and the search continues to step 3. If the file exists but a library is also found in a different standard system directory a warning is logged (the configured path is still used).
- Standard system library paths: dynamic-linker names first (respects LD_LIBRARY_PATH / DYLD_LIBRARY_PATH / rpath), then a list of well-known absolute paths such as /usr/local/lib and /opt/homebrew/lib.
Use the LibBackend with WithBackend:
lib, err := libbackend.New(
libbackend.WithLibraryPath("/usr/local/lib/libsmartmon_go.so"),
)
if err != nil {
log.Fatal(err)
}
defer lib.Close()
client, err := smartmontools.NewClient(smartmontools.WithBackend(lib))
Or rely on automatic resolution via the environment variable:
// export SMARTMON_LIB_PATH=/path/to/libsmartmon_go.dylib lib, err := libbackend.New()
Package smartmontools provides Go bindings for interfacing with smartmontools to monitor and manage storage device health using S.M.A.R.T. data.
The library wraps the smartctl command-line utility and provides a clean, idiomatic Go API for accessing SMART information from storage devices.
Index ¶
- Constants
- type AtaSmartData
- type Backend
- type Capabilities
- type CapabilitiesOutput
- type Client
- func (c *Client) AbortSelfTest(ctx context.Context, devicePath string) error
- func (c *Client) CheckHealth(ctx context.Context, devicePath string) (bool, error)
- func (c *Client) Close() error
- func (c *Client) DisableSMART(ctx context.Context, devicePath string) error
- func (c *Client) DiscoverDevices(ctx context.Context) ([]DiscoveryResult, error)
- func (c *Client) EnableSMART(ctx context.Context, devicePath string) error
- func (c *Client) GetAvailableSelfTests(ctx context.Context, devicePath string) (*SelfTestInfo, error)
- func (c *Client) GetAvailableSelfTestsFromInfo(smartInfo *SMARTInfo) *SelfTestInfo
- func (c *Client) GetDeviceInfo(ctx context.Context, devicePath string) (map[string]interface{}, error)
- func (c *Client) GetSMARTInfo(ctx context.Context, devicePath string) (*SMARTInfo, error)
- func (c *Client) GetSMARTSupportFromInfo(smartInfo *SMARTInfo) *SmartSupport
- func (c *Client) IsSMARTSupported(ctx context.Context, devicePath string) (*SmartSupport, error)
- func (c *Client) RunSelfTest(ctx context.Context, devicePath string, testType string) error
- func (c *Client) RunSelfTestWithProgress(ctx context.Context, devicePath string, testType string, ...) error
- func (c *Client) ScanDevices(ctx context.Context) ([]Device, error)
- type ClientOption
- func WithBackend(backend Backend) ClientOption
- func WithCommander(commander Commander) ClientOption
- func WithContext(ctx context.Context) ClientOption
- func WithLogHandler(logger *slog.Logger) ClientOption
- func WithSmartctlPath(path string) ClientOption
- func WithTLogHandler(logger *tlog.Logger) ClientOption
- type Cmd
- type Commander
- type CompareBackend
- type CompareBackendOption
- type Device
- type DiscoveryBackend
- type DiscoveryResult
- type ExecBackend
- type ExecBackendOption
- func WithExecCommander(commander Commander) ExecBackendOption
- func WithExecLogHandler(logger LogAdapter) ExecBackendOption
- func WithExecSlogHandler(logger *slog.Logger) ExecBackendOption
- func WithExecSmartctlPath(path string) ExecBackendOption
- func WithExecTLogHandler(logger *tlog.Logger) ExecBackendOption
- type ExitCodeInfo
- type Flags
- type LogAdapter
- type Message
- type NvmeControllerCapabilities
- type NvmeOptionalAdminCommands
- type NvmeSmartHealth
- type NvmeSmartTestLog
- type OfflineDataCollection
- type PollingMinutes
- type PowerOnTime
- type ProgressCallback
- type Raw
- type SMARTInfo
- type SelfTest
- type SelfTestInfo
- type SmartAttribute
- type SmartClient
- type SmartStatus
- type SmartSupport
- type SmartctlInfo
- type StatusField
- type Temperature
- type UserCapacity
Constants ¶
const ( SmartAttrSSDLifeUsed = smtypes.SmartAttrSSDLifeUsed SmartAttrWearLevelingCount = smtypes.SmartAttrWearLevelingCount SmartAttrSSDLifeLeft = smtypes.SmartAttrSSDLifeLeft SmartAttrSandForceInternal = smtypes.SmartAttrSandForceInternal SmartAttrTotalLBAsWritten = smtypes.SmartAttrTotalLBAsWritten )
SMART attribute IDs for SSD detection and wear-level computation.
const DrivedbUpstreamCommit = smexec.DrivedbUpstreamCommit
DrivedbUpstreamCommit is the upstream smartmontools commit SHA from which the embedded drivedb.h was taken. It is re-exported from the exec backend.
const DrivedbUpstreamDate = smexec.DrivedbUpstreamDate
DrivedbUpstreamDate is the commit date of DrivedbUpstreamCommit in RFC 3339 format. It is re-exported from the exec backend.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AtaSmartData ¶
type AtaSmartData = smtypes.AtaSmartData
AtaSmartData represents ATA SMART attributes.
type Capabilities ¶
type Capabilities = smtypes.Capabilities
Capabilities represents SMART capabilities.
type CapabilitiesOutput ¶
type CapabilitiesOutput = smtypes.CapabilitiesOutput
CapabilitiesOutput represents the output of smartctl -c -j.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client represents a smartmontools client that delegates SMART operations to a pluggable Backend. The default backend is ExecBackend.
func (*Client) AbortSelfTest ¶
AbortSelfTest aborts a running self-test on a device.
func (*Client) CheckHealth ¶
CheckHealth checks if a device is healthy according to SMART.
func (*Client) DisableSMART ¶
DisableSMART disables SMART monitoring on a device.
func (*Client) DiscoverDevices ¶ added in v0.3.1
func (c *Client) DiscoverDevices(ctx context.Context) ([]DiscoveryResult, error)
DiscoverDevices scans all available storage devices and probes each one to determine SMART readability and protocol compatibility.
func (*Client) EnableSMART ¶
EnableSMART enables SMART monitoring on a device.
func (*Client) GetAvailableSelfTests ¶
func (c *Client) GetAvailableSelfTests(ctx context.Context, devicePath string) (*SelfTestInfo, error)
GetAvailableSelfTests returns the list of available self-test types and their durations for a device.
func (*Client) GetAvailableSelfTestsFromInfo ¶ added in v0.2.7
func (c *Client) GetAvailableSelfTestsFromInfo(smartInfo *SMARTInfo) *SelfTestInfo
GetAvailableSelfTestsFromInfo extracts available self-test types and their durations from a SMARTInfo struct without performing additional disk I/O. Applications that already hold a cached SMARTInfo (from GetSMARTInfo) should use this method instead of GetAvailableSelfTests to avoid an extra smartctl -c disk query.
Note: NVMe detection uses NvmeControllerCapabilities, which is present in -a output. The NvmeOptionalAdminCommands field (available only via -c) is not stored in SMARTInfo, so NVMe self-test capability detection may be incomplete for some controllers.
Example usage:
// Get and cache SMART info once info, err := client.GetSMARTInfo(ctx, devicePath)
if err != nil {
return err
}
// Extract self-test types without another disk query selfTests := client.GetAvailableSelfTestsFromInfo(info)
for _, testType := range selfTests.Available {
fmt.Printf("Test: %s (%d min)\n", testType, selfTests.Durations[testType])
}
func (*Client) GetDeviceInfo ¶
func (c *Client) GetDeviceInfo(ctx context.Context, devicePath string) (map[string]interface{}, error)
GetDeviceInfo retrieves basic device information.
func (*Client) GetSMARTInfo ¶
GetSMARTInfo retrieves SMART information for a device.
func (*Client) GetSMARTSupportFromInfo ¶ added in v0.2.5
func (c *Client) GetSMARTSupportFromInfo(smartInfo *SMARTInfo) *SmartSupport
GetSMARTSupportFromInfo extracts SMART support status from a SMARTInfo struct. This is a helper method that allows checking SMART availability and enablement status without performing additional disk I/O. Applications should call GetSMARTInfo once, cache the result, and use this method to check the SMART status from the cache.
This pattern avoids periodic disk access and prevents waking disks from standby mode.
Example usage:
// Get and cache SMART info once info, err := client.GetSMARTInfo(ctx, devicePath)
if err != nil {
return err
}
// Check SMART status from cached info (no disk access) support := client.GetSMARTSupportFromInfo(info)
if support.Available && support.Enabled {
// SMART is available and enabled
}
// After EnableSMART/DisableSMART, refresh the cache:
if err := client.EnableSMART(ctx, devicePath); err != nil {
return err
}
// Refresh cache after state change info, err = client.GetSMARTInfo(ctx, devicePath)
if err != nil {
return err
}
func (*Client) IsSMARTSupported ¶
IsSMARTSupported checks if SMART is supported on a device and if it's enabled.
WARNING: This method performs disk I/O by calling GetSMARTInfo internally. For applications that need to check SMART status frequently (e.g., monitoring daemons), it's recommended to call GetSMARTInfo once, cache the result, and use GetSMARTSupportFromInfo to extract SMART support status from the cached data. This avoids periodic disk access and prevents waking disks from standby mode.
Preferred usage pattern for periodic monitoring:
// Initial query (performed once or when SMART status changes) info, err := client.GetSMARTInfo(ctx, devicePath)
if err != nil {
return err
}
// Cache the info and check SMART status without disk I/O support := client.GetSMARTSupportFromInfo(info)
if !support.Enabled {
// Skip SMART monitoring when disabled
return
}
Only use IsSMARTSupported for one-off checks where disk access is acceptable.
func (*Client) RunSelfTest ¶
RunSelfTest initiates a SMART self-test.
func (*Client) RunSelfTestWithProgress ¶
func (c *Client) RunSelfTestWithProgress(ctx context.Context, devicePath string, testType string, callback ProgressCallback) error
RunSelfTestWithProgress starts a SMART self-test and reports progress.
type ClientOption ¶ added in v0.1.1
type ClientOption func(*Client)
ClientOption is a function that configures a Client.
func WithBackend ¶ added in v0.4.0
func WithBackend(backend Backend) ClientOption
WithBackend sets an explicit Backend implementation, bypassing the default ExecBackend. When WithBackend is provided, options such as WithSmartctlPath and WithCommander have no effect.
func WithCommander ¶ added in v0.1.1
func WithCommander(commander Commander) ClientOption
WithCommander sets a custom commander for testing purposes. This option is only effective when using the default ExecBackend. It is silently ignored when WithBackend is also provided.
func WithContext ¶ added in v0.1.1
func WithContext(ctx context.Context) ClientOption
WithContext sets a default context to use when methods are called with nil context.
func WithLogHandler ¶ added in v0.1.1
func WithLogHandler(logger *slog.Logger) ClientOption
WithLogHandler sets a custom slog.Logger for the client.
func WithSmartctlPath ¶ added in v0.1.1
func WithSmartctlPath(path string) ClientOption
WithSmartctlPath sets a custom path to the smartctl binary. This option is only effective when using the default ExecBackend. It is silently ignored when WithBackend is also provided.
func WithTLogHandler ¶ added in v0.1.4
func WithTLogHandler(logger *tlog.Logger) ClientOption
WithTLogHandler sets a custom tlog.Logger for the client.
type CompareBackend ¶ added in v0.4.0
type CompareBackend = smcompare.CompareBackend
CompareBackend is a virtual Backend that runs multiple backends in parallel, returns the first (master) backend's results, and logs discrepancies.
func NewCompareBackend ¶ added in v0.4.0
func NewCompareBackend(backends []Backend, opts ...CompareBackendOption) (*CompareBackend, error)
NewCompareBackend creates a CompareBackend with at least two backends. The first backend is the master; its results are always returned to the caller. Secondary backends run in parallel; result mismatches are logged as warnings and secondary errors are logged as errors.
type CompareBackendOption ¶ added in v0.4.0
CompareBackendOption configures a CompareBackend.
func WithCompareLogHandler ¶ added in v0.4.0
func WithCompareLogHandler(logger LogAdapter) CompareBackendOption
WithCompareLogHandler sets a custom LogAdapter for a CompareBackend.
func WithCompareSlogHandler ¶ added in v0.4.0
func WithCompareSlogHandler(logger *slog.Logger) CompareBackendOption
WithCompareSlogHandler sets a custom slog.Logger for a CompareBackend.
func WithCompareTLogHandler ¶ added in v0.4.0
func WithCompareTLogHandler(logger *tlog.Logger) CompareBackendOption
WithCompareTLogHandler sets a custom tlog.Logger for a CompareBackend.
type DiscoveryBackend ¶ added in v0.4.0
type DiscoveryBackend = smtypes.DiscoveryBackend
DiscoveryBackend extends Backend with richer device discovery details.
type DiscoveryResult ¶ added in v0.3.1
type DiscoveryResult = smtypes.DiscoveryResult
DiscoveryResult holds the outcome of probing a single device during discovery.
type ExecBackend ¶ added in v0.4.0
type ExecBackend = smexec.ExecBackend
ExecBackend is the default backend that shells out to the smartctl binary.
func NewExecBackend ¶ added in v0.4.0
func NewExecBackend(opts ...ExecBackendOption) (*ExecBackend, error)
NewExecBackend creates a new exec backend.
type ExecBackendOption ¶ added in v0.4.0
ExecBackendOption configures an ExecBackend.
func WithExecCommander ¶ added in v0.4.0
func WithExecCommander(commander Commander) ExecBackendOption
WithExecCommander sets a custom commander for ExecBackend.
func WithExecLogHandler ¶ added in v0.4.0
func WithExecLogHandler(logger LogAdapter) ExecBackendOption
WithExecLogHandler sets a custom logger adapter for ExecBackend.
func WithExecSlogHandler ¶ added in v0.4.0
func WithExecSlogHandler(logger *slog.Logger) ExecBackendOption
WithExecSlogHandler sets a slog.Logger for ExecBackend.
func WithExecSmartctlPath ¶ added in v0.4.0
func WithExecSmartctlPath(path string) ExecBackendOption
WithExecSmartctlPath sets a custom path to the smartctl binary for ExecBackend.
func WithExecTLogHandler ¶ added in v0.4.0
func WithExecTLogHandler(logger *tlog.Logger) ExecBackendOption
WithExecTLogHandler sets a tlog.Logger for ExecBackend.
type ExitCodeInfo ¶ added in v0.3.1
type ExitCodeInfo = smtypes.ExitCodeInfo
ExitCodeInfo breaks down the smartctl exit status into semantic groups.
type LogAdapter ¶ added in v0.4.0
type LogAdapter = smtypes.LogAdapter
LogAdapter captures the logging methods used by this package.
type NvmeControllerCapabilities ¶
type NvmeControllerCapabilities = smtypes.NvmeControllerCapabilities
NvmeControllerCapabilities represents NVMe controller capabilities.
type NvmeOptionalAdminCommands ¶
type NvmeOptionalAdminCommands = smtypes.NvmeOptionalAdminCommands
NvmeOptionalAdminCommands represents NVMe optional admin commands.
type NvmeSmartHealth ¶
type NvmeSmartHealth = smtypes.NvmeSmartHealth
NvmeSmartHealth represents NVMe SMART health information.
type NvmeSmartTestLog ¶ added in v0.2.3
type NvmeSmartTestLog = smtypes.NvmeSmartTestLog
NvmeSmartTestLog represents the NVMe self-test log.
type OfflineDataCollection ¶
type OfflineDataCollection = smtypes.OfflineDataCollection
OfflineDataCollection represents offline data collection status.
type PollingMinutes ¶
type PollingMinutes = smtypes.PollingMinutes
PollingMinutes represents polling minutes for different test types.
type ProgressCallback ¶
type ProgressCallback = smtypes.ProgressCallback
ProgressCallback reports self-test progress.
type SelfTestInfo ¶
type SelfTestInfo = smtypes.SelfTestInfo
SelfTestInfo represents available self-tests and their durations.
type SmartAttribute ¶
type SmartAttribute = smtypes.SmartAttribute
SmartAttribute represents a single SMART attribute.
type SmartClient ¶
type SmartClient interface {
ScanDevices(ctx context.Context) ([]Device, error)
GetSMARTInfo(ctx context.Context, devicePath string) (*SMARTInfo, error)
CheckHealth(ctx context.Context, devicePath string) (bool, error)
GetDeviceInfo(ctx context.Context, devicePath string) (map[string]interface{}, error)
RunSelfTest(ctx context.Context, devicePath string, testType string) error
RunSelfTestWithProgress(ctx context.Context, devicePath string, testType string, callback ProgressCallback) error
GetAvailableSelfTests(ctx context.Context, devicePath string) (*SelfTestInfo, error)
GetAvailableSelfTestsFromInfo(smartInfo *SMARTInfo) *SelfTestInfo
IsSMARTSupported(ctx context.Context, devicePath string) (*SmartSupport, error)
GetSMARTSupportFromInfo(smartInfo *SMARTInfo) *SmartSupport
EnableSMART(ctx context.Context, devicePath string) error
DisableSMART(ctx context.Context, devicePath string) error
AbortSelfTest(ctx context.Context, devicePath string) error
DiscoverDevices(ctx context.Context) ([]DiscoveryResult, error)
Close() error
}
SmartClient interface defines the methods for interacting with smartmontools.
func NewClient ¶
func NewClient(opts ...ClientOption) (SmartClient, error)
NewClient creates a new smartmontools client with optional configuration. If no Backend is provided via WithBackend, an ExecBackend is created using any pending exec options (e.g., from WithSmartctlPath or WithCommander). If no log handler is provided, a tlog debug-level logger is used. If no context is provided, context.Background() is used as the default.
type SmartStatus ¶
type SmartStatus = smtypes.SmartStatus
SmartStatus represents the overall SMART health status.
type SmartSupport ¶
type SmartSupport = smtypes.SmartSupport
SmartSupport represents SMART availability and enablement status.
type SmartctlInfo ¶
type SmartctlInfo = smtypes.SmartctlInfo
SmartctlInfo represents smartctl metadata and messages.
type StatusField ¶
type StatusField = smtypes.StatusField
StatusField represents a SMART status field.
type Temperature ¶
type Temperature = smtypes.Temperature
Temperature represents device temperature.
type UserCapacity ¶
type UserCapacity = smtypes.UserCapacity
UserCapacity represents storage device capacity information.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
backends
|
|
|
compare
Package compare provides a virtual Backend that runs multiple backends in parallel, uses the first (master) backend's results as the response, and logs discrepancies between backends for testing and validation purposes.
|
Package compare provides a virtual Backend that runs multiple backends in parallel, uses the first (master) backend's results as the response, and logs discrepancies between backends for testing and validation purposes. |
|
exec
Package smartmontools provides Go bindings for interfacing with smartmontools to monitor and manage storage device health using S.M.A.R.T. data.
|
Package smartmontools provides Go bindings for interfacing with smartmontools to monitor and manage storage device health using S.M.A.R.T. data. |
|
lib
Package lib provides a Backend implementation that loads the smartmon wrapper library via purego (no CGO required).
|
Package lib provides a Backend implementation that loads the smartmon wrapper library via purego (no CGO required). |