diff --git a/src/engine/strat_engine/backstore/backstore.rs b/src/engine/strat_engine/backstore/backstore.rs index 72cf1ddbb43..c8d16a9a9d3 100644 --- a/src/engine/strat_engine/backstore/backstore.rs +++ b/src/engine/strat_engine/backstore/backstore.rs @@ -26,7 +26,7 @@ use crate::{ shared::BlockSizeSummary, transaction::RequestTransaction, }, - dm::get_dm, + dm::{get_dm, list_of_backstore_devices, remove_optional_devices}, metadata::{MDADataSize, BDA}, names::{format_backstore_ids, CacheRole}, serde_structs::{BackstoreSave, CapSave, Recordable}, @@ -550,43 +550,23 @@ impl Backstore { } /// Destroy the entire store. - pub fn destroy(&mut self) -> StratisResult<()> { - match self.cache { - Some(ref mut cache) => { - cache.teardown(get_dm())?; - self.cache_tier - .as_mut() - .expect("if dm_device is cache, cache tier exists") - .destroy()?; - } - None => { - if let Some(ref mut linear) = self.linear { - linear.teardown(get_dm())?; - } - } - }; + pub fn destroy(&mut self, pool_uuid: PoolUuid) -> StratisResult<()> { + let devs = list_of_backstore_devices(pool_uuid); + remove_optional_devices(devs)?; + if let Some(ref mut cache_tier) = self.cache_tier { + cache_tier.destroy()?; + } self.data_tier.destroy() } /// Teardown the DM devices in the backstore. - pub fn teardown(&mut self) -> StratisResult<()> { - match self - .cache - .as_mut() - .and_then(|c| self.cache_tier.as_mut().map(|ct| (c, ct))) - { - Some((cache, cache_tier)) => { - cache.teardown(get_dm())?; - cache_tier.block_mgr.teardown()?; - } - None => { - if let Some(ref mut linear) = self.linear { - linear.teardown(get_dm())?; - } - } - }; - self.data_tier.block_mgr.teardown()?; - Ok(()) + pub fn teardown(&mut self, pool_uuid: PoolUuid) -> StratisResult<()> { + let devs = list_of_backstore_devices(pool_uuid); + remove_optional_devices(devs)?; + if let Some(ref mut cache_tier) = self.cache_tier { + cache_tier.block_mgr.teardown()?; + } + self.data_tier.block_mgr.teardown() } /// Consume the backstore and convert it into a set of BDAs representing @@ -1249,7 +1229,7 @@ mod tests { CacheDevStatus::Fail => panic!("cache is in a failed state"), } - backstore.destroy().unwrap(); + backstore.destroy(pool_uuid).unwrap(); } #[test] @@ -1330,7 +1310,7 @@ mod tests { assert_ne!(backstore.device(), old_device); - backstore.destroy().unwrap(); + backstore.destroy(pool_uuid).unwrap(); } #[test] diff --git a/src/engine/strat_engine/backstore/crypt/shared.rs b/src/engine/strat_engine/backstore/crypt/shared.rs index c786cda8311..87d87fa7bcc 100644 --- a/src/engine/strat_engine/backstore/crypt/shared.rs +++ b/src/engine/strat_engine/backstore/crypt/shared.rs @@ -11,7 +11,6 @@ use std::{ use data_encoding::BASE64URL_NOPAD; use either::Either; -use retry::{delay::Fixed, retry_with_index, Error as RetryError}; use serde::{ de::{Error, MapAccess, Visitor}, ser::SerializeMap, @@ -21,11 +20,11 @@ use serde_json::{from_value, to_value, Map, Value}; use sha2::{Digest, Sha256}; use tempfile::TempDir; -use devicemapper::{Bytes, DmName, DmNameBuf}; +use devicemapper::{Bytes, DevId, DmName, DmNameBuf, DmOptions}; use libcryptsetup_rs::{ c_uint, consts::{ - flags::{CryptActivate, CryptDeactivate, CryptVolumeKey, CryptWipe}, + flags::{CryptActivate, CryptVolumeKey, CryptWipe}, vals::{ CryptDebugLevel, CryptLogLevel, CryptStatusInfo, CryptWipePattern, EncryptionFormat, }, @@ -51,6 +50,7 @@ use crate::{ devices::get_devno_from_path, }, cmd::clevis_luks_unlock, + dm::get_dm, keys, metadata::StratisIdentifiers, }, @@ -863,31 +863,8 @@ pub fn ensure_inactive(device: &mut CryptDevice, name: &DmName) -> StratisResult name ); match status { - CryptStatusInfo::Active => { - log_on_failure!( - device - .activate_handle() - .deactivate(&name.to_string(), CryptDeactivate::empty()), - "Failed to deactivate the crypt device with name {}", - name - ); - } - CryptStatusInfo::Busy => { - retry_with_index(Fixed::from_millis(100).take(2), |i| { - trace!("Crypt device deactivate attempt {}", i); - device - .activate_handle() - .deactivate(&name.to_string(), CryptDeactivate::empty()) - .map_err(StratisError::Crypt) - }) - .map_err(|e| match e { - RetryError::Internal(s) => StratisError::Chained( - "Retries for crypt device deactivation failed with an internal error" - .to_string(), - Box::new(StratisError::Msg(s)), - ), - RetryError::Operation { error, .. } => error, - })?; + CryptStatusInfo::Active | CryptStatusInfo::Busy => { + get_dm().device_remove(&DevId::Name(name), DmOptions::default())?; } _ => (), } diff --git a/src/engine/strat_engine/dm.rs b/src/engine/strat_engine/dm.rs index 6358db10644..960e978f560 100644 --- a/src/engine/strat_engine/dm.rs +++ b/src/engine/strat_engine/dm.rs @@ -10,14 +10,11 @@ use devicemapper::{DevId, DmNameBuf, DmOptions, DmResult, DM}; use crate::{ engine::{ - strat_engine::{ - liminal::DeviceSet, - names::{ - format_backstore_ids, format_crypt_name, format_flex_ids, format_thinpool_ids, - CacheRole, FlexRole, ThinPoolRole, - }, + strat_engine::names::{ + format_backstore_ids, format_crypt_name, format_flex_ids, format_thin_ids, + format_thinpool_ids, CacheRole, FlexRole, ThinPoolRole, ThinRole, }, - types::{DevUuid, PoolUuid}, + types::{DevUuid, FilesystemUuid, PoolUuid}, }, stratis::{StratisError, StratisResult}, }; @@ -48,21 +45,14 @@ pub fn get_dm() -> &'static DM { ) } -pub fn stop_partially_constructed_pool( - pool_uuid: PoolUuid, - device_set: &DeviceSet, -) -> StratisResult { +pub fn remove_optional_devices(devs: Vec) -> StratisResult { let mut did_something = false; let devices = get_dm() .list_devices()? .into_iter() .map(|(name, _, _)| name) .collect::>(); - let dev_uuids = device_set - .iter() - .map(|(dev_uuid, _)| *dev_uuid) - .collect::>(); - for device in list_of_devices(pool_uuid, &dev_uuids) { + for device in devs { if devices.contains(&device) { did_something = true; get_dm().device_remove(&DevId::Name(&device), DmOptions::default())?; @@ -71,11 +61,22 @@ pub fn stop_partially_constructed_pool( Ok(did_something) } -/// List of device names for removal on partially constructed pool stop. Does not have -/// filesystem names because partially constructed pools are guaranteed not to have any -/// active filesystems. -fn list_of_devices(pool_uuid: PoolUuid, dev_uuids: &[DevUuid]) -> Vec { +pub fn stop_partially_constructed_pool( + pool_uuid: PoolUuid, + dev_uuids: &[DevUuid], +) -> StratisResult { + let devs = list_of_partial_pool_devices(pool_uuid, dev_uuids); + remove_optional_devices(devs) +} + +pub fn thin_device(pool_uuid: PoolUuid, fs_uuid: FilesystemUuid) -> DmNameBuf { + let (dm_name, _) = format_thin_ids(pool_uuid, ThinRole::Filesystem(fs_uuid)); + dm_name +} + +pub fn list_of_thin_pool_devices(pool_uuid: PoolUuid) -> Vec { let mut devs = Vec::new(); + let (thin_pool, _) = format_thinpool_ids(pool_uuid, ThinPoolRole::Pool); devs.push(thin_pool); let (thin_data, _) = format_flex_ids(pool_uuid, FlexRole::ThinData); @@ -84,8 +85,18 @@ fn list_of_devices(pool_uuid: PoolUuid, dev_uuids: &[DevUuid]) -> Vec devs.push(thin_meta); let (thin_meta_spare, _) = format_flex_ids(pool_uuid, FlexRole::ThinMetaSpare); devs.push(thin_meta_spare); + + devs +} + +pub fn mdv_device(pool_uuid: PoolUuid) -> DmNameBuf { let (thin_mdv, _) = format_flex_ids(pool_uuid, FlexRole::MetadataVolume); - devs.push(thin_mdv); + thin_mdv +} + +pub fn list_of_backstore_devices(pool_uuid: PoolUuid) -> Vec { + let mut devs = Vec::new(); + let (cache, _) = format_backstore_ids(pool_uuid, CacheRole::Cache); devs.push(cache); let (cache_sub, _) = format_backstore_ids(pool_uuid, CacheRole::CacheSub); @@ -95,6 +106,12 @@ fn list_of_devices(pool_uuid: PoolUuid, dev_uuids: &[DevUuid]) -> Vec let (origin, _) = format_backstore_ids(pool_uuid, CacheRole::OriginSub); devs.push(origin); + devs +} + +pub fn list_of_crypt_devices(dev_uuids: &[DevUuid]) -> Vec { + let mut devs = Vec::new(); + for dev_uuid in dev_uuids.iter() { let crypt = format_crypt_name(dev_uuid); devs.push(crypt); @@ -103,10 +120,27 @@ fn list_of_devices(pool_uuid: PoolUuid, dev_uuids: &[DevUuid]) -> Vec devs } +/// List of device names for removal on partially constructed pool stop. Does not have +/// filesystem names because partially constructed pools are guaranteed not to have any +/// active filesystems. +fn list_of_partial_pool_devices(pool_uuid: PoolUuid, dev_uuids: &[DevUuid]) -> Vec { + let mut devs = Vec::new(); + + devs.extend(list_of_thin_pool_devices(pool_uuid)); + + devs.push(mdv_device(pool_uuid)); + + devs.extend(list_of_backstore_devices(pool_uuid)); + + devs.extend(list_of_crypt_devices(dev_uuids)); + + devs +} + /// Check whether there are any leftover devicemapper devices from the pool. pub fn has_leftover_devices(pool_uuid: PoolUuid, dev_uuids: &[DevUuid]) -> bool { let mut has_leftover = false; - let devices = list_of_devices(pool_uuid, dev_uuids); + let devices = list_of_partial_pool_devices(pool_uuid, dev_uuids); match get_dm().list_devices() { Ok(l) => { let listed_devices = l diff --git a/src/engine/strat_engine/engine.rs b/src/engine/strat_engine/engine.rs index 859d3069322..bc83ed31893 100644 --- a/src/engine/strat_engine/engine.rs +++ b/src/engine/strat_engine/engine.rs @@ -233,7 +233,7 @@ impl StratEngine { let mut untorndown_pools = Vec::new(); let mut write_all = block_on(self.pools.write_all()); for (_, uuid, pool) in write_all.iter_mut() { - pool.teardown() + pool.teardown(*uuid) .unwrap_or_else(|_| untorndown_pools.push(uuid)); } if untorndown_pools.is_empty() { @@ -453,7 +453,7 @@ impl Engine for StratEngine { .remove_by_uuid(uuid) .expect("Must succeed since self.pools.get_by_uuid() returned a value"); - let (res, mut pool) = spawn_blocking!((pool.destroy(), pool))?; + let (res, mut pool) = spawn_blocking!((pool.destroy(uuid), pool))?; if let Err((err, true)) = res { guard.insert(pool_name, uuid, pool); Err(err) diff --git a/src/engine/strat_engine/liminal/device_info.rs b/src/engine/strat_engine/liminal/device_info.rs index d8df7340c97..1b65aa22e23 100644 --- a/src/engine/strat_engine/liminal/device_info.rs +++ b/src/engine/strat_engine/liminal/device_info.rs @@ -47,8 +47,13 @@ impl fmt::Display for LLuksInfo { write!( f, "{}, {}, {}", - self.dev_info, self.identifiers, self.encryption_info - ) + self.dev_info, self.identifiers, self.encryption_info, + )?; + if let Some(ref pn) = self.pool_name { + write!(f, ", {}", pn) + } else { + Ok(()) + } } } @@ -502,6 +507,15 @@ impl FromIterator<(DevUuid, LInfo)> for DeviceSet { } } +impl IntoIterator for DeviceSet { + type Item = as IntoIterator>::Item; + type IntoIter = as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.internal.into_iter() + } +} + impl From> for DeviceSet { fn from(vec: Vec) -> Self { vec.into_iter() diff --git a/src/engine/strat_engine/liminal/liminal.rs b/src/engine/strat_engine/liminal/liminal.rs index 7664cd5d598..4b78bc5e21d 100644 --- a/src/engine/strat_engine/liminal/liminal.rs +++ b/src/engine/strat_engine/liminal/liminal.rs @@ -273,7 +273,7 @@ impl LiminalDevices { pool_uuid: PoolUuid, mut pool: StratPool, ) -> StratisResult<()> { - let (devices, err) = match pool.stop(&pool_name) { + let (devices, err) = match pool.stop(&pool_name, pool_uuid) { Ok(devs) => (devs, None), Err((e, true)) => { pools.insert(pool_name, pool_uuid, pool); @@ -881,9 +881,37 @@ impl LiminalDevices { .map(|(dev_uuid, _)| *dev_uuid) .collect::>(); if has_leftover_devices(pool_uuid, &device_uuids) { - match stop_partially_constructed_pool(pool_uuid, &device_set) { + let dev_uuids = device_set + .iter() + .map(|(dev_uuid, _)| *dev_uuid) + .collect::>(); + let res = stop_partially_constructed_pool(pool_uuid, &dev_uuids); + let device_set = device_set + .into_iter() + .map(|(dev_uuid, info)| { + ( + dev_uuid, + match info { + LInfo::Luks(l) => LInfo::Luks(l), + LInfo::Stratis(mut s) => { + if let Some(l) = s.luks { + if !s.dev_info.devnode.exists() { + LInfo::Luks(l) + } else { + s.luks = Some(l); + LInfo::Stratis(s) + } + } else { + LInfo::Stratis(s) + } + } + }, + ) + }) + .collect::(); + match res { Ok(_) => { - assert!(!has_leftover_devices(pool_uuid, &device_uuids,)); + assert!(!has_leftover_devices(pool_uuid, &device_uuids)); self.stopped_pools.insert(pool_uuid, device_set); } Err(_) => { diff --git a/src/engine/strat_engine/pool.rs b/src/engine/strat_engine/pool.rs index c29201b25ab..9c2732e441c 100644 --- a/src/engine/strat_engine/pool.rs +++ b/src/engine/strat_engine/pool.rs @@ -187,7 +187,7 @@ impl StratPool { match ThinPoolSizeParams::new(backstore.datatier_usable_size()) { Ok(ref params) => params, Err(causal_error) => { - if let Err(cleanup_err) = backstore.destroy() { + if let Err(cleanup_err) = backstore.destroy(pool_uuid) { warn!("Failed to clean up Stratis metadata for incompletely set up pool with UUID {}: {}.", pool_uuid, cleanup_err); return Err(StratisError::NoActionRollbackError { causal_error: Box::new(causal_error), @@ -204,7 +204,7 @@ impl StratPool { let thinpool = match thinpool { Ok(thinpool) => thinpool, Err(causal_error) => { - if let Err(cleanup_err) = backstore.destroy() { + if let Err(cleanup_err) = backstore.destroy(pool_uuid) { warn!("Failed to clean up Stratis metadata for incompletely set up pool with UUID {}: {}.", pool_uuid, cleanup_err); return Err(StratisError::NoActionRollbackError { causal_error: Box::new(causal_error), @@ -317,9 +317,9 @@ impl StratPool { /// Teardown a pool. #[cfg(test)] - pub fn teardown(&mut self) -> StratisResult<()> { - self.thin_pool.teardown().map_err(|(e, _)| e)?; - self.backstore.teardown()?; + pub fn teardown(&mut self, pool_uuid: PoolUuid) -> StratisResult<()> { + self.thin_pool.teardown(pool_uuid).map_err(|(e, _)| e)?; + self.backstore.teardown(pool_uuid)?; Ok(()) } @@ -394,9 +394,9 @@ impl StratPool { /// /// This method is not a mutating action as the pool should be allowed /// to be destroyed even if the metadata is inconsistent. - pub fn destroy(&mut self) -> Result<(), (StratisError, bool)> { - self.thin_pool.teardown()?; - self.backstore.destroy().map_err(|e| (e, false))?; + pub fn destroy(&mut self, pool_uuid: PoolUuid) -> Result<(), (StratisError, bool)> { + self.thin_pool.teardown(pool_uuid)?; + self.backstore.destroy(pool_uuid).map_err(|e| (e, false))?; Ok(()) } @@ -412,15 +412,19 @@ impl StratPool { /// Stop a pool, consuming it and converting it into a set of devices to be /// set up again later. - pub fn stop(&mut self, pool_name: &Name) -> Result { - self.thin_pool.teardown()?; + pub fn stop( + &mut self, + pool_name: &Name, + pool_uuid: PoolUuid, + ) -> Result { + self.thin_pool.teardown(pool_uuid)?; let mut data = self.record(pool_name); data.started = Some(false); let json = serde_json::to_string(&data).map_err(|e| (StratisError::from(e), false))?; self.backstore .save_state(json.as_bytes()) .map_err(|e| (e, false))?; - self.backstore.teardown().map_err(|e| (e, false))?; + self.backstore.teardown(pool_uuid).map_err(|e| (e, false))?; let bds = self.backstore.drain_bds(); Ok(DeviceSet::from(bds)) } @@ -1314,7 +1318,7 @@ mod tests { } assert_eq!(&buf, bytestring); umount(tmp_dir.path()).unwrap(); - pool.teardown().unwrap(); + pool.teardown(uuid).unwrap(); } #[test] @@ -1354,7 +1358,7 @@ mod tests { pool.add_blockdevs(uuid, name, data_paths, BlockDevTier::Data) .unwrap(); - pool.teardown().unwrap(); + pool.teardown(uuid).unwrap(); } #[test] @@ -1469,14 +1473,14 @@ mod tests { let (stratis_devices, unowned_devices) = devices.unpack(); stratis_devices.error_on_not_empty().unwrap(); - let (_, mut pool) = StratPool::initialize(name, unowned_devices, None).unwrap(); + let (uuid, mut pool) = StratPool::initialize(name, unowned_devices, None).unwrap(); invariant(&pool, name); assert_eq!(pool.action_avail, ActionAvailability::Full); assert!(pool.return_rollback_failure().is_err()); assert_eq!(pool.action_avail, ActionAvailability::NoRequests); - pool.destroy().unwrap(); + pool.destroy(uuid).unwrap(); udev_settle().unwrap(); let name = "stratis-test-pool"; diff --git a/src/engine/strat_engine/thinpool/filesystem.rs b/src/engine/strat_engine/thinpool/filesystem.rs index bb84e297cc2..ac85aec8769 100644 --- a/src/engine/strat_engine/thinpool/filesystem.rs +++ b/src/engine/strat_engine/thinpool/filesystem.rs @@ -15,7 +15,7 @@ use retry::{delay::Fixed, retry_with_index}; use serde_json::{Map, Value}; use devicemapper::{ - Bytes, DmDevice, DmName, DmOptions, DmUuid, Sectors, ThinDev, ThinDevId, ThinPoolDev, + Bytes, DevId, DmDevice, DmName, DmOptions, DmUuid, Sectors, ThinDev, ThinDevId, ThinPoolDev, ThinStatus, }; @@ -31,7 +31,7 @@ use crate::{ strat_engine::{ cmd::{create_fs, set_uuid, xfs_growfs}, devlinks, - dm::get_dm, + dm::{get_dm, thin_device}, names::{format_thin_ids, ThinRole}, serde_structs::FilesystemSave, }, @@ -322,8 +322,9 @@ impl StratFilesystem { } /// Tear down the filesystem. - pub fn teardown(&mut self) -> StratisResult<()> { - self.thin_dev.teardown(get_dm())?; + pub fn teardown(pool_uuid: PoolUuid, fs_uuid: FilesystemUuid) -> StratisResult<()> { + let device = thin_device(pool_uuid, fs_uuid); + get_dm().device_remove(&DevId::Name(&device), DmOptions::default())?; Ok(()) } diff --git a/src/engine/strat_engine/thinpool/mdv.rs b/src/engine/strat_engine/thinpool/mdv.rs index 0bdf0cbb3a1..444b763eda4 100644 --- a/src/engine/strat_engine/thinpool/mdv.rs +++ b/src/engine/strat_engine/thinpool/mdv.rs @@ -19,13 +19,15 @@ use nix::{ }; use retry::{delay::Fixed, retry_with_index}; -use devicemapper::{DmDevice, DmOptions, LinearDev, LinearDevTargetParams, Sectors, TargetLine}; +use devicemapper::{ + DevId, DmDevice, DmOptions, LinearDev, LinearDevTargetParams, Sectors, TargetLine, +}; use crate::{ engine::{ strat_engine::{ cmd::create_fs, - dm::get_dm, + dm::{get_dm, mdv_device}, ns::NS_TMPFS_LOCATION, serde_structs::FilesystemSave, thinpool::filesystem::{fs_usage, StratFilesystem}, @@ -188,7 +190,7 @@ impl MetadataVol { } /// Tear down a Metadata Volume. - pub fn teardown(&mut self) -> StratisResult<()> { + pub fn teardown(&mut self, pool_uuid: PoolUuid) -> StratisResult<()> { if let Err(e) = retry_with_index(Fixed::from_millis(100).take(2), |i| { trace!("MDV unmount attempt {}", i); umount(&self.mount_pt) @@ -206,7 +208,8 @@ impl MetadataVol { warn!("Could not remove MDV mount point: {}", err); } - self.dev.teardown(get_dm())?; + let dev = mdv_device(pool_uuid); + get_dm().device_remove(&DevId::Name(&dev), DmOptions::default())?; Ok(()) } diff --git a/src/engine/strat_engine/thinpool/thinpool.rs b/src/engine/strat_engine/thinpool/thinpool.rs index 9ab67117543..17883b5d45a 100644 --- a/src/engine/strat_engine/thinpool/thinpool.rs +++ b/src/engine/strat_engine/thinpool/thinpool.rs @@ -26,7 +26,7 @@ use crate::{ strat_engine::{ backstore::Backstore, cmd::{thin_check, thin_metadata_size, thin_repair}, - dm::get_dm, + dm::{get_dm, list_of_thin_pool_devices, remove_optional_devices}, names::{ format_flex_ids, format_thin_ids, format_thinpool_ids, FlexRole, ThinPoolRole, ThinRole, @@ -814,18 +814,17 @@ impl ThinPool { /// structures. However if all filesystems were torn down, the pool can be moved to /// the designation of partially constructed pools as no IO can be received on the pool /// and it has been partially torn down. - pub fn teardown(&mut self) -> Result<(), (StratisError, bool)> { + pub fn teardown(&mut self, pool_uuid: PoolUuid) -> Result<(), (StratisError, bool)> { // Must succeed in tearing down all filesystems before the // thinpool.. - for (_, _, ref mut fs) in &mut self.filesystems { - fs.teardown().map_err(|e| (e, true))?; + for (_, fs_uuid, _) in &mut self.filesystems { + StratFilesystem::teardown(pool_uuid, *fs_uuid).map_err(|e| (e, true))?; } - self.thin_pool - .teardown(get_dm()) - .map_err(|e| (StratisError::from(e), false))?; + let devs = list_of_thin_pool_devices(pool_uuid); + remove_optional_devices(devs).map_err(|e| (e, false))?; // ..but MDV has no DM dependencies with the above - self.mdv.teardown().map_err(|e| (e, false))?; + self.mdv.teardown(pool_uuid).map_err(|e| (e, false))?; Ok(()) } @@ -2116,7 +2115,7 @@ mod tests { let flexdevs: FlexDevsSave = pool.record(); let thinpoolsave: ThinPoolDevSave = pool.record(); - retry_operation!(pool.teardown()); + retry_operation!(pool.teardown(pool_uuid)); let pool = ThinPool::setup(pool_name, pool_uuid, &thinpoolsave, &flexdevs, &backstore).unwrap(); @@ -2248,7 +2247,7 @@ mod tests { retry_operation!(pool.destroy_filesystem(pool_name, fs_uuid)); let flexdevs: FlexDevsSave = pool.record(); let thinpooldevsave: ThinPoolDevSave = pool.record(); - pool.teardown().unwrap(); + pool.teardown(pool_uuid).unwrap(); // Check that destroyed fs is not present in MDV. If the record // had been left on the MDV that didn't match a thin_id in the