From 36dd59560bdf75eaf537dba436fd62796e9c3473 Mon Sep 17 00:00:00 2001 From: Lisandro Pin Date: Mon, 1 Dec 2025 19:58:29 +0100 Subject: [PATCH] =?UTF-8?q?Have=20`volume.check.disk`=20select=20a=20rando?= =?UTF-8?q?m=20(heathly)=20source=20volume=20when=E2=80=A6=20(#7574)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Have `volume.check.disk` select a random (heathly) source volume when repairing read-only volumes. This ensures uniform load across the topology when the command is run. Also remove a lingering TODO about ignoring full volumes; not only there's no way to discern read-only volumes from being full vs. being damaged, we ultimately want to check the former anyway. --- weed/shell/command_volume_check_disk.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/weed/shell/command_volume_check_disk.go b/weed/shell/command_volume_check_disk.go index 054c0cb67..d7b015979 100644 --- a/weed/shell/command_volume_check_disk.go +++ b/weed/shell/command_volume_check_disk.go @@ -8,6 +8,7 @@ import ( "fmt" "io" "math" + "math/rand/v2" "net/http" "time" @@ -234,29 +235,30 @@ func (vcd *volumeCheckDisk) checkReadOnlyVolumes(volumeReplicas map[uint32][]*Vo vcd.write("Pass #2 (read-only volumes)\n") for vid, replicas := range volumeReplicas { - var source *VolumeReplica = nil roReplicas := []*VolumeReplica{} + rwReplicas := []*VolumeReplica{} for _, r := range replicas { if r.info.ReadOnly { roReplicas = append(roReplicas, r) } else { - // we assume all writable replicas are identical by this point, after the checkWritableVolumes() pass. - source = r + rwReplicas = append(rwReplicas, r) } } if len(roReplicas) == 0 { vcd.write("no read-only replicas for volume %d\n", vid) continue } - if source == nil { + if len(rwReplicas) == 0 { vcd.write("got %d read-only replicas for volume %d and no writable replicas to fix from\n", len(roReplicas), vid) continue } - // attempt to fix read-only replicas from the know good source + // attempt to fix read-only replicas from known good sources for _, r := range roReplicas { - // TODO: skip full readonly volumes. + // select a random writable source replica. we assume these are identical by this point, after the checkWritableVolumes() pass. + source := rwReplicas[rand.IntN(len(rwReplicas))] + skip, err := vcd.shouldSkipVolume(r, source) if err != nil { vcd.write("error checking if volume %d should be skipped: %v\n", r.info.Id, err)