From f536d2547a39ed1fc9551b29a0307762958d80fa Mon Sep 17 00:00:00 2001 From: John Baublitz Date: Thu, 9 Mar 2023 17:32:15 -0500 Subject: [PATCH] Placeholder LinearDev to be converted to CacheDev This commit adds a linear device in between the thin pool and linear device containing all of the data devices. This will later be used when the cryptsetup layer is moved on top of the cap device. This way, the backing device for the crypt device will never change. Changing the backing device for the dm-crypt device outside of cryptsetup could result in future problems. --- Cargo.lock | 43 ++++------- Cargo.toml | 3 +- .../strat_engine/backstore/backstore.rs | 72 ++++++++++++++++--- 3 files changed, 78 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aa3a2777863..46e1b1b7080 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -333,26 +333,28 @@ dependencies = [ [[package]] name = "devicemapper" -version = "0.32.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1da7c273a50833e1fbbff5b71b06fd1f3f00356b0fa1d392a21ee8b4aabb2a1e" +version = "0.33.1" +source = "git+https://github.com/jbaublitz/devicemapper-rs?branch=stratisd-metadata-rework#b6f6a703701390548f553b020b95256fcf1128c6" dependencies = [ "bitflags", "devicemapper-sys", + "env_logger", "lazy_static", - "nix 0.24.3", + "log", + "nix 0.26.2", + "rand", + "retry", "semver", "serde", ] [[package]] name = "devicemapper-sys" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d2aad5bae6bc8a217f8c398c5737122966cbd35f19dd223433606225ec48285" +version = "0.1.5" +source = "git+https://github.com/jbaublitz/devicemapper-rs?branch=stratisd-metadata-rework#b6f6a703701390548f553b020b95256fcf1128c6" dependencies = [ - "bindgen 0.59.2", - "nix 0.24.3", + "bindgen 0.63.0", + "nix 0.26.2", ] [[package]] @@ -799,15 +801,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" -[[package]] -name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg", -] - [[package]] name = "memoffset" version = "0.7.1" @@ -848,18 +841,6 @@ dependencies = [ "void", ] -[[package]] -name = "nix" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" -dependencies = [ - "bitflags", - "cfg-if 1.0.0", - "libc", - "memoffset 0.6.5", -] - [[package]] name = "nix" version = "0.26.2" @@ -869,7 +850,7 @@ dependencies = [ "bitflags", "cfg-if 1.0.0", "libc", - "memoffset 0.7.1", + "memoffset", "pin-utils", "static_assertions", ] diff --git a/Cargo.toml b/Cargo.toml index 371af4d74fd..41447a57a20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -84,7 +84,8 @@ version = "2.3.0" optional = true [dependencies.devicemapper] -version = "0.32.3" +git = "https://github.com/jbaublitz/devicemapper-rs" +branch = "stratisd-metadata-rework" optional = true [dependencies.dbus] diff --git a/src/engine/strat_engine/backstore/backstore.rs b/src/engine/strat_engine/backstore/backstore.rs index 5823b25ba93..049e402ee92 100644 --- a/src/engine/strat_engine/backstore/backstore.rs +++ b/src/engine/strat_engine/backstore/backstore.rs @@ -10,7 +10,10 @@ use chrono::{DateTime, Utc}; use serde_json::Value; use tempfile::TempDir; -use devicemapper::{CacheDev, Device, DmDevice, LinearDev, Sectors}; +use devicemapper::{ + CacheDev, CacheDevTargetTable, CacheTargetParams, DevId, Device, DmDevice, DmFlags, DmOptions, + LinearDev, LinearDevTargetParams, LinearTargetParams, Sectors, TargetLine, TargetTable, +}; use crate::{ engine::{ @@ -52,6 +55,7 @@ fn make_cache( pool_uuid: PoolUuid, cache_tier: &CacheTier, origin: LinearDev, + cap: Option, new: bool, ) -> StratisResult { let (dm_name, dm_uuid) = format_backstore_ids(pool_uuid, CacheRole::MetaSub); @@ -80,6 +84,32 @@ fn make_cache( )?; let (dm_name, dm_uuid) = format_backstore_ids(pool_uuid, CacheRole::Cache); + if cap.is_some() { + let dm = get_dm(); + dm.device_suspend( + &DevId::Name(&dm_name), + DmOptions::default().set_flags(DmFlags::DM_SUSPEND), + )?; + let table = CacheDevTargetTable::new( + Sectors(0), + origin.size(), + CacheTargetParams::new( + meta.device(), + cache.device(), + origin.device(), + CACHE_BLOCK_SIZE, + vec!["writethrough".into()], + "default".to_owned(), + Vec::new(), + ), + ); + dm.table_load( + &DevId::Name(&dm_name), + &table.to_raw_table(), + DmOptions::default(), + )?; + dm.device_suspend(&DevId::Name(&dm_name), DmOptions::default())?; + }; Ok(CacheDev::setup( get_dm(), &dm_name, @@ -91,6 +121,18 @@ fn make_cache( )?) } +/// Set up the linear device on top of the data tier that can later be converted to a +/// cache device and serves as a placeholder for the device beneath encryption. +fn make_cap_linear_dev(pool_uuid: PoolUuid, origin: &LinearDev) -> Result { + let (dm_name, dm_uuid) = format_backstore_ids(pool_uuid, CacheRole::Cache); + let target = vec![TargetLine::new( + Sectors(0), + origin.size(), + LinearDevTargetParams::Linear(LinearTargetParams::new(origin.device(), Sectors(0))), + )]; + LinearDev::setup(get_dm(), &dm_name, Some(&dm_uuid), target).map_err(StratisError::from) +} + /// This structure can allocate additional space to the upper layer, but it /// cannot accept returned space. When it is extended to be able to accept /// returned space the allocation algorithm will have to be revised. @@ -105,6 +147,8 @@ pub struct Backstore { data_tier: DataTier, /// A linear DM device. linear: Option, + /// A placeholder device to be converted to cache. + cap_linear: Option, /// Index for managing allocation of cap device next: Sectors, } @@ -162,7 +206,7 @@ impl Backstore { } }; - let (cache_tier, cache, origin) = if !cachedevs.is_empty() { + let (cap_linear, cache_tier, cache, origin) = if !cachedevs.is_empty() { let block_mgr = BlockDevMgr::new(cachedevs, Some(last_update_time)); match backstore_save.cache_tier { Some(ref cache_tier_save) => { @@ -174,7 +218,8 @@ impl Backstore { } }; - let cache_device = match make_cache(pool_uuid, &cache_tier, origin, false) { + let cache_device = match make_cache(pool_uuid, &cache_tier, origin, None, false) + { Ok(cd) => cd, Err(e) => { return Err(( @@ -188,7 +233,7 @@ impl Backstore { )); } }; - (Some(cache_tier), Some(cache_device), None) + (None, Some(cache_tier), Some(cache_device), None) } None => { let err_msg = "Cachedevs exist, but cache metadata does not exist"; @@ -204,7 +249,11 @@ impl Backstore { } } } else { - (None, None, Some(origin)) + let cap_linear = match make_cap_linear_dev(pool_uuid, &origin) { + Ok(cap) => cap, + Err(e) => return Err((e, data_tier.block_mgr.into_bdas())), + }; + (Some(cap_linear), None, None, Some(origin)) }; Ok(Backstore { @@ -212,6 +261,7 @@ impl Backstore { cache_tier, linear: origin, cache, + cap_linear, next: backstore_save.cap.allocs[0].1, }) } @@ -245,6 +295,7 @@ impl Backstore { cache_tier: None, linear: None, cache: None, + cap_linear: None, next: Sectors(0), }) } @@ -287,8 +338,11 @@ impl Backstore { let linear = self.linear .take() .expect("some space has already been allocated from the backstore => (cache_tier.is_none() <=> self.linear.is_some())"); + let cap = self.cap_linear + .take() + .expect("some space has already been allocated from the backstore => (cache_tier.is_none() <=> self.cap_linear.is_some())"); - let cache = make_cache(pool_uuid, &cache_tier, linear, true)?; + let cache = make_cache(pool_uuid, &cache_tier, linear, Some(cap), true)?; self.cache = Some(cache); @@ -369,7 +423,7 @@ impl Backstore { /// device if it does not already exist. Return an error if DM /// operations fail. Use all segments currently allocated in the data tier. fn extend_cap_device(&mut self, pool_uuid: PoolUuid) -> StratisResult<()> { - let create = match (self.cache.as_mut(), self.linear.as_mut()) { + let create = match (self.cache.as_mut(), self.cap_linear.as_mut()) { (None, None) => true, (Some(cache), None) => { let table = self.data_tier.segments.map_to_dm(); @@ -390,7 +444,9 @@ impl Backstore { let table = self.data_tier.segments.map_to_dm(); let (dm_name, dm_uuid) = format_backstore_ids(pool_uuid, CacheRole::OriginSub); let origin = LinearDev::setup(get_dm(), &dm_name, Some(&dm_uuid), table)?; + let cap = make_cap_linear_dev(pool_uuid, &origin)?; self.linear = Some(origin); + self.cap_linear = Some(cap); } Ok(()) @@ -613,7 +669,7 @@ impl Backstore { self.cache .as_ref() .map(|d| d.device()) - .or_else(|| self.linear.as_ref().map(|d| d.device())) + .or_else(|| self.cap_linear.as_ref().map(|d| d.device())) } /// Lookup an immutable blockdev by its Stratis UUID.