Skip to content

Commit

Permalink
Placeholder LinearDev to be converted to CacheDev
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jbaublitz committed Mar 10, 2023
1 parent 77fa3d0 commit ffbb713
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 40 deletions.
43 changes: 12 additions & 31 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
72 changes: 64 additions & 8 deletions src/engine/strat_engine/backstore/backstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -52,6 +55,7 @@ fn make_cache(
pool_uuid: PoolUuid,
cache_tier: &CacheTier,
origin: LinearDev,
cap: Option<LinearDev>,
new: bool,
) -> StratisResult<CacheDev> {
let (dm_name, dm_uuid) = format_backstore_ids(pool_uuid, CacheRole::MetaSub);
Expand Down Expand Up @@ -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,
Expand All @@ -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<LinearDev, StratisError> {
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.
Expand All @@ -105,6 +147,8 @@ pub struct Backstore {
data_tier: DataTier,
/// A linear DM device.
linear: Option<LinearDev>,
/// A placeholder device to be converted to cache.
cap_linear: Option<LinearDev>,
/// Index for managing allocation of cap device
next: Sectors,
}
Expand Down Expand Up @@ -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) => {
Expand All @@ -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((
Expand All @@ -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";
Expand All @@ -204,14 +249,19 @@ 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 {
data_tier,
cache_tier,
linear: origin,
cache,
cap_linear,
next: backstore_save.cap.allocs[0].1,
})
}
Expand Down Expand Up @@ -245,6 +295,7 @@ impl Backstore {
cache_tier: None,
linear: None,
cache: None,
cap_linear: None,
next: Sectors(0),
})
}
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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();
Expand All @@ -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(())
Expand Down Expand Up @@ -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.
Expand Down
3 changes: 3 additions & 0 deletions src/engine/types/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ impl fmt::Display for EncryptionInfo {
// serves no obvious purpose to stringify it and then hash it.
// Necessary Hash Property: \forall x_1, x_2 in EncryptionInfo,
// if x_1 == x_2, then hash(x_1) == hash(x_2) obviously holds.
#[allow(unknown_lints)]
#[allow(renamed_and_removed_lints)]
#[allow(clippy::derive_hash_xor_eq)]
#[allow(clippy::derived_hash_with_manual_eq)]
impl Hash for EncryptionInfo {
fn hash<H: Hasher>(&self, state: &mut H) {
self.key_description().hash(state);
Expand Down

0 comments on commit ffbb713

Please sign in to comment.