Skip to content

Commit fc9dc0c

Browse files
committed
feat: support disk smart config and status
Adds DiskSMARTConfig and SMARTStatus Signed-off-by: Maja Bojarska <maja.bojarska@siderolabs.com>
1 parent 076c381 commit fc9dc0c

30 files changed

Lines changed: 9096 additions & 11511 deletions

File tree

.golangci.yml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ linters:
219219
- golang.zx2c4.com/wireguard/wgctrl
220220
- github.com/mdlayher/ethtool
221221
- github.com/secure-io/siv-go
222+
- github.com/anatol/smart.go
222223
replace-local: true
223224
exclude-forbidden: false
224225
retract-allow-no-explanation: false
@@ -247,7 +248,18 @@ linters:
247248
disabled: true
248249
rowserrcheck: {}
249250
staticcheck:
250-
checks: ["all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022", "-QF1001", "-QF1008"]
251+
checks:
252+
[
253+
"all",
254+
"-ST1000",
255+
"-ST1003",
256+
"-ST1016",
257+
"-ST1020",
258+
"-ST1021",
259+
"-ST1022",
260+
"-QF1001",
261+
"-QF1008",
262+
]
251263
testpackage: {}
252264
unparam:
253265
check-exported: false

api/resource/definitions/block/block.proto

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ syntax = "proto3";
22

33
package talos.resource.definitions.block;
44

5-
option go_package = "github.com/siderolabs/talos/pkg/machinery/api/resource/definitions/block";
6-
option java_package = "dev.talos.api.resource.definitions.block";
7-
85
import "google/api/expr/v1alpha1/checked.proto";
96
import "google/protobuf/duration.proto";
107
import "google/protobuf/timestamp.proto";
118
import "resource/definitions/enums/enums.proto";
129

