Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
ironspdk
Rust runtime for SPDK. Write high-performance userspace storage drivers in Rust.
Overview
SPDK provides a high-performance userspace storage framework based on polling and asynchronous I/O. Its native API is written in C and uses callbacks and explicit resource management.
ironspdk provides a Rust interface to this execution model. It uses Rust's
type system and ownership rules to manage resources such as I/O requests,
DMA buffers, and I/O channels, while allowing storage operations to be
implemented using Rust futures.
The runtime is designed to keep the execution model of SPDK rather than
introducing a general-purpose async runtime on top of it.
SPDK's reactor-based execution model is integrated with Rust's asynchronous model.
Rust futures are executed on SPDK threads, and SPDK I/O operations can be composed using
async/await.
The project is intended for applications where SPDK's userspace storage architecture is appropriate and where Rust's memory safety and language features are useful for implementing storage logic.
Key Features
🦀 Idiomatic Rust Programming Model
- No callback hell: Use Rust's async/await syntax and futures for natural asynchronous I/O handling.
- Memory safety: Leverage Rust's ownership and borrowing system to prevent data races and memory bugs.
- Type safety: Compile-time guarantees replace runtime errors.
⚡ SPDK Integration
- Full SPDK primitives support: SPDK lightweight threads, I/O channels, block device descriptors, and more are exposed to Rust.
- Tight runtime integration: The
ironspdkruntime executor extends the SPDK poller, allowing Rust code to seamlessly integrate with the SPDK event loop. - Zero-copy I/O: Work directly with SPDK I/O vectors and DMA buffers. without unnecessary data copies.
- SPDK thread model: Build on SPDK's thread-per-core, message-passing execution model rather than introducing a conventional shared-state threading model.
- C <-> Rust interoperability: Use SPDK's C API directly from Rust when the higher-level abstractions are not sufficient.
🚀 Performance
- Native code: Rust code is compiled to native machine code with the same optimization opportunities as other systems languages.
- Low-overhead abstractions: Keep the abstractions close to the underlying SPDK primitives.
- Lock-free architecture: Take advantage of SPDK's thread-per-core model to avoid unnecessary shared-state synchronization.
- Direct FFI binding: Minimal abstraction over underlying SPDK C APIs.
🔀 I/O Abstractions
- Multiple I/O representations: Support for borrowed I/O references (
IoRef), owned I/O buffers (IoBuf), and unifiedIoenum. - I/O splitting: Advanced API for splitting and reordering I/O operations.
- DMA buffers: Allocate and manage SPDK-compatible DMA memory through Rust-owned buffers.
- Block device abstraction: Simple trait-based interface for implementing custom block devices.
Architecture
Core Components
ironspdk-sys/ # Low-level C FFI bindings to SPDK
ironspdk/ # High-level Rust runtime and abstractions
├── app.rs # SpdkApp lifecycle management
├── lib.rs # Core types: Bdev, IoRef, IoBuf, SpdkThread, Tcb
├── c.rs # C FFI wrappers
├── c_enum.rs # Enum conversions
└── rpc.rs # RPC command registration
examples/raid1/ # Simple RAID1 implementation example
examples/raid5/ # Minimal reference RAID5 implementation example
Runtime Executor
The ironspdk runtime leverages SPDK's poller mechanism:
- Run queue: Manages async task execution on each SPDK thread
- Poller: Queues and polls futures
- TLS: Lightweight per SPDK thread storage (to store contexts, for ex. I/O channels)
- Waker integration: Custom waker implementation to notify tasks in runqueue
Usage
Basic Setup
Add to your Cargo.toml:
[]
= "1.2.56"
= "0.2"
[]
= "0.2"
= "0.2"
Create a Simple Block Device
Simplified code of ironspdk block device:
use ;
See examples/ for exact implementations.
Build & Run
# Set up environment
# Or use local SPDK git submodule dependency
# Build
# Run with specific CPU cores (0xf = cores 0-3)
Examples
RAID1 Block Device
The repository includes a simple yet functional RAID1 implementation (examples/raid1/). This example demonstrates:
- Mirroring I/O across several backend block devices
- Handling read/write operations
- RPC-based management interface
Compare with SPDK's C implementation raid1.c: The Rust version is significantly more concise and readable, while maintaining almost identical performance.
RAID5 Block Device
A simple RAID5 implementation (examples/raid5/). This example demonstrates:
- Data striping with distributed XOR parity
- Full-stripe writes and partial-stripe writes using read-modify-write (RMW)
- Recovery of a single failed read using parity reconstruction
- Per-stripe request serialization to prevent concurrent RMW operations from corrupting parity
- RPC-based management interface
This is a reference implementation intended to demonstrate RAID5 concepts, not a production-ready solution. It does not provide crash consistency or persistent failure tracking.
Running the RAID1 Example
# Terminal 1: Start the RAID1 driver
SPDK=/path/to/built/spdk/
# run RAID1 usermode driver example at 4 CPU cores
# Terminal 2: Create backend devices
SPDK=/path/to/built/spdk/
# Create RAID1 instance
# Export via ublk and benchmark with fio
# Run I/O benchmark
TIME=30
# Cleanup
Running the RAID5 Example
This is similar to RAID1. The block device creation command is:
sudo PYTHONPATH=/path/to/ironspdk/examples/raid5/ ./scripts/rpc.py \
--plugin raid5 \
rs_raid5_create --name my_ironspdk_raid5 -z 16 -c malloc0,malloc1,malloc2
API Overview
Core Types
SpdkApp
Main application entry point. Manages SPDK initialization, thread creation, and lifecycle.
let mut app = new;
app.on_start;
app.on_shutdown;
app.run?;
SpdkThread
Wrapper around SPDK threads. Enables spawning async tasks and inter-thread communication.
// create new SPDK thread at core 2
let thread = new_at_cores;
// run some code at this SPDK thread asynchronously
thread.spawn;
// stop SPDK threads this way only
thread.request_exit;
Bdev (Trait)
Implement this trait to create custom block devices.
BdevIo
Represents a single I/O request. Provides access to request metadata and completion mechanism.
Io<'a> (Enum)
Unified interface for working with I/O data. Can be either a reference to SPDK I/O vectors or a buffered copy.
DmaBuf
DMA-allocated memory buffer. It may be shared between threads, so it implements Send+Sync.
Lbdev
Client API for accessing lower-layer SPDK block devices.
Error Handling
All fallible operations return Result<T, Error>. The Error enum covers common SPDK scenarios:
Requirements
- Rust: 1.70+
- SPDK: Built and configured (see SPDK documentation), version v26.01 is supported
- Linux: confirmed support at 6.17+ kernels
- Privileges: Most operations require superuser access for hardware access and memory management
Performance Characteristics
- Latency: Microsecond-scale I/O latency (same as C SPDK)
- Throughput: Limited only by underlying hardware (Rust overhead is minimal)
- CPU efficiency: Lock-free design with thread-per-core scaling
- Memory: Minimal overhead compared to C implementation
Licensing
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- BSD 3-Clause License (LICENSE-BSD-3-Clause)
at your option.
Contributing
Contributions are welcome! Please:
- Ensure all tests pass:
cargo test - Format code:
cargo fmt -- - Run clippy:
cargo clippy --locked --all --all-targets --tests -- -D warnings - Document public APIs
- Add tests for new functionality
Getting Help
- SPDK Documentation: https://spdk.io/doc/
- Rust async/await: https://rust-lang.github.io/async-book/
- Repository Issues: Open an issue on GitHub for bugs or feature requests
Roadmap
- More public API documentation
- Documentation at docs.rs
- RAID5 example
- Test coverage (cargo test)
- Additional block device examples
- T10 PI (DIF/DIX) support
- SPDK bdev resizing support
- Performance profiling tools
- Higher-level storage abstractions
- FreeBSD support
Related or Similar Projects
- SPDK - Storage Performance Development Kit
- Tokio - Async Rust runtime
- Rust for Linux - Bringing Rust to kernel space