spdk-rs
crate provides a higher-level bindings and wrappers around
SPDK library to enable building safer SPDK-based Rust applications.
Read about SPDK here: https://spdk.io/.
About linking SPDK applications: https://spdk.io/doc/pkgconfig.html.
OpenEBS provides a version of SPDK with a number of patches needed by OpenEBS
storage products: https://github.com/openebs/spdk.
When a new version of SPDK is released, OpenEBS maintainers port these
patches on the new branch.
For Mayastor family of products, the branches with OpenEBS patches are named
like v24.05.x-mayastor
where v24.05
is the tag name of a major SPDK release.
Please note that not every major SPDK release has a branch with OpenEBS patches.
For developing with spdk-rs
, a Rust compiler and an SPDK library must be
present on the system. This spdk-rs
repo contains a set of scripts
that allows to set up this development environment easily.
spdk-rs
leverages Nix package manager for that purpose: instead of
relying on system's package manager, all the necessary tools and libraries
are supplied by Nix.
In order to provide a stable and reproducible build environment,
spdk-rs
pins the concrete versions of all the required tools and libraries.
This is done via a set of Nix package definitions.
Currently, spdk-rs
can only be built on Linux.
In order to make use of this repo's developement scripts, a developer must have a Nix environment installed on the system. One can either install a Nix packager manager on the existing operating system, or install the Nix OS Linux distro which is built on top of the Nix packager manager.
Installing Nix as a packager manager: https://nixos.org/download/
Installing Nix as a Linux distro: https://nixos.org/download/#nixos-iso
Once a Nix environment is ready, the developer can proceed and start
spdk-rs
Ni x shell.
To start Nix shell, run this command from spdk-rs
directory:
nix-shell
Nix package manager will download and install all the necessary tool and libraries, including the Rust compiler and SPDK. Then, it will start a bash session.
When started for the first time, it would take some time to download and build the dependencies. It may take a considerable amount of time, depending on Internet connection speed and CPU power. Next time, Nix will use dependencies previously built and cached.
Nix installs different versions of the same package independently, allowing to have multiple versions of a library on the same system in different shells.
Note: Nix package manager does not install anything on any the system-wide
bin
or lib
directories, instead it creates a virtual environment for
each shell instance.
All the required libraries and binaries are installed into
Nix's own directory. Within the Nix shell, PATH
and other variables
like LD_LIBRARY_PATH
are set up accordingly.
Nix shell for spdk-rs
accepts some arguments that allow to alter
the development environment.
Nix shell arguments are passed by --argstr <value>
shell argument, e.g.:
nix-shell --argstr spdk release --argstr rust nightly
The supported parameters are the following:
spdk <config>
:develop
: use debug Nix package for SPDK (this is the default);release
: use release Nix package for SPDK;none
: do not use Nix package for SPDK; see below.
spdk-path <path>
: sets path to SPDK source directory; see below.rust <config>
stable
: use stable Rust Nix package (this is the default);nightly
: use nightly Rust Nix package;asan
: enable ASAN for Rust; nightly Nix package is forced;none
: do not use Nix package for SPDK; see below.
Once the Nix shell is started, spdk-rs
can be built the usual Rust way:
cargo build
Example SPDK-based programs from this repo can be built and run with:
cargo build --example hello_world
sudo ./target/debug/examples/hello_world
Note: Generally, SPDK-based program are likely to require root priveleges.
This repo provides a Nix package definition for SPDK library, configured
for spdk-rs
needs.
spdk-rs
is not designed to work with an arbitrary SPDK version, or arbitrary
SPDK configuration. Rather, a specific spdk-rs
version is compatible with
a specific SPDK commit and configuration. This relationship is established
by specifying SPDK commit hash in SPDK Nix package definition:
nix/pkgs/libspdk/default.nix
. When Nix shell is started, it fetches
the version specified in that file (github commit hash).
Nix package definition for SPDK configures and compiles SPDK with options
compatible with spdk-rs
.
One can select either a debug SPDK package (no optimizations,
assertions enabled), or a release package by starting Nix shell with
the spdk
argument:
nix-shell --argstr spdk debug
or
nix-shell --argstr spdk release
By default, Nix shell starts with debug SPDK.
Note: Installing SPDK via system's package managers like apt
is
not supported. It may, or may not work.
To add new features to, or fix bugs in SPDK itself, SPDK has to be built
from source code. To do that, one has to start the Nix shell without
SPDK packages, pull and checkout the correct SPDK version, and build it
manually. spdk-rs
provides helper shell scripts to simplify SPDK compilation.
SPDK must be built with the environment compatible with spdk-rs
, and
with a compatible configuration. To set up the compatible environment,
configure and compile SPDK from within the spdk-rs
Nix shell.
To get the SPDK source code, determine the branch and/or commit you need, and run the following commands:
git clone [email protected]:openebs/spdk.git
cd spdk
git checkout -t origin/v24.01.x-mayastor
git submodule update --recursive --init
spdk-rs
relies on SPDK_ROOT_DIR
environment variable to point to
SPDK installation or source code directory.
To begin with custom SPDK compilation, start the shell with SPDK packages disabled, and SPDK source path specified:
nix-shell --argstr spdk none --argstr spdk-path ~/myspdk
--argstr spdk-path <path>
will set SPDK_ROOT_DIR
to point to the given
path. (Please note tha the path is resolved to the real path before assigning
the shell var).
Note: If --argstr spdk-path <path>
is given, --argstr spdk none
is
implied:
nix-shell --argstr spdk-path ~/myspdk
Note: However, if --argstr spdk none
is given, and
--argstr spdk-path <path>
is not given, the developer must
set SPDK_ROOT_DIR
manually.
spdk-rs
provides a helper script to simplify configuring and compiling SPDK,
./build_scripts/build_spdk.sh
. The script supports verbose (-v
) and
dry run (-n
) modes. See script's help (--help
) for more options.
To configure SPDK, run:
./build_scripts/build_spdk.sh configure
To compile SPDK, run:
./build_scripts/build_spdk.sh make
To check and fix SPDK source code formatting according to SPDK rules, run:
./build_scripts/build_spdk.sh fmt
To clean the SPDK directory with git clean, run:
./build_scripts/build_spdk.sh clean
When Nix shell is started with Nix SPDK packages disabled, Rust build script
for spdk-rs
will tell Cargo to recompile Rust code every time
build_spdk.sh make
is invoked.
(./build_spdk.sh make
writes to build_logs
directory.
Rust build script detects modifications of build_logs
directory, and
rebuilds Rust sources.)
Instead of relying on build_spdk.sh
script, one can configure and make
SPDK manually:
cd <spdk_path>
AS=nasm ./configure --enable-debug --target-arch=nehalem --without-shared \
--without-crypto \
--without-nvme-cuse --without-fuse \
--with-uring --without-uring-zns \
--disable-unit-tests --disable-tests \
--with-fio=$(realpath $(dirname $(which fio))/..)
make -j
Note: Currently, spdk-rs
can only link to SPDK built as static libraries.
spdk-rs
must be cleaned manually in order to rebuild Rust code after
making SPDK.
cd <spdk_dir>
./scripts/check_format.sh
To clean up the SPDK directory and reset to the initial state:
mkdir ${your_spdk_dir}
make clean
git clean -fdx ./
git submodule foreach --recursive git clean -xfd
git submodule update
Currently, SPDK's standard make install
script does not make an installation
sutiable to be used with spdk-rs
. That is, trying to configure (via DESTDIR
)
and install SPDK in other directory using Makefile
is not supported.
To install, run:
./build_scripts/build_spdk.sh install <path>
To provide a reproducible build environment, Rust compiler is suppiled by Nix. By default, a compatible, verified stable Rust is used when Nix shell starts. One can choose a nightly Rust (although, it is a compatible, verified nightly):
nix-shell --argstr rust nightly
To use Rust provided by the system, e.g. by brough up rustup
, run:
nix-shell --argstr rust none
One can compile and run Rust code with LLVM Address Sanitizer (ASAN) enabled:
nix-shell --argstr rust asan
cargo build
Note: ASAN forces nightly Rust, and changes output directory.
TODO
Different versions of SPDK require different configuration option.
./configure --enable-debug --target-arch=nehalem --without-shared \
--without-isal --with-crypto --with-uring --disable-unit-tests \
--disable-tests --with-fio=$(which fio | sed s';bin/fio;include;')
make
- ISAL is now mandatory
- When upgrading from previous versions, clean the SPDK directory before building (e.g. git clean).
- An
AS
shell var must be set, eitheryasm
ornasm
. - Zone support for uring must be disabled.
- Crypto must be disabled.
AS=yasm ./configure --enable-debug --target-arch=nehalem --without-shared \
--without-crypto \
--with-uring --without-uring-zns \
--disable-unit-tests --disable-tests \
--with-fio=$(realpath $(dirname $(which fio))/..)
make
Same as 22.09+ but with the following additionally:
AS
must benasm
now.- FUSE must be disabled.
AS=nasm ./configure --enable-debug --target-arch=nehalem --without-shared \
--without-crypto \
--without-nvme-cuse --without-fuse \
--with-uring --without-uring-zns \
--disable-unit-tests --disable-tests \
--with-fio=$(realpath $(dirname $(which fio))/..)
make