summarylogtreecommitdiffstats
path: root/293.patch
blob: 67177f759bd416adb9fcdc8b48229d2b6a733298 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
From ae7c8cf8b7ce1f0ac0fe101b79d71dba13fba2af Mon Sep 17 00:00:00 2001
From: Konstantin Shalygin <k0ste@k0ste.ru>
Date: Mon, 28 Apr 2025 14:07:55 +0300
Subject: [PATCH] feat: support for mine NVMe Volatile Memory Backup

This PR add's metric, when NVMe PLP is failed (bool)
Further use of the drive is unsafe; if the power fails, the data may be lost.

Healthy device
```console
[root@host]# smartctl --json --info --capabilities --health --attributes --tolerance=verypermissive --nocheck=standby --format=brief --log=error --device=nvme /dev/nvme1 | jq .smart_status
{
  "passed": true,
  "nvme": {
    "value": 0
  }
}
```

PLP failed
```console
[root@host]# smartctl --json --info --capabilities --health --attributes --tolerance=verypermissive --nocheck=standby --format=brief --log=error --device=nvme /dev/nvme0 | jq .smart_status
{
  "passed": false,
  "nvme": {
    "value": 16,
    "spare_below_threshold": false,
    "temperature_above_or_below_threshold": false,
    "reliability_degraded": false,
    "media_read_only": false,
    "volatile_memory_backup_failed": true,
    "persistent_memory_region_unreliable": false,
    "other": 0
  }
}
```

Signed-off-by: Konstantin Shalygin <k0ste@k0ste.ru>
---
 metrics.go  |  8 ++++++++
 smartctl.go | 18 +++++++++++++++++-
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/metrics.go b/metrics.go
index 0ac083f..e9c98e6 100644
--- a/metrics.go
+++ b/metrics.go
@@ -194,6 +194,14 @@ var (
 		},
 		nil,
 	)
+	metricDeviceVolatileMemoryBackupFailed = prometheus.NewDesc(
+		"smartctl_device_volatile_memory_backup_failed",
+		"Indicates that Volatile Memory Backup (NVMe PLP) is failed",
+		[]string{
+			"device",
+		},
+		nil,
+	)
 	metricDeviceBytesRead = prometheus.NewDesc(
 		"smartctl_device_bytes_read",
 		"",
diff --git a/smartctl.go b/smartctl.go
index b136b8b..30b4fa5 100644
--- a/smartctl.go
+++ b/smartctl.go
@@ -109,6 +109,7 @@ func (smart *SMARTctl) Collect() {
 		smart.mineNvmeCriticalWarning()
 		smart.mineNvmeMediaErrors()
 		smart.mineNvmeNumErrLogEntries()
+		smart.mineNvmeVolatileMemoryBackupFailed()
 		smart.mineNvmeBytesRead()
 		smart.mineNvmeBytesWritten()
 	}
@@ -382,6 +383,21 @@ func (smart *SMARTctl) mineNvmeNumErrLogEntries() {
 	)
 }
 
+func (smart *SMARTctl) mineNvmeVolatileMemoryBackupFailed() {
+	nvmeStatus := smart.json.Get("smart_status.nvme")
+	if nvmeStatus.Exists() {
+		volatileMemoryBackupFailed := nvmeStatus.Get("volatile_memory_backup_failed")
+		if volatileMemoryBackupFailed.Exists() {
+			smart.ch <- prometheus.MustNewConstMetric(
+				metricDeviceVolatileMemoryBackupFailed,
+				prometheus.CounterValue,
+				volatileMemoryBackupFailed.Float(),
+				smart.device.device,
+			)
+		}
+	}
+}
+
 // https://nvmexpress.org/wp-content/uploads/NVM-Express-NVM-Command-Set-Specification-1.0d-2023.12.28-Ratified.pdf
 // 4.1.4.2 SMART / Health Information (02h)
 // The SMART / Health Information log page is as defined in the NVM Express Base Specification. For the
@@ -472,7 +488,7 @@ func (smart *SMARTctl) mineSmartStatus() {
 	if smartStatus.Exists() {
 		smart.ch <- prometheus.MustNewConstMetric(
 			metricDeviceSmartStatus,
-			prometheus.GaugeValue,
+			prometheus.CounterValue,
 			smartStatus.Get("passed").Float(),
 			smart.device.device,
 		)