smartmontools

package module
v0.2.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 5, 2026 License: GPL-3.0 Imports: 12 Imported by: 0

README

⚠️ IMPORTANT — Very early development

This project is in very early development. The current implementation executes the external smartctl binary (via exec) and parses its output. It does NOT currently provide native Go bindings, direct ioctl integration, or libgoffi-based integration. Those integrations are planned for future releases. Use this library for experimentation only.

smartmontools-go

A Go library that interfaces with smartmontools to monitor and manage storage device health using S.M.A.R.T. (Self-Monitoring, Analysis, and Reporting Technology) data.

CI Coverage Status Stable Release Prerelease

Features

  • 🔍 Device Scanning: Automatically detect available storage devices
  • 💚 Health Monitoring: Check device health status using SMART data
  • 📊 SMART Attributes: Read and parse detailed SMART attributes
  • 🌡️ Temperature Monitoring: Track device temperature
  • ⚙️ Self-Tests: Initiate and monitor SMART self-tests
  • 🔧 Device Information: Retrieve model, serial number, firmware version, and more
  • 🔌 USB Bridge Support: Automatic fallback for unknown USB bridges with embedded device database

Prerequisites

This library requires smartctl (part of smartmontools) to be installed on your system.

Minimum supported version: smartctl 7.0 (for JSON -j output).

Linux
# Debian/Ubuntu
sudo apt-get install smartmontools

# RHEL/CentOS/Fedora
sudo yum install smartmontools

# Arch Linux
sudo pacman -S smartmontools
macOS
brew install smartmontools
Windows

Download and install from smartmontools.org

Installation

go get github.com/dianlight/smartmontools-go

Usage

Basic Example
package main

import (
    "fmt"
    "log"

    "github.com/dianlight/smartmontools-go"
)

func main() {
    // Create a new client
    client, err := smartmontools.NewClient()
    if err != nil {
        log.Fatalf("Failed to create client: %v", err)
    }

    // Scan for devices
    devices, err := client.ScanDevices()
    if err != nil {
        log.Fatalf("Failed to scan devices: %v", err)
    }

    for _, device := range devices {
        fmt.Printf("Device: %s (type: %s)\n", device.Name, device.Type)
        
        // Check health
        healthy, err := client.CheckHealth(device.Name)
        if err != nil {
            log.Printf("Failed to check health: %v", err)
            continue
        }
        
        if healthy {
            fmt.Println("  Health: PASSED ✓")
        } else {
            fmt.Println("  Health: FAILED ✗")
        }
    }
}
Getting SMART Information
// Get detailed SMART information
smartInfo, err := client.GetSMARTInfo("/dev/sda")
if err != nil {
    log.Fatalf("Failed to get SMART info: %v", err)
}

fmt.Printf("Model: %s\n", smartInfo.ModelName)
fmt.Printf("Serial: %s\n", smartInfo.SerialNumber)
fmt.Printf("Temperature: %d°C\n", smartInfo.Temperature.Current)
fmt.Printf("Power On Hours: %d\n", smartInfo.PowerOnTime.Hours)

// Access SMART attributes
if smartInfo.AtaSmartData != nil {
    for _, attr := range smartInfo.AtaSmartData.Table {
        fmt.Printf("Attribute %d (%s): %d\n", attr.ID, attr.Name, attr.Value)
    }
}
Running Self-Tests
// Run a short self-test
err := client.RunSelfTest("/dev/sda", "short")
if err != nil {
    log.Fatalf("Failed to run self-test: %v", err)
}

// Available test types: "short", "long", "conveyance", "offline"
Custom smartctl Path
// If smartctl is not in PATH or you want to use a specific binary
client, err := smartmontools.NewClient(smartmontools.WithSmartctlPath("/usr/local/sbin/smartctl"))
if err != nil {
    log.Fatalf("Failed to create client: %v", err)
}
Logging

The library uses the tlog package for structured logging.

Default behavior:

  • When you call smartmontools.NewClient() without a WithLogHandler option, the client creates a debug-level *tlog.Logger (via tlog.NewLoggerWithLevel(tlog.LevelDebug)) so that diagnostic output (command execution, fallbacks, warnings) is available.
  • You can adjust the global log level at runtime using tlog.SetLevelFromString("info") or tlog.SetLevel(tlog.LevelInfo). Levels include: trace, debug, info, notice, warn, error, fatal.
  • All internal logging is key/value structured. Expensive debug operations are guarded; if you perform your own heavy debug logging, first check with tlog.IsLevelEnabled(tlog.LevelDebug).

