Skip to content

Commit 7754907

Browse files
committed
Add interface to set up up linear subdevices for integrity
1 parent bdcd954 commit 7754907

File tree

4 files changed

+140
-2
lines changed

4 files changed

+140
-2
lines changed

src/engine/strat_engine/backstore/blockdev/v2.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,11 @@ impl StratBlockDev {
187187
&self.devnode
188188
}
189189

190+
/// Return the allocations for integrity metadata on this block device.
191+
pub fn meta_allocs(&self) -> Vec<(Sectors, Sectors)> {
192+
self.integrity_meta_allocs.clone()
193+
}
194+
190195
/// Scan the block device specified by physical_path for its size.
191196
pub fn scan_blkdev_size(physical_path: &Path) -> StratisResult<Sectors> {
192197
Ok(blkdev_size(&File::open(physical_path)?)?.sectors())
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this
3+
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4+
5+
use std::collections::{hash_map::Entry, HashMap};
6+
7+
use devicemapper::{
8+
Device, LinearDev, LinearDevTargetParams, LinearTargetParams, Sectors, TargetLine,
9+
};
10+
11+
use crate::{
12+
engine::{
13+
strat_engine::{
14+
backstore::{blockdev::v2::StratBlockDev, data_tier::DataTier},
15+
dm::get_dm,
16+
names::{format_integrity_ids, IntegrityRole},
17+
},
18+
types::PoolUuid,
19+
},
20+
stratis::{StratisError, StratisResult},
21+
};
22+
23+
/// Generate a better format for the integrity data and metadata segments when setting up the
24+
/// linear devices.
25+
#[allow(dead_code)]
26+
fn generate_segments_from_metadata(
27+
data_tier: DataTier<StratBlockDev>,
28+
) -> StratisResult<(
29+
HashMap<Device, Vec<(Sectors, Sectors)>>,
30+
HashMap<Device, Vec<(Sectors, Sectors)>>,
31+
)> {
32+
let data_segments = data_tier
33+
.segments
34+
.inner
35+
.iter()
36+
.try_fold::<_, _, StratisResult<_>>(
37+
HashMap::new(),
38+
|mut hash: HashMap<_, Vec<(Sectors, Sectors)>>, seg| {
39+
let (_, blockdev) = data_tier.get_blockdev_by_uuid(seg.uuid).ok_or_else(|| {
40+
StratisError::Msg(format!(
41+
"No record of device with UUID {} found in active block device manager",
42+
seg.uuid
43+
))
44+
})?;
45+
match hash.entry(*blockdev.device()) {
46+
Entry::Occupied(mut entry) => {
47+
entry
48+
.get_mut()
49+
.push((seg.segment.start, seg.segment.length));
50+
}
51+
Entry::Vacant(entry) => {
52+
entry.insert(vec![(seg.segment.start, seg.segment.length)]);
53+
}
54+
};
55+
Ok(hash)
56+
},
57+
)?;
58+
59+
let meta_segments = data_tier.blockdevs().into_iter().fold(
60+
HashMap::new(),
61+
|mut hash: HashMap<_, Vec<(Sectors, Sectors)>>, (_, bd)| {
62+
match hash.entry(*bd.device()) {
63+
Entry::Occupied(mut entry) => entry.get_mut().extend(bd.meta_allocs()),
64+
Entry::Vacant(entry) => {
65+
entry.insert(bd.meta_allocs());
66+
}
67+
};
68+
hash
69+
},
70+
);
71+
72+
Ok((data_segments, meta_segments))
73+
}
74+
75+
/// Set up a linear device to be used as an integrity subdevice from a record of allocations in the
76+
/// metadata.
77+
fn setup_linear_dev(
78+
pool_uuid: PoolUuid,
79+
devno: Device,
80+
role: IntegrityRole,
81+
info: &HashMap<Device, Vec<(Sectors, Sectors)>>,
82+
) -> StratisResult<LinearDev> {
83+
let (name, uuid) = format_integrity_ids(pool_uuid, role);
84+
let (_, linear_table) = info
85+
.get(&devno)
86+
.ok_or_else(|| {
87+
StratisError::Msg(format!(
88+
"Failed to find a record of allocations for device number {devno}"
89+
))
90+
})?
91+
.iter()
92+
.fold(
93+
(Sectors(0), Vec::new()),
94+
|(mut offset, mut vec), (start, length)| {
95+
vec.push(TargetLine::new(
96+
offset,
97+
*length,
98+
LinearDevTargetParams::Linear(LinearTargetParams::new(devno, *start)),
99+
));
100+
offset += *length;
101+
(offset, vec)
102+
},
103+
);
104+
LinearDev::setup(get_dm(), &name, Some(&uuid), linear_table).map_err(StratisError::from)
105+
}
106+
107+
/// Represents a handle to the integrity layer of the devicemapper stack.
108+
#[allow(dead_code)]
109+
pub struct IntegrityLayer {
110+
data: LinearDev,
111+
meta: LinearDev,
112+
}
113+
114+
impl IntegrityLayer {
115+
/// Initialize the integrity layer for a pool.
116+
#[allow(dead_code)]
117+
fn initialize(
118+
pool_uuid: PoolUuid,
119+
devno: Device,
120+
data_segments: &HashMap<Device, Vec<(Sectors, Sectors)>>,
121+
metadata_segments: &HashMap<Device, Vec<(Sectors, Sectors)>>,
122+
) -> StratisResult<Self> {
123+
let data_dev = setup_linear_dev(pool_uuid, devno, IntegrityRole::OriginSub, data_segments)?;
124+
125+
let meta_dev =
126+
setup_linear_dev(pool_uuid, devno, IntegrityRole::MetaSub, metadata_segments)?;
127+
128+
Ok(IntegrityLayer {
129+
data: data_dev,
130+
meta: meta_dev,
131+
})
132+
}
133+
}

src/engine/strat_engine/backstore/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod blockdevmgr;
99
mod cache_tier;
1010
mod data_tier;
1111
mod devices;
12+
mod integrity;
1213
mod range_alloc;
1314
mod shared;
1415

src/engine/strat_engine/names.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,9 @@ pub enum CacheRole {
140140
/// The various roles taken on by DM devices in the integrity tier.
141141
#[derive(Clone, Copy, strum_macros::Display)]
142142
#[strum(serialize_all = "lowercase")]
143-
#[allow(dead_code)]
144143
pub enum IntegrityRole {
145144
/// The DM integrity device, contains the other two devices.
145+
#[allow(dead_code)]
146146
Integrity,
147147
/// The meta sub-device of the DM integrity device.
148148
MetaSub,
@@ -261,7 +261,6 @@ pub fn format_backstore_ids(pool_uuid: PoolUuid, role: CacheRole) -> (DmNameBuf,
261261
/// < 128 (129 for UUID)
262262
///
263263
/// which is equivalent to len(format!("{}", FORMAT_VERSION) < 60 (61 for UUID)
264-
#[allow(dead_code)]
265264
pub fn format_integrity_ids(pool_uuid: PoolUuid, role: IntegrityRole) -> (DmNameBuf, DmUuidBuf) {
266265
let value = format!(
267266
"stratis-{}-private-{}-integrity-{}",

0 commit comments

Comments
 (0)