diff --git a/io-engine/src/bdev/lvs.rs b/io-engine/src/bdev/lvs.rs index 281673e10..6ba0bf505 100644 --- a/io-engine/src/bdev/lvs.rs +++ b/io-engine/src/bdev/lvs.rs @@ -232,35 +232,10 @@ impl Lvs { LvsMode::CreateOrImport => { crate::lvs::Lvs::create_or_import(args).await } - LvsMode::Purge => match self.destroy().await { - Ok(_) - | Err(BdevError::BdevNotFound { - .. - }) => match crate::lvs::Lvs::create_or_import(args.clone()) - .await - { - Ok(lvs) => Ok(lvs), - Err(crate::lvs::Error::Import { - reason: - crate::lvs::ImportErrorReason::NameMismatch { - name, - }, - .. - }) => { - let mut eargs = args.clone(); - eargs.name = name; - match crate::lvs::Lvs::create_or_import(eargs).await { - Ok(lvs) => { - lvs.destroy().await.ok(); - crate::lvs::Lvs::create_or_import(args).await - } - Err(error) => Err(error), - } - } - Err(error) => Err(error), - }, - Err(error) => return Err(error), - }, + LvsMode::Purge => { + Self::wipe_super(args.clone()).await?; + crate::lvs::Lvs::create_or_import(args).await + } } .map_err(|error| BdevError::CreateBdevFailedStr { error: error.to_string(), @@ -268,6 +243,49 @@ impl Lvs { }) } + async fn wipe_super(args: PoolArgs) -> Result<(), BdevError> { + let disk = + crate::lvs::Lvs::parse_disk(args.disks.clone()).map_err(|_| { + BdevError::InvalidUri { + uri: String::new(), + message: String::new(), + } + })?; + + let parsed = super::uri::parse(&disk)?; + let bdev_str = parsed.create().await?; + { + let bdev = + crate::core::Bdev::get_by_name(&bdev_str).map_err(|_| { + BdevError::BdevNotFound { + name: bdev_str, + } + })?; + + let hdl = crate::core::Bdev::open(&bdev, true) + .and_then(|desc| desc.into_handle()) + .map_err(|_| BdevError::BdevNotFound { + name: bdev.name().into(), + })?; + + let wiper = crate::core::wiper::Wiper::new( + hdl, + crate::core::wiper::WipeMethod::WriteZeroes, + ) + .map_err(|_| BdevError::WipeFailed {})?; + wiper + .wipe(0, 8 * 1024 * 1024) + .await + .map_err(|_| BdevError::WipeFailed {})?; + } + // We can't destroy the device here as this causes issues with the next + // section. Seems the deletion of nvme device is not sync as + // bdev_nvme_delete implies.. + // todo: ensure nvme delete does what it says.. + // parsed.destroy().await.unwrap(); + Ok(()) + } + async fn destroy(&self) -> Result<(), BdevError> { debug!("{self:?}: deleting"); let Some(lvs) = crate::lvs::Lvs::lookup(&self.name) else { diff --git a/io-engine/src/bdev_api.rs b/io-engine/src/bdev_api.rs index 9f189ee79..1d65d0c0d 100644 --- a/io-engine/src/bdev_api.rs +++ b/io-engine/src/bdev_api.rs @@ -98,6 +98,8 @@ pub enum BdevError { // Command canceled. #[snafu(display("Command canceled for a BDEV '{}'", name))] BdevCommandCanceled { source: Canceled, name: String }, + #[snafu(display("Failed to wipe the BDEV"))] + WipeFailed {}, } /// Parse URI and create bdev described in the URI. diff --git a/io-engine/src/core/wiper.rs b/io-engine/src/core/wiper.rs index 2489a7f23..24146bf16 100644 --- a/io-engine/src/core/wiper.rs +++ b/io-engine/src/core/wiper.rs @@ -159,7 +159,7 @@ impl Wiper { }) } /// Wipe the bdev at the given byte offset and byte size. - async fn wipe(&self, offset: u64, size: u64) -> Result<(), Error> { + pub async fn wipe(&self, offset: u64, size: u64) -> Result<(), Error> { match self.wipe_method { WipeMethod::None => Ok(()), WipeMethod::WriteZeroes => { diff --git a/io-engine/src/lvs/lvs_store.rs b/io-engine/src/lvs/lvs_store.rs index afb8c5847..68cfe489c 100644 --- a/io-engine/src/lvs/lvs_store.rs +++ b/io-engine/src/lvs/lvs_store.rs @@ -218,7 +218,7 @@ impl Lvs { } // checks for the disks length and parses to correct format - fn parse_disk(disks: Vec) -> Result { + pub fn parse_disk(disks: Vec) -> Result { let disk = match disks.first() { Some(disk) if disks.len() == 1 => { if Url::parse(disk).is_err() {