Override the logger for a specific client instance:

import (
    "context"
    "log"
    "github.com/dianlight/smartmontools-go"
    "github.com/dianlight/tlog"
)

func main() {
    // Create a custom logger which only logs WARN and above.
    customLogger := tlog.NewLoggerWithLevel(tlog.LevelWarn)

    client, err := smartmontools.NewClient(
        smartmontools.WithLogHandler(customLogger),
    )
    if err != nil {
        log.Fatalf("Failed to create client: %v", err)
    }

    // Example global level change (applies to package-level functions too)
    if err := tlog.SetLevelFromString("info"); err != nil {
        tlog.Warn("Failed to set log level", "error", err)
    }

    devices, err := client.ScanDevices(context.Background())
    if err != nil {
        tlog.Error("Scan failed", "error", err)
        return
    }
    tlog.Info("Scan complete", "count", len(devices))
}

If you need a logger instance with a different minimum level temporarily (without changing globals), use:

traceLogger := tlog.WithLevel(tlog.LevelTrace) // returns *slog.Logger for ad-hoc usage
traceLogger.Log(context.Background(), tlog.LevelTrace, "Detailed trace")

For code interacting with the client, prefer passing a *tlog.Logger via WithLogHandler. For ad-hoc logging outside the client lifecycle, use the package-level helpers (tlog.Info, tlog.DebugContext, etc.).

Graceful shutdown of callback processor (if you registered callbacks):

defer tlog.Shutdown() // Ensures queued callback events are processed before exit
Custom Default Context
// Set a default context that will be used when methods are called with nil context
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

client, err := smartmontools.NewClient(smartmontools.WithContext(ctx))
if err != nil {
    log.Fatalf("Failed to create client: %v", err)
}

// Now when calling with nil context, the client will use the configured default
info, err := client.GetSMARTInfo(nil, "/dev/sda") // Uses the 30s timeout context
Combining Options
// Combine multiple options
client, err := smartmontools.NewClient(
    smartmontools.WithSmartctlPath("/usr/local/sbin/smartctl"),
    smartmontools.WithLogHandler(logger),
    smartmontools.WithContext(ctx),
)
if err != nil {
    log.Fatalf("Failed to create client: %v", err)
}
USB Bridge Support

The library includes automatic support for USB storage devices that use unknown USB bridges. When smartctl reports an "Unknown USB bridge" error, the library:

  1. Checks embedded database: Looks up the USB vendor:product ID in the embedded standard drivedb.h from smartmontools
  2. Automatic fallback: If found, uses the known device type; otherwise falls back to -d sat
  3. Caches results: Remembers successful device types for faster future access
client, _ := smartmontools.NewClient()

// Works automatically with USB bridges, even if unknown to smartctl
info, err := client.GetSMARTInfo("/dev/disk/by-id/usb-Intenso_Memory_Center-0:0")
if err != nil {
    log.Fatalf("Failed to get SMART info: %v", err)
}

fmt.Printf("Model: %s\n", info.ModelName)
fmt.Printf("Health: %v\n", info.SmartStatus.Passed)

The embedded database is the official smartmontools drivedb.h which contains USB bridge definitions from the upstream project. See docs/drivedb.md for details.

API Reference

See APIDOC.md for detailed API documentation.

Examples

See the examples directory for more detailed usage examples:

  • Basic Usage - Demonstrates device scanning, health checking, and SMART info retrieval

To run the basic example:

cd examples/basic
go run main.go

Note: Some operations require root/administrator privileges to access disk devices.

Architecture

This library uses a command-line wrapper approach, executing smartctl commands and parsing their JSON output. The library leverages smartmontools' built-in JSON output format for reliable and structured data extraction.

While the project references libgoffi in its description, the current implementation uses the command-line interface for maximum compatibility and reliability. Future versions may incorporate direct library bindings using libgoffi for enhanced performance.

📚 For a comprehensive analysis of different SMART access approaches, see our Architecture Decision Record (ADR-001), which covers:

  • Command wrapper (current approach)
  • Direct ioctl access
  • Shared library with FFI
  • Hybrid approaches

