2023-12-13 02:19:04 +00:00
|
|
|
{ lib, pkgs, config, ... }:
|
|
|
|
let
|
|
|
|
inherit (builtins) toJSON;
|
2023-12-16 15:59:33 +00:00
|
|
|
inherit (lib) optional optionalAttrs mapAttrsToList mkIf withFeature;
|
2023-12-13 02:19:04 +00:00
|
|
|
inherit (lib.my) mkOpt' mkBoolOpt';
|
|
|
|
|
|
|
|
rpcOpts = with lib.types; {
|
|
|
|
options = {
|
|
|
|
method = mkOpt' str null "RPC method name.";
|
|
|
|
params = mkOpt' (attrsOf unspecified) { } "RPC params";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
cfg = config.my.spdk;
|
|
|
|
config' = {
|
|
|
|
subsystems = mapAttrsToList (subsystem: c: {
|
|
|
|
inherit subsystem;
|
|
|
|
config = map (rpc: {
|
|
|
|
inherit (rpc) method;
|
2023-12-16 15:59:33 +00:00
|
|
|
} // (optionalAttrs (rpc.params != { }) { inherit (rpc) params; })) c;
|
2023-12-13 02:19:04 +00:00
|
|
|
}) cfg.config.subsystems;
|
|
|
|
};
|
|
|
|
configJSON = pkgs.writeText "spdk-config.json" (toJSON config');
|
|
|
|
|
|
|
|
spdk = pkgs.spdk.overrideAttrs (o: {
|
|
|
|
configureFlags = o.configureFlags ++ (map (withFeature true) [ "rdma" "ublk" ]);
|
|
|
|
buildInputs = o.buildInputs ++ (with pkgs; [ liburing ]);
|
|
|
|
});
|
|
|
|
spdk-rpc = (pkgs.writeShellScriptBin "spdk-rpc" ''
|
|
|
|
exec ${pkgs.python3}/bin/python3 ${spdk.src}/scripts/rpc.py "$@"
|
|
|
|
'');
|
|
|
|
spdk-setup = (pkgs.writeShellScriptBin "spdk-setup" ''
|
|
|
|
exec ${spdk.src}/scripts/setup.sh "$@"
|
|
|
|
'');
|
|
|
|
spdk-debug = pkgs.writeShellApplication {
|
|
|
|
name = "spdk-debug";
|
|
|
|
runtimeInputs = [ spdk ];
|
|
|
|
text = ''
|
|
|
|
set -m
|
|
|
|
if [ "$(id -u)" -ne 0 ]; then
|
|
|
|
echo "I need to be root!"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
spdk_tgt ${cfg.extraArgs} --wait-for-rpc &
|
|
|
|
until spdk-rpc spdk_get_version > /dev/null; do
|
|
|
|
sleep 0.5
|
|
|
|
done
|
|
|
|
|
|
|
|
spdk-rpc bdev_set_options --disable-auto-examine
|
|
|
|
spdk-rpc framework_start_init
|
|
|
|
|
|
|
|
${cfg.debugCommands}
|
|
|
|
|
|
|
|
fg %1
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
in
|
|
|
|
{
|
|
|
|
options.my.spdk = with lib.types; {
|
|
|
|
enable = mkBoolOpt' false "Whether to enable SPDK target.";
|
|
|
|
extraArgs = mkOpt' str "" "Extra arguments to pass to spdk_tgt.";
|
|
|
|
debugCommands = mkOpt' lines "" "Commands to run with the spdk-debug script.";
|
|
|
|
config.subsystems = mkOpt' (attrsOf (listOf (submodule rpcOpts))) { } "Subsystem config / RPCs.";
|
|
|
|
};
|
|
|
|
|
|
|
|
config = mkIf cfg.enable {
|
|
|
|
boot.kernelModules = [ "ublk_drv" ];
|
|
|
|
|
|
|
|
environment.systemPackages = [
|
|
|
|
spdk
|
|
|
|
spdk-setup
|
|
|
|
spdk-rpc
|
|
|
|
] ++ (optional (cfg.debugCommands != "") spdk-debug);
|
|
|
|
|
|
|
|
systemd.services = {
|
|
|
|
spdk-tgt = {
|
|
|
|
description = "SPDK target";
|
|
|
|
path = with pkgs; [
|
|
|
|
bash
|
|
|
|
python3
|
|
|
|
kmod
|
|
|
|
gawk
|
|
|
|
util-linux
|
|
|
|
];
|
|
|
|
serviceConfig = {
|
|
|
|
ExecStartPre = "${spdk.src}/scripts/setup.sh";
|
|
|
|
ExecStart = "${spdk}/bin/spdk_tgt ${cfg.extraArgs} -c ${configJSON}";
|
|
|
|
};
|
|
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|