diff options
| author | Chris Lu <chrislusf@users.noreply.github.com> | 2025-12-09 12:34:39 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-12-09 12:34:39 -0800 |
| commit | 5c2752250745fb4c2a7a288dee8c04b8b02ecdb1 (patch) | |
| tree | 0441d8e8b43c9f1c1ab8ee46429d455b5baa0a36 /weed | |
| parent | 40eee23be9b9e45efdbd07dcae45b4c540e7031d (diff) | |
| download | seaweedfs-5c2752250745fb4c2a7a288dee8c04b8b02ecdb1.tar.xz seaweedfs-5c2752250745fb4c2a7a288dee8c04b8b02ecdb1.zip | |
fix: prevent empty .vif files from ec.decode causing parse errors (#7686)
* fix: prevent empty .vif files from ec.decode causing parse errors
When ec.decode copies .vif files from EC shard nodes, if a source node
doesn't have the .vif file, an empty .vif file was created on the target
node. This caused volume.configure.replication to fail with 'proto: syntax
error' when trying to parse the empty file.
This fix:
1. In writeToFile: Remove empty files when no data was written (source
file was not found) to avoid leaving corrupted empty files
2. In MaybeLoadVolumeInfo: Handle empty .vif files gracefully by treating
them as non-existent, allowing the system to create a proper one
Fixes #7666
* refactor: remove redundant dst.Close() and add error logging
Address review feedback:
- Remove redundant dst.Close() call since defer already handles it
- Add error logging for os.Remove() failure
Diffstat (limited to 'weed')
| -rw-r--r-- | weed/server/volume_grpc_copy.go | 9 | ||||
| -rw-r--r-- | weed/storage/volume_info/volume_info.go | 8 |
2 files changed, 17 insertions, 0 deletions
diff --git a/weed/server/volume_grpc_copy.go b/weed/server/volume_grpc_copy.go index 410c6b05d..2e20941ad 100644 --- a/weed/server/volume_grpc_copy.go +++ b/weed/server/volume_grpc_copy.go @@ -291,6 +291,15 @@ func writeToFile(client volume_server_pb.VolumeServer_CopyFileClient, fileName s } wt.MaybeSlowdown(int64(len(resp.FileContent))) } + // If no data was written (source file was not found), remove the empty file + // to avoid leaving corrupted empty files that cause parse errors later + if progressedBytes == 0 && !isAppend { + if removeErr := os.Remove(fileName); removeErr != nil { + glog.V(1).Infof("failed to remove empty file %s: %v", fileName, removeErr) + } else { + glog.V(1).Infof("removed empty file %s (source file not found)", fileName) + } + } return modifiedTsNs, nil } diff --git a/weed/storage/volume_info/volume_info.go b/weed/storage/volume_info/volume_info.go index 2ac4cc493..75cbc1472 100644 --- a/weed/storage/volume_info/volume_info.go +++ b/weed/storage/volume_info/volume_info.go @@ -42,6 +42,14 @@ func MaybeLoadVolumeInfo(fileName string) (volumeInfo *volume_server_pb.VolumeIn } + // Handle empty .vif files gracefully - treat as if file doesn't exist + // This can happen when ec.decode copies from a source that doesn't have a .vif file + if len(fileData) == 0 { + glog.Warningf("empty volume info file %s, treating as non-existent", fileName) + hasVolumeInfoFile = false + return + } + glog.V(1).Infof("maybeLoadVolumeInfo Unmarshal volume info %v", fileName) if err = jsonpb.Unmarshal(fileData, volumeInfo); err != nil { if oldVersionErr := tryOldVersionVolumeInfo(fileData, volumeInfo); oldVersionErr != nil { |
