From 6a61037333117399508cecef00a2a0af07e412af Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Mon, 9 Feb 2026 13:23:17 -0800 Subject: [PATCH] fix issue #8230: volume.fsck deletion logic to respect purgeAbsent flag (#8266) * fix issue #8230: volume.fsck deletion logic to respect purgeAbsent flag This commit fixes two issues in volume.fsck: 1. Missing chunks in existing volumes are now deleted if -reallyDeleteFilerEntries is set. 2. Missing volumes are now properly handled when a -volumeId filter is specified, allowing deletion of filer entries for those volumes. * address PR feedback for issue #8230 - Ensure volume filter is applied before reporting missing volumes - Fix potential nil-pointer dereferences in httpDelete method - Use proper error checking throughout httpDelete * address second round PR feedback for issue #8230 - Use fmt.Fprintf(c.writer, ...) instead of fmt.Printf - Add missing newline in "deleting path" log message --- weed/shell/command_volume_fsck.go | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/weed/shell/command_volume_fsck.go b/weed/shell/command_volume_fsck.go index e9b2d1521..17c553141 100644 --- a/weed/shell/command_volume_fsck.go +++ b/weed/shell/command_volume_fsck.go @@ -198,7 +198,7 @@ func (c *commandVolumeFsck) Do(args []string, commandEnv *CommandEnv, writer io. } for dataNodeId, volumeIdToVInfo := range dataNodeVolumeIdToVInfo { // for each volume, check filer file ids - if err = c.findFilerChunksMissingInVolumeServers(volumeIdToVInfo, dataNodeId, *applyPurging); err != nil { + if err = c.findFilerChunksMissingInVolumeServers(volumeIdToVInfo, dataNodeId, *applyPurging || *purgeAbsent); err != nil { return fmt.Errorf("findFilerChunksMissingInVolumeServers: %w", err) } } @@ -284,10 +284,16 @@ func (c *commandVolumeFsck) collectFilerFileIdAndPaths(dataNodeVolumeIdToVInfo m if _, err := f.Write([]byte(i.path)); err != nil { return err } - } else if *c.findMissingChunksInFiler && len(c.volumeIds) == 0 { + } else if *c.findMissingChunksInFiler { + // check if the volume matches the filter + if len(c.volumeIds) > 0 { + if _, ok := c.volumeIds[i.vid]; !ok { + continue + } + } fmt.Fprintf(c.writer, "%d,%x%08x %s volume not found\n", i.vid, i.fileKey, i.cookie, i.path) if purgeAbsent { - fmt.Printf("deleting path %s after volume not found", i.path) + fmt.Fprintf(c.writer, "deleting path %s after volume not found\n", i.path) c.httpDelete(i.path) } } @@ -540,6 +546,10 @@ func (c *commandVolumeFsck) oneVolumeFileIdsCheckOneVolume(dataNodeId string, vo func (c *commandVolumeFsck) httpDelete(path util.FullPath) { req, err := http.NewRequest(http.MethodDelete, "", nil) + if err != nil { + fmt.Fprintf(c.writer, "HTTP delete request error: %v\n", err) + return + } req.URL = &url.URL{ Scheme: "http", @@ -549,13 +559,11 @@ func (c *commandVolumeFsck) httpDelete(path util.FullPath) { if *c.verbose { fmt.Fprintf(c.writer, "full HTTP delete request to be sent: %v\n", req) } - if err != nil { - fmt.Fprintf(c.writer, "HTTP delete request error: %v\n", err) - } resp, err := util_http.GetGlobalHttpClient().Do(req) if err != nil { fmt.Fprintf(c.writer, "DELETE fetch error: %v\n", err) + return } defer resp.Body.Close()