[Libguestfs] [libnbd PATCH v5 04/12] rust: Add some examples

Tage Johansson tage.j.lists at posteo.net
Thu Aug 3 15:36:08 UTC 2023


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



More information about the Libguestfs mailing list