mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-11-04 02:57:44 +01:00
feat(ec): copy the .ecsum sidecar during VolumeEcShardsCopy
Honor copy_ecsum_file: when set, copy the generation-0 .ecsum alongside the shards so protection travels with them, mirroring Go's non-2PC copy path. Tolerant of a missing source (empty stream) — the 0-byte file is dropped so mount sees no sidecar (protection off) rather than a truncated/invalid one. Claude-Session: https://claude.ai/code/session_015EE9Sc9EvNp8BCVva4RKdo
This commit is contained in:
1 parent
d810dbd03d
commit
11c277765c
1 file changed
+52
@@ -2766,6 +2766,58 @@ impl VolumeServer for VolumeGrpcService {
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the generation-0 bitrot checksum sidecar (.ecsum) when requested, so
|
||||
// protection travels with the shards. Tolerant of a missing source (no-op):
|
||||
// this non-2PC path has no Prepare backstop, and an unprotected source
|
||||
// simply leaves the copy unprotected.
|
||||
if req.copy_ecsum_file {
|
||||
let copy_req = volume_server_pb::CopyFileRequest {
|
||||
volume_id: req.volume_id,
|
||||
collection: req.collection.clone(),
|
||||
is_ec_volume: true,
|
||||
ext: ".ecsum".to_string(),
|
||||
compaction_revision: u32::MAX,
|
||||
stop_offset: i64::MAX as u64,
|
||||
ignore_source_file_not_found: true,
|
||||
..Default::default()
|
||||
};
|
||||
let mut stream = client
|
||||
.copy_file(copy_req)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
Status::internal(format!(
|
||||
"VolumeEcShardsCopy volume {} copy .ecsum: {}",
|
||||
vid, e
|
||||
))
|
||||
})?
|
||||
.into_inner();
|
||||
|
||||
let file_path = {
|
||||
let base =
|
||||
crate::storage::volume::volume_file_name(&dest_dir, &req.collection, vid);
|
||||
format!("{}.ecsum", base)
|
||||
};
|
||||
let mut file = std::fs::File::create(&file_path)
|
||||
.map_err(|e| Status::internal(format!("create {}: {}", file_path, e)))?;
|
||||
let mut written: u64 = 0;
|
||||
while let Some(chunk) = stream
|
||||
.message()
|
||||
.await
|
||||
.map_err(|e| Status::internal(format!("recv .ecsum: {}", e)))?
|
||||
{
|
||||
use std::io::Write;
|
||||
file.write_all(&chunk.file_content)
|
||||
.map_err(|e| Status::internal(format!("write {}: {}", file_path, e)))?;
|
||||
written += chunk.file_content.len() as u64;
|
||||
}
|
||||
// A missing source yields an empty stream; drop the 0-byte file so mount
|
||||
// sees no sidecar (protection Off) rather than a truncated/invalid one.
|
||||
if written == 0 {
|
||||
drop(file);
|
||||
let _ = std::fs::remove_file(&file_path);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Response::new(
|
||||
volume_server_pb::VolumeEcShardsCopyResponse {},
|
||||
))
|
||||
|
||||
Reference in new issue
Block a user