From 6ed84a3b4bfc8ffd316ade1bd059bac8d18c8f7d Mon Sep 17 00:00:00 2001 From: mehrdadbn9 Date: Tue, 24 Feb 2026 07:26:13 +0330 Subject: [PATCH 1/2] fix: handle 'delayed' state in sync_completed parsing When multiple MD RAID arrays share physical devices and a check/resync is triggered for more than one, the kernel delays the action on all but one device. In this case, sync_completed contains 'delayed' instead of 'none' or 'N / M'. This fix adds 'delayed' to the list of special values that should not be parsed as integers. Fixes prometheus/procfs#770 Related: prometheus/node_exporter#3500 --- sysfs/mdraid.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sysfs/mdraid.go b/sysfs/mdraid.go index 139c7ebe..d44414e0 100644 --- a/sysfs/mdraid.go +++ b/sysfs/mdraid.go @@ -136,7 +136,7 @@ func (fs FS) Mdraids() ([]Mdraid, error) { } if val, err := util.SysReadFile(filepath.Join(path, "sync_completed")); err == nil { - if val != "none" { + if val != "none" && val != "delayed" { var a, b uint64 // File contains two values representing the fraction of number of completed From 427ead07e18be1bb546bb645f7323ad4232ef044 Mon Sep 17 00:00:00 2001 From: mehrdadbn9 Date: Wed, 25 Feb 2026 21:38:24 +0330 Subject: [PATCH 2/2] Add comprehensive tests for delayed sync_completed parsing - Add TestMdraidDelayedSyncCompleted to verify delayed state handling - Include complete test data with delayed sync_completed value - Test verifies SyncCompleted=0, SyncAction='resync', and all component states Fixes prometheus/procfs#786 --- sysfs/mdraid_test.go | 23 +++++++++++++++++++ testdata/issue770/block/md127/md/array_state | 1 + testdata/issue770/block/md127/md/chunk_size | 1 + testdata/issue770/block/md127/md/degraded | 1 + .../issue770/block/md127/md/dev-sdaa/state | 1 + .../issue770/block/md127/md/dev-sdn/state | 1 + .../issue770/block/md127/md/dev-sdo/state | 1 + .../issue770/block/md127/md/dev-sdp/state | 1 + testdata/issue770/block/md127/md/level | 1 + .../issue770/block/md127/md/metadata_version | 1 + testdata/issue770/block/md127/md/raid_disks | 1 + testdata/issue770/block/md127/md/sync_action | 1 + .../issue770/block/md127/md/sync_completed | 1 + testdata/issue770/block/md127/md/uuid | 1 + 14 files changed, 36 insertions(+) create mode 100644 testdata/issue770/block/md127/md/array_state create mode 100644 testdata/issue770/block/md127/md/chunk_size create mode 100644 testdata/issue770/block/md127/md/degraded create mode 100644 testdata/issue770/block/md127/md/dev-sdaa/state create mode 100644 testdata/issue770/block/md127/md/dev-sdn/state create mode 100644 testdata/issue770/block/md127/md/dev-sdo/state create mode 100644 testdata/issue770/block/md127/md/dev-sdp/state create mode 100644 testdata/issue770/block/md127/md/level create mode 100644 testdata/issue770/block/md127/md/metadata_version create mode 100644 testdata/issue770/block/md127/md/raid_disks create mode 100644 testdata/issue770/block/md127/md/sync_action create mode 100644 testdata/issue770/block/md127/md/sync_completed create mode 100644 testdata/issue770/block/md127/md/uuid diff --git a/sysfs/mdraid_test.go b/sysfs/mdraid_test.go index cef9a342..59a88b7b 100644 --- a/sysfs/mdraid_test.go +++ b/sysfs/mdraid_test.go @@ -131,3 +131,26 @@ func TestMdraidStats(t *testing.T) { t.Fatalf("unexpected Mdraid (-want +got):\n%s", diff) } } +func TestMdraidDelayedSyncCompleted(t *testing.T) { + fs, err := NewFS("testdata/fixtures/sys/issue770") + if err != nil { + t.Fatal(err) + } + + mdraids, err := fs.Mdraids() + if err != nil { + t.Fatal(err) + } + + if len(mdraids) != 1 { + t.Fatalf("expected 1 mdraid, got %d", len(mdraids)) + } + + md := mdraids[0] + if md.SyncCompleted != 0 { + t.Fatalf("expected SyncCompleted=0 for 'delayed' state, got %f", md.SyncCompleted) + } + if md.SyncAction != "resync" { + t.Fatalf("expected SyncAction='resync', got '%s'", md.SyncAction) + } +} diff --git a/testdata/issue770/block/md127/md/array_state b/testdata/issue770/block/md127/md/array_state new file mode 100644 index 00000000..83126302 --- /dev/null +++ b/testdata/issue770/block/md127/md/array_state @@ -0,0 +1 @@ +clean diff --git a/testdata/issue770/block/md127/md/chunk_size b/testdata/issue770/block/md127/md/chunk_size new file mode 100644 index 00000000..c0758e93 --- /dev/null +++ b/testdata/issue770/block/md127/md/chunk_size @@ -0,0 +1 @@ +524288 diff --git a/testdata/issue770/block/md127/md/degraded b/testdata/issue770/block/md127/md/degraded new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/testdata/issue770/block/md127/md/degraded @@ -0,0 +1 @@ +0 diff --git a/testdata/issue770/block/md127/md/dev-sdaa/state b/testdata/issue770/block/md127/md/dev-sdaa/state new file mode 100644 index 00000000..cb75ec0a --- /dev/null +++ b/testdata/issue770/block/md127/md/dev-sdaa/state @@ -0,0 +1 @@ +spare diff --git a/testdata/issue770/block/md127/md/dev-sdn/state b/testdata/issue770/block/md127/md/dev-sdn/state new file mode 100644 index 00000000..96499100 --- /dev/null +++ b/testdata/issue770/block/md127/md/dev-sdn/state @@ -0,0 +1 @@ +in_sync diff --git a/testdata/issue770/block/md127/md/dev-sdo/state b/testdata/issue770/block/md127/md/dev-sdo/state new file mode 100644 index 00000000..96499100 --- /dev/null +++ b/testdata/issue770/block/md127/md/dev-sdo/state @@ -0,0 +1 @@ +in_sync diff --git a/testdata/issue770/block/md127/md/dev-sdp/state b/testdata/issue770/block/md127/md/dev-sdp/state new file mode 100644 index 00000000..ddae9041 --- /dev/null +++ b/testdata/issue770/block/md127/md/dev-sdp/state @@ -0,0 +1 @@ +faulty diff --git a/testdata/issue770/block/md127/md/level b/testdata/issue770/block/md127/md/level new file mode 100644 index 00000000..341b806e --- /dev/null +++ b/testdata/issue770/block/md127/md/level @@ -0,0 +1 @@ +raid1 diff --git a/testdata/issue770/block/md127/md/metadata_version b/testdata/issue770/block/md127/md/metadata_version new file mode 100644 index 00000000..5625e59d --- /dev/null +++ b/testdata/issue770/block/md127/md/metadata_version @@ -0,0 +1 @@ +1.2 diff --git a/testdata/issue770/block/md127/md/raid_disks b/testdata/issue770/block/md127/md/raid_disks new file mode 100644 index 00000000..00750edc --- /dev/null +++ b/testdata/issue770/block/md127/md/raid_disks @@ -0,0 +1 @@ +3 diff --git a/testdata/issue770/block/md127/md/sync_action b/testdata/issue770/block/md127/md/sync_action new file mode 100644 index 00000000..efa2f3d7 --- /dev/null +++ b/testdata/issue770/block/md127/md/sync_action @@ -0,0 +1 @@ +resync diff --git a/testdata/issue770/block/md127/md/sync_completed b/testdata/issue770/block/md127/md/sync_completed new file mode 100644 index 00000000..5339daa0 --- /dev/null +++ b/testdata/issue770/block/md127/md/sync_completed @@ -0,0 +1 @@ +delayed diff --git a/testdata/issue770/block/md127/md/uuid b/testdata/issue770/block/md127/md/uuid new file mode 100644 index 00000000..21421dbd --- /dev/null +++ b/testdata/issue770/block/md127/md/uuid @@ -0,0 +1 @@ +7615b98d-f2ba-4d99-bee8-6202d8e130b9