diff --git a/Cargo.lock b/Cargo.lock index ce860f7a1..990216c53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -380,6 +380,29 @@ dependencies = [ "which", ] +[[package]] +name = "bindgen" +version = "0.69.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +dependencies = [ + "bitflags 2.4.0", + "cexpr", + "clang-sys", + "itertools 0.11.0", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.38", + "which", +] + [[package]] name = "bit-vec" version = "0.6.3" @@ -924,7 +947,7 @@ dependencies = [ name = "devinfo" version = "1.0.0" dependencies = [ - "bindgen", + "bindgen 0.68.1", "nix", "semver", "snafu", @@ -1891,7 +1914,7 @@ dependencies = [ name = "libnvme-rs" version = "0.1.0" dependencies = [ - "bindgen", + "bindgen 0.68.1", "cc", "glob", "libc", @@ -2990,10 +3013,10 @@ dependencies = [ [[package]] name = "spdk-rs" -version = "0.1.0" +version = "0.2.0" dependencies = [ "async-trait", - "bindgen", + "bindgen 0.69.4", "cc", "futures", "nix", diff --git a/ci.nix b/ci.nix index b0b4bbbb6..efec76e32 100644 --- a/ci.nix +++ b/ci.nix @@ -39,6 +39,7 @@ mkShell { kubernetes-helm libaio libbsd + libexecinfo libnvme libpcap libunwind diff --git a/io-engine-tests/src/error_bdev.rs b/io-engine-tests/src/error_bdev.rs index c2d24ee4e..89a0d51c7 100644 --- a/io-engine-tests/src/error_bdev.rs +++ b/io-engine-tests/src/error_bdev.rs @@ -44,6 +44,7 @@ pub fn inject_error(error_device: &str, op: u32, mode: u32, count: u32) { error_num: count, corrupt_offset: 0, corrupt_value: 0, + error_qd: 0, }; unsafe { diff --git a/io-engine/src/bdev/null_bdev.rs b/io-engine/src/bdev/null_bdev.rs index 4e34c3e44..b1ace5b36 100644 --- a/io-engine/src/bdev/null_bdev.rs +++ b/io-engine/src/bdev/null_bdev.rs @@ -134,10 +134,12 @@ impl CreateDestroy for Null { }); } + let uuid = spdk_rs::Uuid::generate().into_raw(); + let cname = self.name.clone().into_cstring(); let opts = spdk_rs::libspdk::spdk_null_bdev_opts { name: cname.as_ptr(), - uuid: std::ptr::null(), + uuid: &uuid, num_blocks: self.num_blocks, block_size: self.blk_size, physical_block_size: 0, diff --git a/io-engine/src/bdev/nvme.rs b/io-engine/src/bdev/nvme.rs index 891e824fc..b6ec14b3e 100644 --- a/io-engine/src/bdev/nvme.rs +++ b/io-engine/src/bdev/nvme.rs @@ -10,13 +10,9 @@ use snafu::ResultExt; use url::Url; use spdk_rs::{ + bdevs::bdev_nvme_delete_async, ffihelper::copy_str_with_null, - libspdk::{ - bdev_nvme_create, - bdev_nvme_delete, - nvme_path_id, - spdk_nvme_transport_id, - }, + libspdk::{bdev_nvme_create, spdk_nvme_transport_id}, }; use crate::{ @@ -136,25 +132,20 @@ impl CreateDestroy for NVMe { if let Some(mut bdev) = UntypedBdev::lookup_by_name(&self.get_name()) { bdev.remove_alias(self.url.as_ref()); - let mut path_id = nvme_path_id::default(); - copy_str_with_null(&self.name, &mut path_id.trid.traddr); - path_id.trid.trtype = spdk_rs::libspdk::SPDK_NVME_TRANSPORT_PCIE; + let res = bdev_nvme_delete_async(&self.name, None).await; - let errno = unsafe { - bdev_nvme_delete( - self.name.clone().into_cstring().as_ptr(), - &path_id, - ) - }; - if errno != 0 { + // Restore the alias in the case the deletion failed. + if !res.is_ok_and(|e| e.is_ok()) { UntypedBdev::lookup_by_name(&self.get_name()) .map(|mut b| b.add_alias(self.url.as_ref())); } - errno_result_from_i32((), errno).context( - bdev_api::DestroyBdevFailed { - name: self.name.clone(), - }, - ) + + res.context(bdev_api::BdevCommandCanceled { + name: self.name.clone(), + })? + .context(bdev_api::DestroyBdevFailed { + name: self.name.clone(), + }) } else { Err(BdevError::BdevNotFound { name: self.get_name(), diff --git a/io-engine/src/bdev/nvmf.rs b/io-engine/src/bdev/nvmf.rs index 4aacc02c4..7da651c61 100644 --- a/io-engine/src/bdev/nvmf.rs +++ b/io-engine/src/bdev/nvmf.rs @@ -11,10 +11,10 @@ use snafu::ResultExt; use url::Url; use spdk_rs::{ + bdevs::bdev_nvme_delete_async, ffihelper::copy_str_with_null, libspdk::{ bdev_nvme_create, - bdev_nvme_delete, spdk_nvme_transport_id, SPDK_NVME_IO_FLAGS_PRCHK_GUARD, SPDK_NVME_IO_FLAGS_PRCHK_REFTAG, @@ -195,31 +195,46 @@ impl CreateDestroy for Nvmf { name: self.name.clone(), })?; + // Remove partially created nvme bdev which doesn't show up in + // the list of bdevs if bdev_count == 0 { - error!("No nvme bdev created, no namespaces?"); - // Remove partially created nvme bdev which doesn't show up in - // the list of bdevs - let errno = - unsafe { bdev_nvme_delete(cname.as_ptr(), std::ptr::null()) }; - info!( - "removed partially created bdev {}, returned {}", - self.name, errno + error!( + "No nvme bdev created after creating {n}, no namespaces?", + n = self.name ); + + match bdev_nvme_delete_async(&self.name, None).await { + Ok(_) => { + info!("Removed partially created bdev {n}", n = self.name) + } + Err(e) => { + error!( + "Failed to remove partially created bdev {n}: {e:?}", + n = self.name + ) + } + } + return Err(BdevError::BdevNotFound { name: self.name.clone(), }); } + if let Some(mut bdev) = UntypedBdev::lookup_by_name(&self.get_name()) { if let Some(u) = self.uuid { if bdev.uuid_as_string() != u.hyphenated().to_string() { - error!("Connected to device {} but expect to connect to {} instead", bdev.uuid_as_string(), u.hyphenated().to_string()); + error!( + "Connected to device {dev} but expect to connect to {s} instead", + dev = bdev.uuid_as_string(), + s = u.hyphenated().to_string(), + ); } }; if !bdev.add_alias(&self.alias) { error!( - "Failed to add alias {} to device {}", - self.alias, - self.get_name() + "Failed to add alias {alias} to device {name}", + alias = self.alias, + name = self.get_name() ); } }; @@ -235,20 +250,15 @@ impl CreateDestroy for Nvmf { match UntypedBdev::lookup_by_name(&self.get_name()) { Some(mut bdev) => { bdev.remove_alias(&self.alias); - let cname = CString::new(self.name.clone()).unwrap(); - - let errno = unsafe { - bdev_nvme_delete(cname.as_ptr(), std::ptr::null()) - }; - async { - errno_result_from_i32((), errno).context( - bdev_api::DestroyBdevFailed { - name: self.name.clone(), - }, - ) - } - .await + bdev_nvme_delete_async(&self.name, None) + .await + .context(bdev_api::BdevCommandCanceled { + name: self.name.clone(), + })? + .context(bdev_api::DestroyBdevFailed { + name: self.name.clone(), + }) } None => Err(BdevError::BdevNotFound { name: self.get_name(), diff --git a/io-engine/src/bdev/nvmx/controller.rs b/io-engine/src/bdev/nvmx/controller.rs index 1751a91f6..4878f3b17 100644 --- a/io-engine/src/bdev/nvmx/controller.rs +++ b/io-engine/src/bdev/nvmx/controller.rs @@ -4,6 +4,7 @@ use std::{ convert::From, fmt, + mem::zeroed, os::raw::c_void, ptr::NonNull, sync::{Arc, Mutex}, @@ -777,7 +778,7 @@ impl<'a> Drop for NvmeController<'a> { } extern "C" fn aer_cb(ctx: *mut c_void, cpl: *const spdk_nvme_cpl) { - let mut event = spdk_nvme_async_event_completion::default(); + let mut event: spdk_nvme_async_event_completion = unsafe { zeroed() }; if !nvme_cpl_succeeded(cpl) { warn!("AER request execute failed"); @@ -1017,7 +1018,7 @@ pub(crate) fn connected_attached_cb( pub(crate) mod options { use spdk_rs::ffihelper::copy_str_with_null; - use std::mem::size_of; + use std::mem::{size_of, zeroed}; use spdk_rs::libspdk::{ spdk_nvme_ctrlr_get_default_ctrlr_opts, @@ -1037,7 +1038,7 @@ pub(crate) mod options { impl Default for NvmeControllerOpts { fn default() -> Self { - let mut default = spdk_nvme_ctrlr_opts::default(); + let mut default: spdk_nvme_ctrlr_opts = unsafe { zeroed() }; unsafe { spdk_nvme_ctrlr_get_default_ctrlr_opts( diff --git a/io-engine/src/bdev/nvmx/handle.rs b/io-engine/src/bdev/nvmx/handle.rs index c138bf505..73a618dde 100644 --- a/io-engine/src/bdev/nvmx/handle.rs +++ b/io-engine/src/bdev/nvmx/handle.rs @@ -1,4 +1,9 @@ -use std::{alloc::Layout, mem::ManuallyDrop, os::raw::c_void, sync::Arc}; +use std::{ + alloc::Layout, + mem::{zeroed, ManuallyDrop}, + os::raw::c_void, + sync::Arc, +}; use async_trait::async_trait; use futures::channel::oneshot; @@ -1118,12 +1123,12 @@ impl BlockDeviceHandle for NvmeDeviceHandle { // Fill max-size ranges until the remaining blocks fit into one range. while remaining > SPDK_NVME_DATASET_MANAGEMENT_RANGE_MAX_BLOCKS { unsafe { - let mut range = spdk_nvme_dsm_range::default(); - - range.attributes.raw = 0; - range.length = - SPDK_NVME_DATASET_MANAGEMENT_RANGE_MAX_BLOCKS as u32; - range.starting_lba = offset; + let range = spdk_nvme_dsm_range { + attributes: zeroed(), + length: SPDK_NVME_DATASET_MANAGEMENT_RANGE_MAX_BLOCKS + as u32, + starting_lba: offset, + }; *dsm_ranges.add(range_id) = range; } @@ -1135,11 +1140,11 @@ impl BlockDeviceHandle for NvmeDeviceHandle { // Setup range that describes the remaining blocks and schedule unmap. let rc = unsafe { - let mut range = spdk_nvme_dsm_range::default(); - - range.attributes.raw = 0; - range.length = remaining as u32; - range.starting_lba = offset; + let range = spdk_nvme_dsm_range { + attributes: zeroed(), + length: remaining as u32, + starting_lba: offset, + }; *dsm_ranges.add(range_id) = range; diff --git a/io-engine/src/bdev/nvmx/qpair.rs b/io-engine/src/bdev/nvmx/qpair.rs index 141364ce9..9684c2ce7 100644 --- a/io-engine/src/bdev/nvmx/qpair.rs +++ b/io-engine/src/bdev/nvmx/qpair.rs @@ -24,6 +24,7 @@ use spdk_rs::libspdk::{ #[cfg(feature = "spdk-async-qpair-connect")] use std::{os::raw::c_void, time::Duration}; +use std::mem::zeroed; #[cfg(feature = "spdk-async-qpair-connect")] use spdk_rs::{ @@ -110,7 +111,7 @@ impl Drop for QPair { fn get_default_options( ctrlr_handle: SpdkNvmeController, ) -> spdk_nvme_io_qpair_opts { - let mut opts = spdk_nvme_io_qpair_opts::default(); + let mut opts: spdk_nvme_io_qpair_opts = unsafe { zeroed() }; let default_opts = nvme_bdev_running_config(); unsafe { diff --git a/io-engine/src/bin/spdk.rs b/io-engine/src/bin/spdk.rs index 13776741e..8862ecf78 100644 --- a/io-engine/src/bin/spdk.rs +++ b/io-engine/src/bin/spdk.rs @@ -10,6 +10,7 @@ use std::{ ffi::{c_void, CString}, io::{Error, ErrorKind}, iter::Iterator, + mem::zeroed, os::raw::{c_char, c_int}, ptr::null_mut, vec::Vec, @@ -35,7 +36,7 @@ fn main() -> Result<(), std::io::Error> { .collect::>(); c_args.push(std::ptr::null()); - let mut opts: spdk_app_opts = Default::default(); + let mut opts: spdk_app_opts = unsafe { zeroed() }; unsafe { spdk_app_opts_init( diff --git a/io-engine/src/core/env.rs b/io-engine/src/core/env.rs index e214b2238..154d8f0bf 100644 --- a/io-engine/src/core/env.rs +++ b/io-engine/src/core/env.rs @@ -20,25 +20,36 @@ use futures::{channel::oneshot, future}; use http::Uri; use once_cell::sync::{Lazy, OnceCell}; use snafu::Snafu; +use tokio::runtime::Builder; +use version_info::{package_description, version_info_str}; + use spdk_rs::{ libspdk::{ spdk_app_shutdown_cb, + spdk_env_dpdk_post_init, + spdk_env_fini, + spdk_log_close, spdk_log_level, spdk_log_open, + spdk_log_set_flag, spdk_log_set_level, spdk_log_set_print_level, spdk_pci_addr, + spdk_rpc_finish, + spdk_rpc_initialize, spdk_rpc_set_state, + spdk_subsystem_fini, + spdk_subsystem_init, spdk_thread_lib_fini, spdk_thread_send_critical_msg, + spdk_trace_cleanup, + spdk_env_dpdk_rte_eal_init, SPDK_LOG_DEBUG, SPDK_LOG_INFO, SPDK_RPC_RUNTIME, }, spdk_rs_log, }; -use tokio::runtime::Builder; -use version_info::{package_description, version_info_str}; use crate::{ bdev::{bdev_io_ctx_pool_init, nexus, nvme_io_ctx_pool_init}, @@ -345,26 +356,6 @@ pub static GLOBAL_RC: Lazy>> = pub static SIG_RECEIVED: Lazy = Lazy::new(|| AtomicBool::new(false)); -// FFI functions that are needed to initialize the environment -extern "C" { - pub fn rte_eal_init(argc: i32, argv: *mut *mut libc::c_char) -> i32; - pub fn spdk_trace_cleanup(); - pub fn spdk_env_dpdk_post_init(legacy_mem: bool) -> i32; - pub fn spdk_env_fini(); - pub fn spdk_log_close(); - pub fn spdk_log_set_flag(name: *const c_char, enable: bool) -> i32; - pub fn spdk_rpc_finish(); - pub fn spdk_rpc_initialize(listen: *mut libc::c_char); - pub fn spdk_subsystem_fini( - f: Option, - ctx: *mut c_void, - ); - pub fn spdk_subsystem_init( - f: Option, - ctx: *mut c_void, - ); -} - #[derive(Debug, Snafu)] pub enum EnvError { #[snafu(display("Failed to install signal handler"))] @@ -777,7 +768,7 @@ impl MayastorEnvironment { debug!("EAL arguments {:?}", args); if unsafe { - rte_eal_init( + spdk_env_dpdk_rte_eal_init( (cargs.len() as libc::c_int) - 1, cargs.as_ptr() as *mut *mut c_char, ) @@ -802,7 +793,7 @@ impl MayastorEnvironment { unsafe { for flag in &self.log_component { let cflag = CString::new(flag.as_str()).unwrap(); - if spdk_log_set_flag(cflag.as_ptr(), true) != 0 { + if spdk_log_set_flag(cflag.as_ptr()) != 0 { error!("Failed to set SPDK log flag: {:?}", cflag); } } @@ -928,7 +919,10 @@ impl MayastorEnvironment { } else { info!("RPC server listening at: {}", ctx.rpc.to_str().unwrap()); unsafe { - spdk_rpc_initialize(ctx.rpc.as_ptr() as *mut c_char); + spdk_rpc_initialize( + ctx.rpc.as_ptr() as *mut c_char, + std::ptr::null_mut(), + ); spdk_rpc_set_state(SPDK_RPC_RUNTIME); }; diff --git a/io-engine/src/lvs/lvol_snapshot.rs b/io-engine/src/lvs/lvol_snapshot.rs index 100bc4c6c..733ddf61f 100644 --- a/io-engine/src/lvs/lvol_snapshot.rs +++ b/io-engine/src/lvs/lvol_snapshot.rs @@ -1,6 +1,7 @@ use std::{ convert::TryFrom, ffi::{c_ushort, c_void, CString}, + mem::zeroed, os::raw::c_char, }; @@ -221,7 +222,7 @@ impl SnapshotOps for Lvol { cb_arg: *mut c_void, ) -> Result<(), LvsError> { let mut attr_descrs: [spdk_xattr_descriptor; SnapshotXattrs::COUNT] = - [spdk_xattr_descriptor::default(); SnapshotXattrs::COUNT]; + [unsafe { zeroed() }; SnapshotXattrs::COUNT]; // Vector to keep allocated CStrings before snapshot creation // is complete to guarantee validity of attribute buffers @@ -385,7 +386,7 @@ impl SnapshotOps for Lvol { cb_arg: *mut c_void, ) -> Result<(), LvsError> { let mut attr_descrs: [spdk_xattr_descriptor; CloneXattrs::COUNT] = - [spdk_xattr_descriptor::default(); CloneXattrs::COUNT]; + [unsafe { zeroed() }; CloneXattrs::COUNT]; // Vector to keep allocated CStrings before snapshot creation // is complete to guarantee validity of attribute buffers diff --git a/io-engine/src/subsys/config/mod.rs b/io-engine/src/subsys/config/mod.rs index 84c5b8c3a..38ddd2391 100644 --- a/io-engine/src/subsys/config/mod.rs +++ b/io-engine/src/subsys/config/mod.rs @@ -6,7 +6,7 @@ //! spell out the YAML spec for a given sub component. Serde will fill //! in the default when missing, which are defined within the individual //! options. -use std::{fmt::Display, fs, io::Write, path::Path}; +use std::{fmt::Display, fs, io::Write, mem::zeroed, path::Path}; use futures::FutureExt; use once_cell::sync::OnceCell; @@ -104,13 +104,16 @@ impl ConfigSubsystem { pub fn new() -> Self { static MAYASTOR_SUBSYS: &str = "MayastorConfig"; debug!("creating Mayastor subsystem..."); - let mut ss = Box::::default(); + let mut ss = spdk_subsystem { + name: unsafe { zeroed() }, + init: Some(Self::init), + fini: Some(Self::fini), + write_config_json: Some(Self::config), + tailq: unsafe { zeroed() }, + }; ss.name = std::ffi::CString::new(MAYASTOR_SUBSYS).unwrap().into_raw(); - ss.init = Some(Self::init); - ss.fini = Some(Self::fini); - ss.write_config_json = Some(Self::config); - Self(Box::into_raw(ss)) + Self(Box::into_raw(Box::new(ss))) } } diff --git a/io-engine/src/subsys/config/opts.rs b/io-engine/src/subsys/config/opts.rs index aece4fcda..7133f3c60 100644 --- a/io-engine/src/subsys/config/opts.rs +++ b/io-engine/src/subsys/config/opts.rs @@ -23,11 +23,14 @@ use spdk_rs::{ spdk_sock_impl_opts, spdk_sock_impl_set_opts, }, + struct_size_init, }; use std::{ convert::TryFrom, fmt::{Debug, Display}, + mem::zeroed, + ptr::null_mut, str::FromStr, }; @@ -98,11 +101,14 @@ pub struct NvmfTgtConfig { impl From for Box { fn from(o: NvmfTgtConfig) -> Self { - let mut out = Self::default(); + let mut out = spdk_nvmf_target_opts { + name: unsafe { zeroed() }, + max_subsystems: o.max_namespaces, + crdt: o.crdt, + discovery_filter: 0, + }; copy_str_with_null(&o.name, &mut out.name); - out.max_subsystems = o.max_namespaces; - out.crdt = o.crdt; - out + Box::new(out) } } @@ -346,7 +352,7 @@ pub struct NvmeBdevOpts { impl GetOpts for NvmeBdevOpts { fn get(&self) -> Self { - let opts = spdk_bdev_nvme_opts::default(); + let opts: spdk_bdev_nvme_opts = unsafe { zeroed() }; unsafe { bdev_nvme_get_opts(&opts as *const _ as *mut spdk_bdev_nvme_opts) }; @@ -466,6 +472,8 @@ impl From<&NvmeBdevOpts> for spdk_bdev_nvme_opts { nvme_error_stat: false, rdma_srq_size: 0, io_path_stat: false, + allow_accel_sequence: false, + rdma_max_cq_size: 0, } } } @@ -477,17 +485,26 @@ pub struct BdevOpts { bdev_io_pool_size: u32, /// number of bdev IO structures cached per thread bdev_io_cache_size: u32, + /// Size of the per-thread iobuf small cache. + iobuf_small_cache_size: u32, + /// Size of the per-thread iobuf large cache. + iobuf_large_cache_size: u32, } impl GetOpts for BdevOpts { fn get(&self) -> Self { - let mut opts = spdk_bdev_opts::default(); - unsafe { - spdk_bdev_get_opts( - &mut opts, - std::mem::size_of::() as u64, - ) - }; + let mut opts = struct_size_init!( + spdk_bdev_opts { + bdev_io_pool_size: 0, + bdev_io_cache_size: 0, + bdev_auto_examine: false, + reserved9: unsafe { zeroed() }, + iobuf_small_cache_size: 0, + iobuf_large_cache_size: 0, + }, + opts_size + ); + unsafe { spdk_bdev_get_opts(&mut opts, opts.opts_size) }; opts.into() } @@ -507,6 +524,8 @@ impl Default for BdevOpts { Self { bdev_io_pool_size: try_from_env("BDEV_IO_POOL_SIZE", 65535), bdev_io_cache_size: try_from_env("BDEV_IO_CACHE_SIZE", 512), + iobuf_small_cache_size: try_from_env("BUF_SMALL_CACHE_SIZE", 128), + iobuf_large_cache_size: try_from_env("BUF_LARGE_CACHE_SIZE", 16), } } } @@ -516,20 +535,25 @@ impl From for BdevOpts { Self { bdev_io_pool_size: o.bdev_io_pool_size, bdev_io_cache_size: o.bdev_io_cache_size, + iobuf_small_cache_size: o.iobuf_small_cache_size, + iobuf_large_cache_size: o.iobuf_large_cache_size, } } } impl From<&BdevOpts> for spdk_bdev_opts { fn from(o: &BdevOpts) -> Self { - Self { - bdev_io_pool_size: o.bdev_io_pool_size, - bdev_io_cache_size: o.bdev_io_cache_size, - bdev_auto_examine: false, - reserved9: Default::default(), - opts_size: std::mem::size_of::() as u64, - reserved: Default::default(), - } + struct_size_init!( + Self { + bdev_io_pool_size: o.bdev_io_pool_size, + bdev_io_cache_size: o.bdev_io_cache_size, + bdev_auto_examine: false, + reserved9: Default::default(), + iobuf_small_cache_size: o.iobuf_small_cache_size, + iobuf_large_cache_size: o.iobuf_large_cache_size, + }, + opts_size + ) } } @@ -573,7 +597,25 @@ impl Default for PosixSocketOpts { impl GetOpts for PosixSocketOpts { fn get(&self) -> Self { - let opts = spdk_sock_impl_opts::default(); + let opts = spdk_sock_impl_opts { + recv_buf_size: 0, + send_buf_size: 0, + enable_recv_pipe: false, + enable_zerocopy_send: false, + enable_quickack: false, + enable_placement_id: 0, + enable_zerocopy_send_server: false, + enable_zerocopy_send_client: false, + zerocopy_threshold: 0, + tls_version: 0, + enable_ktls: false, + psk_key: null_mut(), + psk_key_size: 0, + psk_identity: null_mut(), + get_key: None, + get_key_ctx: null_mut(), + tls_cipher_suites: null_mut(), + }; unsafe { let name = std::ffi::CString::new("posix").unwrap(); @@ -655,7 +697,12 @@ pub struct IoBufOpts { impl GetOpts for IoBufOpts { fn get(&self) -> Self { - let mut opts = spdk_iobuf_opts::default(); + let mut opts = spdk_iobuf_opts { + small_pool_count: 0, + large_pool_count: 0, + small_bufsize: 0, + large_bufsize: 0, + }; unsafe { spdk_iobuf_get_opts(&mut opts) }; opts.into() } diff --git a/io-engine/src/subsys/mod.rs b/io-engine/src/subsys/mod.rs index 0518e9c0d..ac6b09060 100644 --- a/io-engine/src/subsys/mod.rs +++ b/io-engine/src/subsys/mod.rs @@ -22,6 +22,7 @@ use spdk_rs::libspdk::{ spdk_add_subsystem_depend, spdk_subsystem_depend, }; +use std::mem::zeroed; pub use registration::{ registration_grpc::Registration, @@ -39,11 +40,13 @@ pub mod registration; pub(crate) fn register_subsystem() { unsafe { spdk_add_subsystem(ConfigSubsystem::new().0) } unsafe { - let mut depend = Box::::default(); - depend.name = b"mayastor_nvmf_tgt\0" as *const u8 as *mut _; - depend.depends_on = b"bdev\0" as *const u8 as *mut _; + let depend = spdk_subsystem_depend { + name: b"mayastor_nvmf_tgt\0" as *const u8 as *mut _, + depends_on: b"bdev\0" as *const u8 as *mut _, + tailq: zeroed(), + }; spdk_add_subsystem(Nvmf::new().0); - spdk_add_subsystem_depend(Box::into_raw(depend)); + spdk_add_subsystem_depend(Box::into_raw(Box::new(depend))); } RegistrationSubsystem::register(); } diff --git a/io-engine/src/subsys/nvmf/admin_cmd.rs b/io-engine/src/subsys/nvmf/admin_cmd.rs index 551393acc..c7dbe264b 100644 --- a/io-engine/src/subsys/nvmf/admin_cmd.rs +++ b/io-engine/src/subsys/nvmf/admin_cmd.rs @@ -37,9 +37,9 @@ use spdk_rs::{ spdk_nvmf_bdev_ctrlr_nvme_passthru_admin, spdk_nvmf_request, spdk_nvmf_request_complete, + spdk_nvmf_request_copy_to_buf, spdk_nvmf_request_get_bdev, spdk_nvmf_request_get_cmd, - spdk_nvmf_request_get_data, spdk_nvmf_request_get_response, spdk_nvmf_request_get_subsystem, spdk_nvmf_set_custom_admin_cmd_hdlr, @@ -131,38 +131,37 @@ pub fn set_snapshot_time(cmd: &mut spdk_nvme_cmd) -> u64 { fn decode_snapshot_params( req: *mut spdk_nvmf_request, ) -> Option { - let encoded_msg = unsafe { - let mut val = std::ptr::null_mut(); - let mut size: u32 = 0; + const ITEM_SZ: usize = std::mem::size_of::(); + + let mut val: Vec = Vec::with_capacity(ITEM_SZ * 2); - spdk_nvmf_request_get_data( + let encoded_msg = unsafe { + let bytes_copied = spdk_nvmf_request_copy_to_buf( req, - &mut val as *mut *mut c_void, - &mut size as *mut u32, - ); + val.as_mut_ptr() as _, + val.capacity() as u64, + ) as usize; info!( "## length = {}, iov_cnt = {}, size = {}", (*req).length, (*req).iovcnt, - size, + bytes_copied, ); - std::slice::from_raw_parts(val as *const u8, size as usize) + std::slice::from_raw_parts(val.as_ptr(), bytes_copied) }; + let decoded_msg = bincode::deserialize::(encoded_msg); + // Decode versioned snapshot creation request. - let decoded_msg = - match bincode::deserialize::(encoded_msg) { - Err(e) => { - error!( - "Failed to deserialize snapshot creation message: {}", - e - ); - return None; - } - Ok(msg) => msg, - }; + let decoded_msg = match decoded_msg { + Err(e) => { + error!("Failed to deserialize snapshot creation message: {:?}", e); + return None; + } + Ok(msg) => msg, + }; let snapshot_params = match decoded_msg { NvmeSnapshotMessage::V1(v1) => v1.params().clone(), diff --git a/io-engine/src/subsys/nvmf/mod.rs b/io-engine/src/subsys/nvmf/mod.rs index 2117a506d..3bdb0884d 100644 --- a/io-engine/src/subsys/nvmf/mod.rs +++ b/io-engine/src/subsys/nvmf/mod.rs @@ -8,7 +8,7 @@ //! //! As connections come on, we randomly schedule them across cores by putting //! the qpair in a poll group that is allocated during reactor start. -use std::cell::RefCell; +use std::{cell::RefCell, mem::zeroed}; use nix::errno::Errno; use snafu::Snafu; @@ -124,11 +124,13 @@ impl Nvmf { pub fn new() -> Self { debug!("Creating NVMF subsystem..."); - let mut ss = Box::::default(); - ss.name = b"mayastor_nvmf_tgt\x00" as *const u8 as *const libc::c_char; - ss.init = Some(Self::init); - ss.fini = Some(Self::fini); - ss.write_config_json = None; - Self(Box::into_raw(ss)) + let ss = spdk_subsystem { + name: b"mayastor_nvmf_tgt\x00" as *const u8 as *const libc::c_char, + init: Some(Self::init), + fini: Some(Self::fini), + write_config_json: None, + tailq: unsafe { zeroed() }, + }; + Self(Box::into_raw(Box::new(ss))) } } diff --git a/io-engine/src/subsys/nvmf/subsystem.rs b/io-engine/src/subsys/nvmf/subsystem.rs index e913580b2..c9e26acf8 100644 --- a/io-engine/src/subsys/nvmf/subsystem.rs +++ b/io-engine/src/subsys/nvmf/subsystem.rs @@ -2,7 +2,7 @@ use std::{ convert::TryFrom, ffi::{c_void, CString}, fmt::{self, Debug, Display, Formatter}, - mem::size_of, + mem::zeroed, ptr::{self, NonNull}, }; @@ -12,9 +12,7 @@ use nix::errno::Errno; use spdk_rs::{ libspdk::{ nvmf_subsystem_find_listener, - nvmf_subsystem_set_ana_state, nvmf_subsystem_set_cntlid_range, - spdk_bdev_nvme_opts, spdk_nvmf_ctrlr_set_cpl_error_cb, spdk_nvmf_ns_get_bdev, spdk_nvmf_ns_opts, @@ -42,6 +40,7 @@ use spdk_rs::{ spdk_nvmf_subsystem_resume, spdk_nvmf_subsystem_set_allow_any_host, spdk_nvmf_subsystem_set_ana_reporting, + spdk_nvmf_subsystem_set_ana_state, spdk_nvmf_subsystem_set_event_cb, spdk_nvmf_subsystem_set_mn, spdk_nvmf_subsystem_set_sn, @@ -55,6 +54,7 @@ use spdk_rs::{ SPDK_NVMF_SUBTYPE_DISCOVERY, SPDK_NVMF_SUBTYPE_NVME, }, + struct_size_init, NvmeStatus, NvmfController, NvmfSubsystemEvent, @@ -519,10 +519,19 @@ impl NvmfSubsystem { where T: spdk_rs::BdevOps, { - let opts = spdk_nvmf_ns_opts { - nguid: *bdev.uuid().as_bytes(), - ..Default::default() - }; + let opts = struct_size_init!( + spdk_nvmf_ns_opts { + nsid: 0, + nguid: *bdev.uuid().as_bytes(), + eui64: unsafe { zeroed() }, + uuid: Default::default(), + reserved44: unsafe { zeroed() }, + anagrpid: 0, + reserved60: unsafe { zeroed() }, + }, + opts_size + ); + let bdev_cname = CString::new(bdev.name()).unwrap(); let ptpl = ptpl.map(|ptpl| { CString::new(ptpl.to_string_lossy().to_string()).unwrap() @@ -536,7 +545,7 @@ impl NvmfSubsystem { self.0.as_ptr(), bdev_cname.as_ptr(), &opts as *const _, - size_of::() as u64, + opts.opts_size, ptpl_ptr, ) }; @@ -979,7 +988,7 @@ impl NvmfSubsystem { let (s, r) = oneshot::channel::(); unsafe { - nvmf_subsystem_set_ana_state( + spdk_nvmf_subsystem_set_ana_state( self.0.as_ptr(), trid_replica.as_ptr(), ana_state, diff --git a/io-engine/src/subsys/nvmf/target.rs b/io-engine/src/subsys/nvmf/target.rs index 56c23f281..7607242f0 100644 --- a/io-engine/src/subsys/nvmf/target.rs +++ b/io-engine/src/subsys/nvmf/target.rs @@ -1,7 +1,8 @@ use std::{ cell::RefCell, ffi::{c_void, CString}, - ptr::NonNull, + mem::zeroed, + ptr::{null, NonNull}, }; use nix::errno::Errno; @@ -225,7 +226,13 @@ impl Target { fn listen(&mut self) -> Result<()> { let cfg = Config::get(); let trid_nexus = TransportId::new(cfg.nexus_opts.nvmf_nexus_port); - let mut opts = spdk_nvmf_listen_opts::default(); + let mut opts = spdk_nvmf_listen_opts { + opts_size: 0, + transport_specific: null(), + secure_channel: false, + reserved1: unsafe { zeroed() }, + ana_state: 0, + }; unsafe { spdk_nvmf_listen_opts_init( &mut opts, diff --git a/io-engine/src/subsys/registration/mod.rs b/io-engine/src/subsys/registration/mod.rs index 16b77e545..4b82917f0 100644 --- a/io-engine/src/subsys/registration/mod.rs +++ b/io-engine/src/subsys/registration/mod.rs @@ -13,7 +13,7 @@ use spdk_rs::libspdk::{ spdk_subsystem_fini_next, spdk_subsystem_init_next, }; -use std::convert::TryFrom; +use std::{convert::TryFrom, mem::zeroed}; macro_rules! default_addr { () => { @@ -70,13 +70,15 @@ impl RegistrationSubsystem { fn new() -> Self { info!("creating Mayastor registration subsystem..."); - let mut ss = Box::::default(); - ss.name = b"mayastor_grpc_registration\x00" as *const u8 - as *const libc::c_char; - ss.init = Some(Self::init); - ss.fini = Some(Self::fini); - ss.write_config_json = None; - Self(Box::into_raw(ss)) + let ss = spdk_subsystem { + name: b"mayastor_grpc_registration\x00" as *const u8 + as *const libc::c_char, + init: Some(Self::init), + fini: Some(Self::fini), + write_config_json: None, + tailq: unsafe { zeroed() }, + }; + Self(Box::into_raw(Box::new(ss))) } /// register the subsystem with spdk diff --git a/io-engine/tests/block_device_nvmf.rs b/io-engine/tests/block_device_nvmf.rs index 919f0223f..4408566f2 100755 --- a/io-engine/tests/block_device_nvmf.rs +++ b/io-engine/tests/block_device_nvmf.rs @@ -38,6 +38,7 @@ use std::{ use spdk_rs::{AsIoVecs, DmaBuf}; pub mod common; + use io_engine::{ constants::NVME_CONTROLLER_MODEL_ID, core::{DeviceEventListener, DeviceEventSink, ReadOptions}, @@ -266,7 +267,7 @@ fn flag_callback_invocation() { false, true, Ordering::Acquire, - Ordering::Relaxed + Ordering::Relaxed, ), Ok(false), "Callback is called more than once" @@ -279,7 +280,7 @@ fn check_callback_invocation() { true, false, Ordering::Acquire, - Ordering::Relaxed + Ordering::Relaxed, ), Ok(true), "Callback has not been called" @@ -1899,5 +1900,5 @@ async fn nvmf_device_hot_remove() { .await .expect_err("Device has been successfully created for controller without namespaces"); }) - .await; + .await; } diff --git a/nix/pkgs/libspdk/default.nix b/nix/pkgs/libspdk/default.nix index 1f6797466..06ebca40b 100644 --- a/nix/pkgs/libspdk/default.nix +++ b/nix/pkgs/libspdk/default.nix @@ -56,13 +56,13 @@ let # 7. Copy SHA256 from 'got' of the error message to 'sha256' field. # 8. 'nix-shell' build must now succeed. drvAttrs = rec { - version = "23.05-a56cdf9"; + version = "24.01-535a9e2"; src = fetchFromGitHub { owner = "openebs"; repo = "spdk"; - rev = "a56cdf9f8e3c0fe7db82dcadfdb6806743167635"; - sha256 = "sha256-Dgnn09dUaAUS6d+Og/DLcIhe5xeHsDBDydHuNyE3pIo="; + rev = "535a9e23cf9c0692e307a72f18856a528cdec9ce"; + sha256 = "sha256-1FhOOr3gjmmk/p0IACI/A/uIIN2yiFxGSLAr377HiZQ="; fetchSubmodules = true; }; @@ -117,13 +117,15 @@ let [ "--with-uring" "--without-uring-zns" + "--without-nvme-cuse" + "--without-fuse" "--disable-unit-tests" "--disable-tests" ]; configurePhase = '' patchShebangs ./. > /dev/null - export AS=yasm + export AS=nasm ./configure ${builtins.concatStringsSep " " configureFlags} ''; enableParallelBuilding = true; @@ -180,6 +182,9 @@ let sed -i "s,$build_dir/build/lib,$out/lib,g" $i sed -i "s,$build_dir/dpdk/build,$out,g" $i sed -i "s,$build_dir/intel-ipsec-mb/lib,$out/lib,g" $i + sed -i "s,$build_dir/isa-l/.libs,$out/lib,g" $i + sed -i "s,$build_dir/isa-l-crypto/.libs,$out/lib,g" $i + sed -i "s,prefix\=/usr/local,prefix\=$out,g" $i done '' + lib.optionalString (with-fio && !multi-outputs) '' mkdir $out/fio @@ -204,7 +209,7 @@ in buildInputs = drvAttrs.buildInputs ++ [ cunit lcov ]; configurePhase = '' patchShebangs ./. > /dev/null - export AS=yasm + export AS=nasm ./configure ${builtins.concatStringsSep " " (drvAttrs.configureFlags ++ [ "--enable-debug" diff --git a/spdk-rs b/spdk-rs index a1efae6c1..d9fd02762 160000 --- a/spdk-rs +++ b/spdk-rs @@ -1 +1 @@ -Subproject commit a1efae6c1d8c6eaf4f6ce54b5c919f664fd466f3 +Subproject commit d9fd027627266f1731064101624160f031779b05