Browse Source

fix: EC shard copy address parsing and preserve .vif on volume destroy

Two bugs found during EC encoding + balancing test with 4 Rust volume servers:

1. VolumeEcShardsCopy manually split source_data_node on '.' which broke
   on IP addresses with dots. Now uses parse_grpc_address() like other RPCs.

2. remove_volume_files() deleted .vif files, breaking EC volumes that
   need the .vif after the original volume is destroyed. Matches Go's
   Destroy() which only removes .dat/.idx.
rust-volume-server
Chris Lu 15 hours ago
parent
commit
24895a3962
  1. 22
      seaweed-volume/src/server/grpc_server.rs
  2. 5
      seaweed-volume/src/storage/volume.rs

22
seaweed-volume/src/server/grpc_server.rs

@ -1814,22 +1814,12 @@ impl VolumeServer for VolumeGrpcService {
// Connect to source and copy shard files via CopyFile
let source = &req.source_data_node;
// Parse source address: "ip:port.grpc_port"
let parts: Vec<&str> = source.split('.').collect();
if parts.len() != 2 {
return Err(Status::internal(format!(
"VolumeEcShardsCopy volume {} invalid source_data_node {}",
vid, source
)));
}
let grpc_addr = format!(
"{}:{}",
parts[0]
.rsplit_once(':')
.map(|(h, _)| h)
.unwrap_or(parts[0]),
parts[1]
);
let grpc_addr = parse_grpc_address(source).map_err(|e| {
Status::internal(format!(
"VolumeEcShardsCopy volume {} invalid source_data_node {}: {}",
vid, source, e
))
})?;
let channel = tonic::transport::Channel::from_shared(format!("http://{}", grpc_addr))
.map_err(|e| {

5
seaweed-volume/src/storage/volume.rs

@ -2167,7 +2167,10 @@ fn get_append_at_ns(last: u64) -> u64 {
/// Remove all files associated with a volume.
pub(crate) fn remove_volume_files(base: &str) {
for ext in &[".dat", ".idx", ".vif", ".sdx", ".cpd", ".cpx", ".note", ".rdb"] {
// Note: .vif is intentionally NOT deleted here — it must be preserved
// for EC volumes that reference it after the original volume is destroyed.
// Matches Go's volume.Destroy() which only removes .dat/.idx.
for ext in &[".dat", ".idx", ".sdx", ".cpd", ".cpx", ".note", ".rdb"] {
let _ = fs::remove_file(format!("{}{}", base, ext));
}
// leveldb uses a directory

Loading…
Cancel
Save