The ADR includes detailed comparisons, code examples, performance benchmarks, and recommendations for different use cases.

Implementation details

  • Execution model: the library locates (or is given) a smartctl binary and executes it (os/exec). Commands use --json where available and the library parses the resulting JSON output.
  • Configurable path: you can pass a custom path with NewClientWithPath(path string) if smartctl is not on PATH or you want to use a specific binary.
  • Permissions: many SMART operations require root/administrator privileges or appropriate device access. Expect permission denied errors when running without sufficient rights.
  • Error handling: the library returns errors when smartctl exits non-zero, when JSON parsing fails, or when required fields are missing. Consumers should inspect errors and possibly the wrapped *exec.ExitError for diagnostics.
  • Limitations: because this approach shells out to an external binary, it has higher process overhead and depends on the installed smartmontools version and platform support. It does not (yet) provide direct ioctl access or in-process bindings.

Example command run by the library (illustrative):

smartctl --json -a /dev/sda

This will be parsed into the library's SMARTInfo structures.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Roadmap

Short-term (current):

  • Stabilize the exec-based API surface (ScanDevices, GetSMARTInfo, CheckHealth, RunSelfTest).
  • Improve error messages and diagnostics when smartctl is missing, incompatible, or returns non-JSON output.
  • Add more unit tests that mock smartctl JSON output.

Mid-term:

  • Add optional libgoffi-based bindings to call smartmontools in-process where supported.
  • Implement ioctl-based device access for platforms where direct calls are preferable and safe.
  • Provide clearer compatibility matrix and CI jobs for Linux/macOS/Windows.

Long-term:

  • Offer a native Go implementation/path that does not require an external smartctl binary for common operations.
  • Optimize performance and reduce process creation overhead for large-scale monitoring setups.

How to help:

  • If you'd like to work on native bindings, start by opening an issue describing the platform and approach (libgoffi vs ioctl-first).
  • Add tests that include representative smartctl --json outputs (captured from different smartmontools versions/devices).
  • Document platform-specific permission and packaging notes (e.g., macOS notarization, Windows admin requirements).

License

This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.

Acknowledgments

  • smartmontools - The underlying tool that makes this library possible
  • libgoffi - FFI adapter library for Go (for future enhancements)

CI and Makefile

This repository includes a Makefile with common targets and a GitHub Actions workflow that runs CI on push and pull_request to main.

Quick Makefile usage:

  • Run tests: make test
  • Run full CI locally (formats, vet, staticcheck, tests): make ci
  • Format code: make fmt
  • Build binary: make build

Staticcheck will be installed into your Go bin (GOBIN or GOPATH/bin) if not already present when you run make ci.

Documentation

Overview

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.

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 (ATA devices only)

Prerequisites

This library requires smartctl (part of smartmontools) to be installed:

Linux:

sudo apt-get install smartmontools  # Debian/Ubuntu
sudo yum install smartmontools       # RHEL/CentOS/Fedora
sudo pacman -S smartmontools         # Arch Linux

macOS:

brew install smartmontools

Windows:

Download from https://www.smartmontools.org/

Basic Usage

package main

import (
    "fmt"
    "log"

    "github.com/dianlight/smartmontools-go"
)

func main() {
    // Create a new client
    client, err := smartmontools.NewClient()
    if err != nil {
        log.Fatal(err)
    }

    // Scan for devices
    devices, err := client.ScanDevices()
    if err != nil {
        log.Fatal(err)
    }

    // Check health of first device
    if len(devices) > 0 {
        healthy, _ := client.CheckHealth(devices[0].Name)
        if healthy {
            fmt.Println("Device is healthy")
        }
    }
}

Standby Mode Handling

For ATA devices (ata, sat, sata, scsi), the library automatically adds the --nocheck=standby flag to smartctl commands. This prevents waking up devices that are in standby/sleep mode, which is especially useful for power-saving scenarios.

When a device is in standby mode:

  • GetSMARTInfo will return a SMARTInfo with InStandby set to true
  • CheckHealth will return an error indicating the device is in standby
  • GetDeviceInfo will return an error indicating the device is in standby
  • GetAvailableSelfTests will return an error indicating the device is in standby

NVMe devices do not support standby mode detection and do not receive the --nocheck=standby flag.

