aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lu <chrislusf@users.noreply.github.com>2025-12-09 12:34:39 -0800
committerGitHub <noreply@github.com>2025-12-09 12:34:39 -0800
commit5c2752250745fb4c2a7a288dee8c04b8b02ecdb1 (patch)
tree0441d8e8b43c9f1c1ab8ee46429d455b5baa0a36
parent40eee23be9b9e45efdbd07dcae45b4c540e7031d (diff)
downloadseaweedfs-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
-rw-r--r--weed/server/volume_grpc_copy.go9
-rw-r--r--weed/storage/volume_info/volume_info.go8
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 {