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 bb2e6f0..295254d 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/lib.rs \
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