Skip to content

Commit 78b9fa8

Browse files
committed
Add interface to set up up linear subdevices for integrity
1 parent bdbb74c commit 78b9fa8

File tree

4 files changed

+142
-2
lines changed

4 files changed

+142
-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: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
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+
type IntegritySegments = (
24+
HashMap<Device, Vec<(Sectors, Sectors)>>,
25+
HashMap<Device, Vec<(Sectors, Sectors)>>,
26+
);
27+
28+
/// Generate a better format for the integrity data and metadata segments when setting up the
29+
/// linear devices.
30+
#[allow(dead_code)]
31+
fn generate_segments_from_metadata(
32+
data_tier: DataTier<StratBlockDev>,
33+
) -> StratisResult<IntegritySegments> {
34+
let data_segments = data_tier
35+
.segments
36+
.inner
37+
.iter()
38+
.try_fold::<_, _, StratisResult<_>>(
39+
HashMap::new(),
40+
|mut hash: HashMap<_, Vec<(Sectors, Sectors)>>, seg| {
41+
let (_, blockdev) = data_tier.get_blockdev_by_uuid(seg.uuid).ok_or_else(|| {
42+
StratisError::Msg(format!(
43+
"No record of device with UUID {} found in active block device manager",
44+
seg.uuid
45+
))
46+
})?;
47+
match hash.entry(*blockdev.device()) {
48+
Entry::Occupied(mut entry) => {
49+
entry
50+
.get_mut()
51+
.push((seg.segment.start, seg.segment.length));
52+
}
53+
Entry::Vacant(entry) => {
54+
entry.insert(vec![(seg.segment.start, seg.segment.length)]);
55+
}
56+
};
57+
Ok(hash)
58+
},
59+
)?;
60+
61+
let meta_segments = data_tier.blockdevs().into_iter().fold(
62+
HashMap::new(),
63+
|mut hash: HashMap<_, Vec<(Sectors, Sectors)>>, (_, bd)| {
64+
match hash.entry(*bd.device()) {
65+
Entry::Occupied(mut entry) => entry.get_mut().extend(bd.meta_allocs()),
66+
Entry::Vacant(entry) => {
67+
entry.insert(bd.meta_allocs());
68+
}
69+
};
70+
hash
71+
},
72+
);
73+
74+
Ok((data_segments, meta_segments))
75+
}
76+
77+
/// Set up a linear device to be used as an integrity subdevice from a record of allocations in the
78+
/// metadata.
79+
fn setup_linear_dev(
80+
pool_uuid: PoolUuid,
81+
devno: Device,
82+
role: IntegrityRole,
83+
info: &HashMap<Device, Vec<(Sectors, Sectors)>>,
84+
) -> StratisResult<LinearDev> {
85+
let (name, uuid) = format_integrity_ids(pool_uuid, role);
86+
let (_, linear_table) = info
87+
.get(&devno)
88+
.ok_or_else(|| {
89+
StratisError::Msg(format!(
90+
"Failed to find a record of allocations for device number {devno}"
91+
))
92+
})?
93+
.iter()
94+
.fold(
95+
(Sectors(0), Vec::new()),
96+
|(mut offset, mut vec), (start, length)| {
97+
vec.push(TargetLine::new(
98+
offset,
99+
*length,
100+
LinearDevTargetParams::Linear(LinearTargetParams::new(devno, *start)),
101+
));
102+
offset += *length;
103+
(offset, vec)
104+
},
105+
);
106+
LinearDev::setup(get_dm(), &name, Some(&uuid), linear_table).map_err(StratisError::from)
107+
}
108+
109+
/// Represents a handle to the integrity layer of the devicemapper stack.
110+
#[allow(dead_code)]
111+
pub struct IntegrityLayer {
112+
data: LinearDev,
113+
meta: LinearDev,
114+
}
115+
116+
impl IntegrityLayer {
117+
/// Initialize the integrity layer for a pool.
118+
#[allow(dead_code)]
119+
fn initialize(
120+
pool_uuid: PoolUuid,
121+
devno: Device,
122+
data_segments: &HashMap<Device, Vec<(Sectors, Sectors)>>,
123+
metadata_segments: &HashMap<Device, Vec<(Sectors, Sectors)>>,
124+
) -> StratisResult<Self> {
125+
let data_dev = setup_linear_dev(pool_uuid, devno, IntegrityRole::OriginSub, data_segments)?;
126+
127+
let meta_dev =
128+
setup_linear_dev(pool_uuid, devno, IntegrityRole::MetaSub, metadata_segments)?;
129+
130+
Ok(IntegrityLayer {
131+
data: data_dev,
132+
meta: meta_dev,
133+
})
134+
}
135+
}

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)