Permissions

Many operations require elevated privileges (root/administrator) to access disk devices. The library will return errors if permissions are insufficient.

Thread Safety

The Client type is safe for concurrent use by multiple goroutines.

Package smartmontools provides Go bindings for interfacing with smartmontools to monitor and manage storage device health using S.M.A.R.T. data.

This file contains functions for parsing and managing the embedded drivedb.h database from smartmontools, which includes USB bridge device mappings.

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

View Source
const (
	SmartAttrSSDLifeLeft       = 231 // SSD Life Left attribute
	SmartAttrSandForceInternal = 233 // SandForce Internal (SSD-specific)
	SmartAttrTotalLBAsWritten  = 234 // Total LBAs Written (SSD-specific)
)

SMART attribute IDs for SSD detection

Variables

This section is empty.

Functions

This section is empty.

Types

type AtaSmartData

type AtaSmartData struct {
	OfflineDataCollection *OfflineDataCollection `json:"offline_data_collection,omitempty"`
	SelfTest              *SelfTest              `json:"self_test,omitempty"`
	Capabilities          *Capabilities          `json:"capabilities,omitempty"`
	Table                 []SmartAttribute       `json:"table,omitempty"`
}

AtaSmartData represents ATA SMART attributes

type Capabilities

type Capabilities struct {
	Values                      []int `json:"values,omitempty"`
	ExecOfflineImmediate        bool  `json:"exec_offline_immediate_supported,omitempty"`
	SelfTestsSupported          bool  `json:"self_tests_supported,omitempty"`
	ConveyanceSelfTestSupported bool  `json:"conveyance_self_test_supported,omitempty"`
}

Capabilities represents SMART capabilities

type CapabilitiesOutput

type CapabilitiesOutput struct {
	AtaSmartData               *AtaSmartData               `json:"ata_smart_data,omitempty"`
	NvmeControllerCapabilities *NvmeControllerCapabilities `json:"nvme_controller_capabilities,omitempty"`
	NvmeOptionalAdminCommands  *NvmeOptionalAdminCommands  `json:"nvme_optional_admin_commands,omitempty"`
}

CapabilitiesOutput represents the output of smartctl -c -j

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client represents a smartmontools client

func (*Client) AbortSelfTest

func (c *Client) AbortSelfTest(ctx context.Context, devicePath string) error

AbortSelfTest aborts a running self-test on a device

func (*Client) CheckHealth

func (c *Client) CheckHealth(ctx context.Context, devicePath string) (bool, error)

CheckHealth checks if a device is healthy according to SMART

func (*Client) DisableSMART

func (c *Client) DisableSMART(ctx context.Context, devicePath string) error

DisableSMART disables SMART monitoring on a device

func (*Client) EnableSMART

func (c *Client) EnableSMART(ctx context.Context, devicePath string) error

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) GetDeviceInfo

func (c *Client) GetDeviceInfo(ctx context.Context, devicePath string) (map[string]interface{}, error)

GetDeviceInfo retrieves basic device information

func (*Client) GetSMARTInfo

func (c *Client) GetSMARTInfo(ctx context.Context, devicePath string) (*SMARTInfo, error)

GetSMARTInfo retrieves SMART information for a device

func (*Client) IsSMARTSupported

func (c *Client) IsSMARTSupported(ctx context.Context, devicePath string) (*SmartSupport, error)

IsSMARTSupported checks if SMART is supported on a device and if it's enabled

func (*Client) RunSelfTest

func (c *Client) RunSelfTest(ctx context.Context, devicePath string, testType string) error

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

func (*Client) ScanDevices

func (c *Client) ScanDevices(ctx context.Context) ([]Device, error)

ScanDevices scans for available storage devices

type ClientOption added in v0.1.1

type ClientOption func(*Client)

ClientOption is a function that configures a Client

func WithCommander added in v0.1.1

func WithCommander(commander Commander) ClientOption

WithCommander sets a custom commander for testing purposes

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

func WithTLogHandler added in v0.1.4

func WithTLogHandler(logger *tlog.Logger) ClientOption

WithTLogHandler sets a custom tlog.Logger for the client.

type Cmd

type Cmd interface {
	Output() ([]byte, error)
	Run() error
}

Cmd interface for command execution

type Commander

