rdma-engine: ranged RDMA READ (offset+size) in rdma-client

Match the real read API shape (file_id + offset + size): rdma-client
takes optional [offset] [size] and RDMA-READs only that sub-range from
the remote MR (remote_addr + offset). Verified over rxe0: reading
[3 MiB, 4 MiB) of an 8 MiB target file yields bytes whose md5 matches
the source slice.
This commit is contained in:
Chris Lu
2026-06-14 18:52:54 -07:00
parent 49c8d123b5
commit 81daa87f8b
@@ -3,7 +3,10 @@
//! space), and write it out. md5 of the output vs the target's source file
//! proves a real cross-process RDMA read of real data.
//!
//! cargo run --features real-rdma --bin rdma-client -- <target_ip> <port> <out_file>
//! cargo run --features real-rdma --bin rdma-client -- <target_ip> <port> <out_file> [offset] [size]
//!
//! With [offset]/[size] it RDMA-READs only that byte range (the real read API
//! shape: file_id + offset + size); without them it reads the whole MR.
use std::fs;
@@ -12,12 +15,13 @@ use rdma_engine::rdma_real::RealRdmaContext;
fn main() {
let args: Vec<String> = std::env::args().collect();
if args.len() < 4 {
eprintln!("usage: rdma-client <target_ip> <port> <out_file>");
eprintln!("usage: rdma-client <target_ip> <port> <out_file> [offset] [size]");
std::process::exit(2);
}
let ip = args[1].clone();
let port: u16 = args[2].parse().expect("port");
let out = &args[3];
let offset: u64 = args.get(4).and_then(|s| s.parse().ok()).unwrap_or(0);
let (ctx, raddr, rkey, rlen) = match RealRdmaContext::connect(&ip, port) {
Ok(v) => v,
@@ -26,11 +30,22 @@ fn main() {
std::process::exit(1);
}
};
eprintln!("client: connected to {ip}:{port}, remote MR len={rlen} rkey=0x{rkey:x}");
// Default to the rest of the MR from `offset`.
let size: usize = args
.get(5)
.and_then(|s| s.parse().ok())
.unwrap_or(rlen - offset.min(rlen as u64) as usize);
eprintln!(
"client: connected to {ip}:{port}, remote MR len={rlen} rkey=0x{rkey:x}; reading [{offset}, {})",
offset as usize + size
);
assert!(offset as usize + size <= rlen, "range exceeds remote MR");
let mut dest = vec![0u8; rlen];
let mut dest = vec![0u8; size];
let (_mi, mr) = ctx.register_memory(&mut dest).expect("register dest");
ctx.post_read(&mut dest, mr, raddr, rkey, 1).expect("post_read");
// RDMA-READ the sub-range: remote source is the MR base + offset.
ctx.post_read(&mut dest, mr, raddr + offset, rkey, 1)
.expect("post_read");
let wc = ctx.poll_completion().expect("poll completion");
ctx.finish();
eprintln!(