diff --git a/seaweed-volume/src/server/grpc_server.rs b/seaweed-volume/src/server/grpc_server.rs index b3582d809..660944974 100644 --- a/seaweed-volume/src/server/grpc_server.rs +++ b/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| { diff --git a/seaweed-volume/src/storage/volume.rs b/seaweed-volume/src/storage/volume.rs index b06a1d6ce..579094584 100644 --- a/seaweed-volume/src/storage/volume.rs +++ b/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