type Commander interface {
	Command(ctx context.Context, logger logAdapter, name string, arg ...string) Cmd
}

Commander interface for executing commands

type Device

type Device struct {
	Name string
	Type string
}

Device represents a storage device

type Flags

type Flags struct {
	Value         int    `json:"value"`
	String        string `json:"string"`
	PreFailure    bool   `json:"prefailure"`
	UpdatedOnline bool   `json:"updated_online"`
	Performance   bool   `json:"performance"`
	ErrorRate     bool   `json:"error_rate"`
	EventCount    bool   `json:"event_count"`
	AutoKeep      bool   `json:"auto_keep"`
}

Flags represents attribute flags

type Message

type Message struct {
	String   string `json:"string"`
	Severity string `json:"severity,omitempty"`
}

Message represents a message from smartctl

type NvmeControllerCapabilities

type NvmeControllerCapabilities struct {
	SelfTest bool `json:"self_test,omitempty"`
}

NvmeControllerCapabilities represents NVMe controller capabilities

type NvmeOptionalAdminCommands

type NvmeOptionalAdminCommands struct {
	SelfTest bool `json:"self_test,omitempty"`
}

NvmeOptionalAdminCommands represents NVMe optional admin commands

type NvmeSmartHealth

type NvmeSmartHealth struct {
	CriticalWarning      int   `json:"critical_warning,omitempty"`
	Temperature          int   `json:"temperature,omitempty"`
	AvailableSpare       int   `json:"available_spare,omitempty"`
	AvailableSpareThresh int   `json:"available_spare_threshold,omitempty"`
	PercentageUsed       int   `json:"percentage_used,omitempty"`
	DataUnitsRead        int64 `json:"data_units_read,omitempty"`
	DataUnitsWritten     int64 `json:"data_units_written,omitempty"`
	HostReadCommands     int64 `json:"host_read_commands,omitempty"`
	HostWriteCommands    int64 `json:"host_write_commands,omitempty"`
	ControllerBusyTime   int64 `json:"controller_busy_time,omitempty"`
	PowerCycles          int64 `json:"power_cycles,omitempty"`
	PowerOnHours         int64 `json:"power_on_hours,omitempty"`
	UnsafeShutdowns      int64 `json:"unsafe_shutdowns,omitempty"`
	MediaErrors          int64 `json:"media_errors,omitempty"`
	NumErrLogEntries     int64 `json:"num_err_log_entries,omitempty"`
	WarningTempTime      int   `json:"warning_temp_time,omitempty"`
	CriticalCompTime     int   `json:"critical_comp_time,omitempty"`
	TemperatureSensors   []int `json:"temperature_sensors,omitempty"`
}

NvmeSmartHealth represents NVMe SMART health information

type NvmeSmartTestLog added in v0.2.3

type NvmeSmartTestLog struct {
	CurrentOpeation   *int `json:"current_operation,omitempty"`
	CurrentCompletion *int `json:"current_completion,omitempty"`
}

type OfflineDataCollection

type OfflineDataCollection struct {
	Status            *StatusField `json:"status,omitempty"`
	CompletionSeconds int          `json:"completion_seconds,omitempty"`
}

OfflineDataCollection represents offline data collection status

type PollingMinutes

type PollingMinutes struct {
	Short      int `json:"short,omitempty"`
	Extended   int `json:"extended,omitempty"`
	Conveyance int `json:"conveyance,omitempty"`
}

PollingMinutes represents polling minutes for different test types

type PowerOnTime

type PowerOnTime struct {
	Hours int `json:"hours"`
}

PowerOnTime represents power on time

type ProgressCallback

type ProgressCallback func(progress int, status string)

ProgressCallback is a function type for reporting progress

type Raw

type Raw struct {
	Value  int64  `json:"value"`
	String string `json:"string"`
}

Raw represents raw attribute value

type SMARTInfo

