@@ -20,6 +20,7 @@ import (
2020 "fmt"
2121 "log/slog"
2222 "os"
23+ "sort"
2324 "strconv"
2425 "strings"
2526
@@ -74,6 +75,7 @@ type diskstatsCollector struct {
7475 descs []typedDesc
7576 filesystemInfoDesc typedDesc
7677 deviceMapperInfoDesc typedDesc
78+ deviceMapperBackingDesc typedDesc
7779 ataDescs map [string ]typedDesc
7880 logger * slog.Logger
7981 getUdevDeviceProperties func (uint32 , uint32 ) (udevInfo , error )
@@ -224,6 +226,13 @@ func NewDiskstatsCollector(logger *slog.Logger) (Collector, error) {
224226 nil ,
225227 ), valueType : prometheus .GaugeValue ,
226228 },
229+ deviceMapperBackingDesc : typedDesc {
230+ desc : prometheus .NewDesc (prometheus .BuildFQName (namespace , diskSubsystem , "device_mapper_backing_device_info" ),
231+ "Info about the underlying block devices of a device mapper device." ,
232+ []string {"device" , "backing_device" },
233+ nil ,
234+ ), valueType : prometheus .GaugeValue ,
235+ },
227236 ataDescs : map [string ]typedDesc {
228237 udevIDATAWriteCache : {
229238 desc : prometheus .NewDesc (prometheus .BuildFQName (namespace , diskSubsystem , "ata_write_cache" ),
@@ -351,6 +360,7 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error {
351360 info [udevDMLVName ],
352361 info [udevDMLVLayer ],
353362 )
363+ c .updateDeviceMapperBackingDevices (ch , dev )
354364 }
355365
356366 if ata := info [udevIDATA ]; ata != "" {
@@ -372,6 +382,23 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error {
372382 return nil
373383}
374384
385+ func (c * diskstatsCollector ) updateDeviceMapperBackingDevices (ch chan <- prometheus.Metric , dev string ) {
386+ underlying , err := c .fs .SysBlockDeviceUnderlyingDevices (dev )
387+ if err != nil {
388+ if ! os .IsNotExist (err ) {
389+ c .logger .Debug ("Failed to get device mapper backing devices" , "device" , dev , "err" , err )
390+ }
391+ return
392+ }
393+
394+ sort .Strings (underlying .DeviceNames )
395+ for _ , backingDevice := range underlying .DeviceNames {
396+ ch <- c .deviceMapperBackingDesc .mustNewConstMetric (1.0 , dev ,
397+ backingDevice ,
398+ )
399+ }
400+ }
401+
375402func getUdevDeviceProperties (major , minor uint32 ) (udevInfo , error ) {
376403 filename := udevDataFilePath (fmt .Sprintf ("b%d:%d" , major , minor ))
377404
0 commit comments