This patch adds a few examples in rust/examples/. The examples are compiled and run as part of the test suite. --- rust/Cargo.toml | 2 ++ rust/Makefile.am | 3 +++ rust/examples/connect-command.rs | 39 +++++++++++++++++++++++++++++ rust/examples/fetch-first-sector.rs | 38 ++++++++++++++++++++++++++++ rust/examples/get-size.rs | 29 +++++++++++++++++++++ rust/run-tests.sh.in | 7 ++++++ scripts/git.orderfile | 1 + 7 files changed, 119 insertions(+) create mode 100644 rust/examples/connect-command.rs create mode 100644 rust/examples/fetch-first-sector.rs create mode 100644 rust/examples/get-size.rs
diff --git a/rust/Cargo.toml b/rust/Cargo.toml index b498930..04e371e 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -49,5 +49,7 @@ libc = "0.2.147" default = ["log"] [dev-dependencies] +anyhow = "1.0.72" once_cell = "1.18.0" +pretty-hex = "0.3.0" tempfile = "3.6.0" diff --git a/rust/Makefile.am b/rust/Makefile.am index f9830d0..bdfe2ca 100644 --- a/rust/Makefile.am +++ b/rust/Makefile.am @@ -30,6 +30,9 @@ source_files = \ src/handle.rs \ src/types.rs \ src/utils.rs \ + examples/connect-command.rs \ + examples/get-size.rs \ + examples/fetch-first-sector.rs \ libnbd-sys/Cargo.toml \ libnbd-sys/build.rs \ libnbd-sys/src/.keep \ diff --git a/rust/examples/connect-command.rs b/rust/examples/connect-command.rs new file mode 100644 index 0000000..db4adbe --- /dev/null +++ b/rust/examples/connect-command.rs @@ -0,0 +1,39 @@ +//! This example shows how to run an NBD server +//! (nbdkit) as a subprocess of libnbd. + + +fn main() -> libnbd::Result<()> { + // Create the libnbd handle. + let handle = libnbd::Handle::new()?; + + // Run nbdkit as a subprocess. + let args = [ + "nbdkit", + // You must use ‘-s’ (which tells nbdkit to serve + // a single connection on stdin/stdout). + "-s", + // It is recommended to use ‘--exit-with-parent’ + // to ensure nbdkit is always cleaned up even + // if the main program crashes. + "--exit-with-parent", + // Use this to enable nbdkit debugging. + "-v", + // The nbdkit plugin name - this is a RAM disk. + "memory", + "size=1M", + ]; + handle.connect_command(&args)?; + + // Write some random data to the first sector. + let wbuf: Vec<u8> = (0..512).into_iter().map(|i| (i % 13) as u8).collect(); + handle.pwrite(&wbuf, 0, None)?; + + // Read the first sector back. + let mut rbuf = [0; 512]; + handle.pread(&mut rbuf, 0, None)?; + + // What was read must be exactly the same as what was written. + assert_eq!(wbuf.as_slice(), rbuf.as_slice()); + + Ok(()) +} diff --git a/rust/examples/fetch-first-sector.rs b/rust/examples/fetch-first-sector.rs new file mode 100644 index 0000000..9efb47a --- /dev/null +++ b/rust/examples/fetch-first-sector.rs @@ -0,0 +1,38 @@ +//! This example shows how to connect to an NBD server +//! and fetch and print the first sector (usually the +//! boot sector or partition table or filesystem +//! superblock). +//! +//! You can test it with nbdkit like this: +//! +//! nbdkit -U - floppy . \ +//! --run 'cargo run --example fetch-first-sector -- $unixsocket' +//! +//! The nbdkit floppy plugin creates an MBR disk so the +//! first sector is the partition table. + +use pretty_hex::pretty_hex; +use std::env; + +fn main() -> anyhow::Result<()> { + let nbd = libnbd::Handle::new()?; + + let args = env::args_os().collect::<Vec<_>>(); + if args.len() != 2 { + anyhow::bail!("Usage: {:?} socket", args[0]); + } + let socket = &args[1]; + + // Connect to the NBD server over a + // Unix domain socket. + nbd.connect_unix(socket)?; + + // Read the first sector synchronously. + let mut buf = [0; 512]; + nbd.pread(&mut buf, 0, None)?; + + // Print the sector in hexdump like format. + print!("{}", pretty_hex(&buf)); + + Ok(()) +} diff --git a/rust/examples/get-size.rs b/rust/examples/get-size.rs new file mode 100644 index 0000000..7f31df5 --- /dev/null +++ b/rust/examples/get-size.rs @@ -0,0 +1,29 @@ +//! This example shows how to connect to an NBD +//! server and read the size of the disk. +//! +//! You can test it with nbdkit like this: +//! +//! nbdkit -U - memory 1M \ +//! --run 'cargo run --example get-size -- $unixsocket' + +use std::env; + +fn main() -> anyhow::Result<()> { + let nbd = libnbd::Handle::new()?; + + let args = env::args_os().collect::<Vec<_>>(); + if args.len() != 2 { + anyhow::bail!("Usage: {:?} socket", args[0]); + } + let socket = &args[1]; + + // Connect to the NBD server over a + // Unix domain socket. + nbd.connect_unix(socket)?; + + // Read the size in bytes and print it. + let size = nbd.get_size()?; + println!("{:?}: size = {size} bytes", socket); + + Ok(()) +} diff --git a/rust/run-tests.sh.in b/rust/run-tests.sh.in index f7db344..138a1fa 100755 --- a/rust/run-tests.sh.in +++ b/rust/run-tests.sh.in @@ -22,9 +22,16 @@ set -e set -x requires nbdkit --version +requires nbdkit floppy --version +requires nbdkit memory --version if [ -z "$VG" ]; then @CARGO@ test -- --nocapture + @CARGO@ run --example connect-command + nbdkit -U - memory 1M \ + --run '@CARGO@ run --example get-size -- $unixsocket' + nbdkit -U - floppy . \ + --run '@CARGO@ run --example fetch-first-sector -- $unixsocket' else @CARGO@ test --config "target.'cfg(all())'.runner = \"$VG\"" -- --nocapture fi diff --git a/scripts/git.orderfile b/scripts/git.orderfile index 9dd3d54..b988d87 100644 --- a/scripts/git.orderfile +++ b/scripts/git.orderfile @@ -70,6 +70,7 @@ rust/src/utils.rs rust/src/lib.rs rust/src/handle.rs rust/libnbd-sys/* +rust/examples/* rust/tests/* # Tests. -- 2.41.0 _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://listman.redhat.com/mailman/listinfo/libguestfs