10+
option go_package = "github.com/siderolabs/talos/pkg/machinery/api/resource/definitions/block";
11+
option java_package = "dev.talos.api.resource.definitions.block";
12+
1313
// DeviceSpec is the spec for devices status.
1414
message DeviceSpec {
1515
string type = 1;
@@ -242,6 +242,45 @@ message ProvisioningSpec {
242242
FilesystemSpec filesystem_spec = 4;
243243
}
244244

245+
// SMARTAttribute is a single ATA SMART attribute.
246+
message SMARTAttribute {
247+
uint32 id = 1;
248+
string name = 2;
249+
uint32 current = 3;
250+
uint32 worst = 4;
251+
uint32 threshold = 5;
252+
uint64 raw_value = 6;
253+
bool failing = 7;
254+
}
255+
256+
// SMARTStatusSpec is the spec for SMARTStatus resource.
257+
message SMARTStatusSpec {
258+
// DevPath is the path to the block device, e.g. /dev/sda.
259+
string dev_path = 1;
260+
// DeviceType is the SMART device type: "nvme", "sata" or "scsi".
261+
string device_type = 2;
262+
// Healthy is the overall SMART health verdict computed by Talos.
263+
bool healthy = 3;
264+
// Message carries additional details, e.g. why the disk is unhealthy or that
265+
// the probe was skipped because the disk was in standby.
266+
string message = 4;
267+
// PowerState reports the disk power mode observed during the last probe, e.g.
268+
// "active", "idle" or "standby". SMART data is not refreshed while the disk is
269+
// in standby (to avoid spinning it up).
270+
string power_state = 5;
271+
// Temperature is the disk temperature in degrees Celsius.
272+
uint32 temperature = 6;
273+
uint64 power_on_hours = 7;
274+
uint64 power_cycles = 8;
275+
// NVMe-specific fields.
276+
uint32 percent_used = 9;
277+
uint32 available_spare = 10;
278+
uint32 critical_warning = 11;
279+
uint64 media_errors = 12;
280+
// Attributes is the raw ATA SMART attribute table (empty for NVMe/SCSI).
281+
repeated SMARTAttribute attributes = 13;
282+
}
283+
245284
// SwapStatusSpec is the spec for SwapStatuss resource.
246285
message SwapStatusSpec {
247286
string device = 1;
@@ -394,4 +433,3 @@ message ZswapStatusSpec {
394433
uint64 reject_compress_poor = 9;
395434
uint64 written_back_pages = 10;
396435
}
397-

go.mod

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ module github.com/siderolabs/talos
33
go 1.26.5
44

55
replace (
6+
// forked to set O_CLOEXEC on device open and add SataDevice.CheckPowerMode (skip standby disks)
7+
github.com/anatol/smart.go => github.com/majabojarska/smart.go v0.0.0-20260707122632-d93e71f8295c
8+
69
// forked coredns so we don't carry caddy and other stuff into the Talos
710
github.com/coredns/coredns => github.com/siderolabs/coredns v1.14.53
811

@@ -52,6 +55,7 @@ require (
5255
github.com/aws/aws-sdk-go-v2/service/acm v1.43.0
5356
github.com/aws/aws-sdk-go-v2/service/kms v1.55.0
5457
github.com/aws/smithy-go v1.27.4
58+
github.com/anatol/smart.go v0.0.0-20260707122632-d93e71f8295c
5559
github.com/beevik/ntp v1.5.0
5660
github.com/beevik/nts v0.3.1
5761
github.com/blang/semver/v4 v4.0.0

go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1 h1:+JkXLHME8vLJafGhOH4ao
7272
github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1/go.mod h1:nuudZmJhzWtx2212z+pkuy7B6nkBqa+xwNXZHL1j8cg=
7373
github.com/alexflint/go-filemutex v1.3.0 h1:LgE+nTUWnQCyRKbpoceKZsPQbs84LivvgwUymZXdOcM=
7474
github.com/alexflint/go-filemutex v1.3.0/go.mod h1:U0+VA/i30mGBlLCrFPGtTe9y6wGQfNAWPBTekHQ+c8A=
75+
github.com/anatol/vmtest v0.0.0-20260313235012-c2b0479898b4 h1:E9KSKETdT7YYxgOAWMRshWLoMF40nV53ZFTPskPXUTI=
76+
github.com/anatol/vmtest v0.0.0-20260313235012-c2b0479898b4/go.mod h1:LQKSHEViwHPr4yRxK/6U+WpYY8ytg1uvVrjt/+PYgfI=
7577
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
7678
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
7779
github.com/apparentlymart/go-cidr v1.1.1 h1:oEEk8CE0HP0YpHxsegk/TaOtR2FLHdWv4p3eM4ceUwg=
@@ -589,6 +591,8 @@ github.com/lmittmann/tint v1.2.0 h1:AogHRHy8HUJUnNJBHJlYa+fR4YY8mko2cnCp67xn9JY=
589591
github.com/lmittmann/tint v1.2.0/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=
590592
github.com/lucasb-eyer/go-colorful v1.4.0 h1:UtrWVfLdarDgc44HcS7pYloGHJUjHV/4FwW4TvVgFr4=
591593
github.com/lucasb-eyer/go-colorful v1.4.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
594+
github.com/majabojarska/smart.go v0.0.0-20260707122632-d93e71f8295c h1:9eLHH+oFEf6zuz49vUtL0hI0FRD5qGgXn1G4wBEr4cc=
595+
github.com/majabojarska/smart.go v0.0.0-20260707122632-d93e71f8295c/go.mod h1:PrHdljtLe/VXVRH+zAJOcPjHkOHjF8/T2Arblruu/ac=
592596
github.com/martinlindhe/base36 v1.1.1 h1:1F1MZ5MGghBXDZ2KJ3QfxmiydlWOGB8HCEtkap5NkVg=
593597
github.com/martinlindhe/base36 v1.1.1/go.mod h1:vMS8PaZ5e/jV9LwFKlm0YLnXl/hpOihiBxKkIoc3g08=
594598
github.com/mattn/go-colorable v0.1.15 h1:+u9SLTRGnXv73cEsnsmoZBom+dMU88B2M0aDcWy0/jY=
@@ -950,6 +954,8 @@ github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C
950954
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs=
951955
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE=
952956
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk=
957+
github.com/tmc/scp v0.0.0-20170824174625-f7b48647feef h1:7D6Nm4D6f0ci9yttWaKjM1TMAXrH5Su72dojqYGntFY=
958+
github.com/tmc/scp v0.0.0-20170824174625-f7b48647feef/go.mod h1:WLFStEdnJXpjK8kd4qKLwQKX/1vrDzp5BcDyiZJBHJM=
953959
github.com/transparency-dev/formats v0.1.1 h1:4bVHJc+KdBgpA1OJD1yjI+g0i5Z1graCppTMH8lWKJI=
954960
github.com/transparency-dev/formats v0.1.1/go.mod h1:qtZ8goRuJ8FTBG9c9+Bj0rn2rUG7eG/AUTkr+Aw3jFw=
955961
github.com/transparency-dev/merkle v0.0.2 h1:Q9nBoQcZcgPamMkGn7ghV8XiTZ/kRxn1yCG81+twTK4=

hack/release.toml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,32 @@ trim:
466466
enabled: true
467467
interval: 24h0m0s
468468
```
469+
"""
470+
471+
[notes.disk_smart]
472+
title = "Disk SMART Status"
473+
description = """\
474+
Talos now collects SMART (Self-Monitoring, Analysis and Reporting Technology) health information from disks,
475+
exposed via the new `SMARTStatus` resource (one per disk, keyed by the disk device name):
476+
477+
```bash
478+
talosctl get smart
479+
```
480+
481+
The resource reports an overall health verdict, temperature, power-on hours and power cycles, NVMe wear
482+
indicators (percent used, available spare, critical warning, media errors) and, for ATA/SATA disks, the raw
483+
SMART attribute table with per-attribute thresholds.
484+
485+
SMART collection is enabled by default. Rotational disks are never spun up just to be probed: a disk in
486+
standby is detected via ATA `CHECK POWER MODE` and its SMART data is left untouched until it is active again.
487+
Collection can be tuned or disabled via the new `DiskSMARTConfig` document:
488+
489+
```yaml
490+
apiVersion: v1alpha1
491+
kind: DiskSMARTConfig
492+
enabled: true
493+
interval: 30m0s
494+
```
469495
"""
470496

471497
[notes.unattended_install]

0 commit comments

Comments
 (0)