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
This commit is contained in:
Chris Lu
2025-12-09 12:34:39 -08:00
committed by GitHub
parent 40eee23be9
commit 5c27522507
2 changed files with 17 additions and 0 deletions

View File

@@ -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
}

View File

@@ -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 {