type SMARTInfo struct {
	Device                     Device                      `json:"device"`
	ModelFamily                string                      `json:"model_family,omitempty"`
	ModelName                  string                      `json:"model_name,omitempty"`
	SerialNumber               string                      `json:"serial_number,omitempty"`
	Firmware                   string                      `json:"firmware_version,omitempty"`
	UserCapacity               *UserCapacity               `json:"user_capacity,omitempty"`
	RotationRate               *int                        `json:"rotation_rate,omitempty"` // Rotation rate in RPM (0 for SSDs, >0 for HDDs, nil if not available or not applicable)
	DiskType                   string                      `json:"-"`                       // Computed disk type: "SSD", "HDD", "NVMe", or "Unknown"
	InStandby                  bool                        `json:"in_standby,omitempty"`    // True if device is in standby/sleep mode (ATA only)
	SmartStatus                SmartStatus                 `json:"smart_status,omitempty"`
	SmartSupport               *SmartSupport               `json:"smart_support,omitempty"`
	AtaSmartData               *AtaSmartData               `json:"ata_smart_data,omitempty"`
	NvmeSmartHealth            *NvmeSmartHealth            `json:"nvme_smart_health_information_log,omitempty"`
	NvmeSmartTestLog           *NvmeSmartTestLog           `json:"nvme_smart_test_log,omitempty"`
	NvmeControllerCapabilities *NvmeControllerCapabilities `json:"nvme_controller_capabilities,omitempty"`
	Temperature                *Temperature                `json:"temperature,omitempty"`
	PowerOnTime                *PowerOnTime                `json:"power_on_time,omitempty"`
	PowerCycleCount            int                         `json:"power_cycle_count,omitempty"`
	Smartctl                   *SmartctlInfo               `json:"smartctl,omitempty"`
}

SMARTInfo represents comprehensive SMART information for a storage device

type SelfTest

type SelfTest struct {
	Status         *StatusField    `json:"status,omitempty"`
	PollingMinutes *PollingMinutes `json:"polling_minutes,omitempty"`
}

SelfTest represents self-test information

type SelfTestInfo

type SelfTestInfo struct {
	Available []string       `json:"available"`
	Durations map[string]int `json:"durations"`
}

SelfTestInfo represents available self-tests and their durations

type SmartAttribute

type SmartAttribute struct {
	ID         int    `json:"id"`
	Name       string `json:"name"`
	Value      int    `json:"value"`
	Worst      int    `json:"worst"`
	Thresh     int    `json:"thresh"`
	WhenFailed string `json:"when_failed,omitempty"`
	Flags      Flags  `json:"flags"`
	Raw        Raw    `json:"raw"`
}

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)
	IsSMARTSupported(ctx context.Context, devicePath string) (*SmartSupport, error)
	EnableSMART(ctx context.Context, devicePath string) error
	DisableSMART(ctx context.Context, devicePath string) error
	AbortSelfTest(ctx context.Context, devicePath string) 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 smartctl path is provided, it will search for smartctl in PATH. If no log handler is provided, it will use a tlog debug-level logger for diagnostic output. If no context is provided, context.Background() will be used as the default.

type SmartStatus

type SmartStatus struct {
	Running  bool `json:"running"`
	Passed   bool `json:"passed"`
	Damaged  bool `json:"damaged,omitempty"`
	Critical bool `json:"critical,omitempty"`
}

SmartStatus represents the overall SMART health status

type SmartSupport

type SmartSupport struct {
	Available bool `json:"available"`
	Enabled   bool `json:"enabled"`
}

SmartSupport represents SMART availability and enablement status.

type SmartctlInfo

type SmartctlInfo struct {
	Version    []int     `json:"version,omitempty"`
	Messages   []Message `json:"messages,omitempty"`
	ExitStatus int       `json:"exit_status,omitempty"`
}

SmartctlInfo represents smartctl metadata and messages

type StatusField

type StatusField struct {
	Value            int    `json:"value"`
	String           string `json:"string"`
	Passed           *bool  `json:"passed,omitempty"`
	RemainingPercent *int   `json:"remaining_percent,omitempty"`
}

StatusField represents a status field that can be either a simple string or a complex object

func (*StatusField) UnmarshalJSON

func (s *StatusField) UnmarshalJSON(data []byte) error

UnmarshalJSON allows StatusField to be parsed from either a JSON string (e.g., "completed") or a structured object with fields {value, string, passed, remaining_percent}.

type Temperature

type Temperature struct {
	Current int `json:"current"`
}

Temperature represents device temperature

type UserCapacity

type UserCapacity struct {
	Blocks int64 `json:"blocks"`
	Bytes  int64 `json:"bytes"`
}

UserCapacity represents storage device capacity information

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL