diff --git a/src/engine/strat_engine/backstore/blockdev/mod.rs b/src/engine/strat_engine/backstore/blockdev/mod.rs new file mode 100644 index 00000000000..0d14458526a --- /dev/null +++ b/src/engine/strat_engine/backstore/blockdev/mod.rs @@ -0,0 +1,4 @@ +mod shared; +pub mod v1; + +pub use shared::StratBlockDev; diff --git a/src/engine/strat_engine/backstore/blockdev/shared.rs b/src/engine/strat_engine/backstore/blockdev/shared.rs new file mode 100644 index 00000000000..d9cdae5edc2 --- /dev/null +++ b/src/engine/strat_engine/backstore/blockdev/shared.rs @@ -0,0 +1,372 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +use std::path::Path; + +use chrono::{DateTime, Utc}; +use serde_json::Value; + +use devicemapper::{Device, Sectors}; + +use crate::{ + engine::{ + engine::{BlockDev, DumpState}, + strat_engine::{ + backstore::{ + blockdev::v1::{self, UnderlyingDevice}, + devices::BlockSizes, + range_alloc::PerDevSegments, + transaction::RequestTransaction, + }, + metadata::{BDAExtendedSize, BlockdevSize, MDADataSize, BDA}, + serde_structs::{BaseBlockDevSave, Recordable}, + types::BDAResult, + }, + types::{ + Compare, DevUuid, Diff, EncryptionInfo, KeyDescription, Name, PoolUuid, StateDiff, + StratBlockDevDiff, + }, + }, + stratis::StratisResult, +}; + +#[derive(Debug)] +pub enum StratBlockDev { + V1(v1::StratBlockDev), +} + +impl StratBlockDev { + pub fn new_v1( + dev: Device, + bda: BDA, + other_segments: &[(Sectors, Sectors)], + user_info: Option, + hardware_info: Option, + underlying_device: UnderlyingDevice, + blksizes: BlockSizes, + ) -> BDAResult { + v1::StratBlockDev::new( + dev, + bda, + other_segments, + user_info, + hardware_info, + underlying_device, + blksizes, + ) + .map(StratBlockDev::V1) + } + + pub fn device(&self) -> &Device { + match self { + StratBlockDev::V1(bd) => bd.device(), + } + } + + pub fn luks_device(&self) -> Option<&Device> { + match self { + StratBlockDev::V1(bd) => bd.luks_device(), + } + } + + pub fn physical_path(&self) -> &Path { + match self { + StratBlockDev::V1(bd) => bd.physical_path(), + } + } + + pub fn metadata_path(&self) -> &Path { + match self { + StratBlockDev::V1(bd) => bd.metadata_path(), + } + } + + pub fn disown(&mut self) -> StratisResult<()> { + match self { + StratBlockDev::V1(bd) => bd.disown(), + } + } + + pub fn save_state(&mut self, time: &DateTime, metadata: &[u8]) -> StratisResult<()> { + match self { + StratBlockDev::V1(bd) => bd.save_state(time, metadata), + } + } + + /// The pool's UUID. + pub fn pool_uuid(&self) -> PoolUuid { + match self { + StratBlockDev::V1(bd) => bd.pool_uuid(), + } + } + + pub fn uuid(&self) -> DevUuid { + match self { + StratBlockDev::V1(bd) => bd.uuid(), + } + } + + pub fn request_space( + &self, + size: Sectors, + transaction: &RequestTransaction, + ) -> StratisResult { + match self { + StratBlockDev::V1(bd) => bd.request_space(size, transaction), + } + } + + pub fn commit_space(&mut self, segs: PerDevSegments) { + match self { + StratBlockDev::V1(bd) => bd.commit_space(segs), + } + } + + pub fn metadata_size(&self) -> BDAExtendedSize { + match self { + StratBlockDev::V1(bd) => bd.metadata_size(), + } + } + + pub fn available(&self) -> Sectors { + match self { + StratBlockDev::V1(bd) => bd.available(), + } + } + + pub fn total_size(&self) -> BlockdevSize { + match self { + StratBlockDev::V1(bd) => bd.total_size(), + } + } + + pub fn max_metadata_size(&self) -> MDADataSize { + match self { + StratBlockDev::V1(bd) => bd.max_metadata_size(), + } + } + + pub fn in_use(&self) -> bool { + match self { + StratBlockDev::V1(bd) => bd.in_use(), + } + } + + pub fn set_user_info(&mut self, user_info: Option<&str>) -> bool { + match self { + StratBlockDev::V1(bd) => bd.set_user_info(user_info), + } + } + + pub fn devnode(&self) -> &Path { + match self { + StratBlockDev::V1(bd) => bd.devnode(), + } + } + + pub fn encryption_info(&self) -> Option<&EncryptionInfo> { + match self { + StratBlockDev::V1(bd) => bd.encryption_info(), + } + } + + #[allow(clippy::option_option)] + pub fn pool_name(&self) -> Option> { + match self { + StratBlockDev::V1(bd) => bd.pool_name(), + } + } + + pub fn blksizes(&self) -> BlockSizes { + match self { + StratBlockDev::V1(bd) => bd.blksizes(), + } + } + + pub fn bind_clevis(&mut self, pin: &str, clevis_info: &Value) -> StratisResult<()> { + match self { + StratBlockDev::V1(bd) => bd.bind_clevis(pin, clevis_info), + } + } + + pub fn unbind_clevis(&mut self) -> StratisResult<()> { + match self { + StratBlockDev::V1(bd) => bd.unbind_clevis(), + } + } + + pub fn bind_keyring(&mut self, key_desc: &KeyDescription) -> StratisResult<()> { + match self { + StratBlockDev::V1(bd) => bd.bind_keyring(key_desc), + } + } + + pub fn unbind_keyring(&mut self) -> StratisResult<()> { + match self { + StratBlockDev::V1(bd) => bd.unbind_keyring(), + } + } + + pub fn rebind_keyring(&mut self, key_desc: &KeyDescription) -> StratisResult<()> { + match self { + StratBlockDev::V1(bd) => bd.rebind_keyring(key_desc), + } + } + + pub fn rebind_clevis(&mut self) -> StratisResult<()> { + match self { + StratBlockDev::V1(bd) => bd.rebind_clevis(), + } + } + + pub fn calc_new_size(&self) -> StratisResult> { + match self { + StratBlockDev::V1(bd) => bd.calc_new_size(), + } + } + + pub fn scan_blkdev_size_v1(physical_path: &Path, is_encrypted: bool) -> StratisResult { + v1::StratBlockDev::scan_blkdev_size(physical_path, is_encrypted) + } + + pub fn set_new_size(&mut self, new_size: Sectors) { + match self { + StratBlockDev::V1(bd) => bd.set_new_size(new_size), + } + } + + pub fn grow(&mut self) -> StratisResult { + match self { + StratBlockDev::V1(bd) => bd.grow(), + } + } + + pub fn rename_pool(&mut self, pool_name: Name) -> StratisResult<()> { + match self { + StratBlockDev::V1(bd) => bd.rename_pool(pool_name), + } + } + + pub fn teardown(&mut self) -> StratisResult<()> { + match self { + StratBlockDev::V1(bd) => bd.teardown(), + } + } + + pub fn into_bda(self) -> BDA { + match self { + StratBlockDev::V1(bd) => bd.into_bda(), + } + } + + #[cfg(test)] + pub fn invariant(&self) { + match self { + StratBlockDev::V1(bd) => bd.invariant(), + } + } +} + +impl BlockDev for StratBlockDev { + fn devnode(&self) -> &Path { + match self { + StratBlockDev::V1(bd) => bd.devnode(), + } + } + + fn metadata_path(&self) -> &Path { + match self { + StratBlockDev::V1(bd) => bd.metadata_path(), + } + } + + fn user_info(&self) -> Option<&str> { + match self { + StratBlockDev::V1(bd) => bd.user_info(), + } + } + + fn hardware_info(&self) -> Option<&str> { + match self { + StratBlockDev::V1(bd) => bd.hardware_info(), + } + } + + fn initialization_time(&self) -> DateTime { + match self { + StratBlockDev::V1(bd) => bd.initialization_time(), + } + } + + fn size(&self) -> Sectors { + match self { + StratBlockDev::V1(bd) => bd.size(), + } + } + + fn is_encrypted(&self) -> bool { + match self { + StratBlockDev::V1(bd) => bd.is_encrypted(), + } + } + + fn new_size(&self) -> Option { + match self { + StratBlockDev::V1(bd) => bd.new_size(), + } + } +} + +impl<'a> Into for &'a StratBlockDev { + fn into(self) -> Value { + match self { + StratBlockDev::V1(bd) => bd.into(), + } + } +} + +impl Recordable for StratBlockDev { + fn record(&self) -> BaseBlockDevSave { + match self { + StratBlockDev::V1(bd) => bd.record(), + } + } +} + +pub struct StratBlockDevState { + pub(super) new_size: Option, +} + +impl StateDiff for StratBlockDevState { + type Diff = StratBlockDevDiff; + + fn diff(&self, new_state: &Self) -> Self::Diff { + StratBlockDevDiff { + size: self.new_size.compare(&new_state.new_size), + } + } + + fn unchanged(&self) -> Self::Diff { + StratBlockDevDiff { + size: Diff::Unchanged(self.new_size), + } + } +} + +impl<'a> DumpState<'a> for StratBlockDev { + type State = StratBlockDevState; + type DumpInput = Sectors; + + fn cached(&self) -> Self::State { + match self { + StratBlockDev::V1(bd) => bd.cached(), + } + } + + fn dump(&mut self, input: Self::DumpInput) -> Self::State { + match self { + StratBlockDev::V1(bd) => bd.dump(input), + } + } +} diff --git a/src/engine/strat_engine/backstore/blockdev.rs b/src/engine/strat_engine/backstore/blockdev/v1.rs similarity index 97% rename from src/engine/strat_engine/backstore/blockdev.rs rename to src/engine/strat_engine/backstore/blockdev/v1.rs index c56e6764f7c..d3eb23f2fb7 100644 --- a/src/engine/strat_engine/backstore/blockdev.rs +++ b/src/engine/strat_engine/backstore/blockdev/v1.rs @@ -21,6 +21,7 @@ use crate::{ engine::{BlockDev, DumpState}, strat_engine::{ backstore::{ + blockdev::shared::StratBlockDevState, crypt::CryptHandle, devices::BlockSizes, range_alloc::{PerDevSegments, RangeAllocator}, @@ -34,10 +35,7 @@ use crate::{ serde_structs::{BaseBlockDevSave, Recordable}, types::BDAResult, }, - types::{ - Compare, DevUuid, DevicePath, Diff, EncryptionInfo, KeyDescription, Name, PoolUuid, - StateDiff, StratBlockDevDiff, - }, + types::{DevUuid, DevicePath, EncryptionInfo, KeyDescription, Name, PoolUuid}, }, stratis::{StratisError, StratisResult}, }; @@ -81,7 +79,7 @@ impl UnderlyingDevice { #[derive(Debug)] pub struct StratBlockDev { dev: Device, - pub(in super::super) bda: BDA, + bda: BDA, used: RangeAllocator, user_info: Option, hardware_info: Option, @@ -504,6 +502,11 @@ impl StratBlockDev { Ok(()) } } + + /// Convert block device into BDA record. + pub fn into_bda(self) -> BDA { + self.bda + } } impl<'a> Into for &'a StratBlockDev { @@ -582,26 +585,6 @@ impl Recordable for StratBlockDev { } } -pub struct StratBlockDevState { - new_size: Option, -} - -impl StateDiff for StratBlockDevState { - type Diff = StratBlockDevDiff; - - fn diff(&self, new_state: &Self) -> Self::Diff { - StratBlockDevDiff { - size: self.new_size.compare(&new_state.new_size), - } - } - - fn unchanged(&self) -> Self::Diff { - StratBlockDevDiff { - size: Diff::Unchanged(self.new_size), - } - } -} - impl<'a> DumpState<'a> for StratBlockDev { type State = StratBlockDevState; type DumpInput = Sectors; diff --git a/src/engine/strat_engine/backstore/devices.rs b/src/engine/strat_engine/backstore/devices.rs index 88fb53ad66a..af1bb53988e 100644 --- a/src/engine/strat_engine/backstore/devices.rs +++ b/src/engine/strat_engine/backstore/devices.rs @@ -23,7 +23,7 @@ use crate::{ engine::{ strat_engine::{ backstore::{ - blockdev::{StratBlockDev, UnderlyingDevice}, + blockdev::{v1::UnderlyingDevice, StratBlockDev}, crypt::CryptHandle, }, device::{blkdev_logical_sector_size, blkdev_physical_sector_size, blkdev_size}, @@ -587,7 +587,7 @@ pub fn initialize_devices( bda.initialize(&mut f)?; - StratBlockDev::new(devno, bda, &[], None, hw_id, underlying_device, blksizes) + StratBlockDev::new_v1(devno, bda, &[], None, hw_id, underlying_device, blksizes) .map_err(|(e, _)| e) } diff --git a/src/engine/strat_engine/backstore/mod.rs b/src/engine/strat_engine/backstore/mod.rs index ae51a8d1876..62bd8315335 100644 --- a/src/engine/strat_engine/backstore/mod.rs +++ b/src/engine/strat_engine/backstore/mod.rs @@ -16,7 +16,7 @@ mod transaction; pub use self::{ backstore::Backstore, - blockdev::{StratBlockDev, UnderlyingDevice}, + blockdev::{v1::UnderlyingDevice, StratBlockDev}, crypt::{crypt_metadata_size, set_up_crypt_logging, CryptHandle, CLEVIS_TANG_TRUST_URL}, devices::{ find_stratis_devs_by_uuid, initialize_devices, BlockSizes, ProcessedPathInfos, diff --git a/src/engine/strat_engine/liminal/identify.rs b/src/engine/strat_engine/liminal/identify.rs index 45bbb7c11f4..605335bfe9b 100644 --- a/src/engine/strat_engine/liminal/identify.rs +++ b/src/engine/strat_engine/liminal/identify.rs @@ -195,7 +195,7 @@ impl From for Vec { device_number: *bd.device(), devnode: bd.metadata_path().to_owned(), }, - bda: bd.bda, + bda: bd.into_bda(), })); } } @@ -205,7 +205,7 @@ impl From for Vec { device_number: *bd.device(), devnode: bd.physical_path().to_owned(), }, - bda: bd.bda, + bda: bd.into_bda(), })), (_, _, _) => unreachable!("If bd.is_encrypted(), all are Some(_)"), } diff --git a/src/engine/strat_engine/liminal/setup.rs b/src/engine/strat_engine/liminal/setup.rs index e8080df7669..875e0e28b5c 100644 --- a/src/engine/strat_engine/liminal/setup.rs +++ b/src/engine/strat_engine/liminal/setup.rs @@ -258,7 +258,7 @@ pub fn get_blockdevs( }; Ok(( tier, - StratBlockDev::new( + StratBlockDev::new_v1( info.dev_info.device_number, bda, segments.unwrap_or(&vec![]), diff --git a/src/engine/strat_engine/shared.rs b/src/engine/strat_engine/shared.rs index 403f5e55002..497eeea423f 100644 --- a/src/engine/strat_engine/shared.rs +++ b/src/engine/strat_engine/shared.rs @@ -12,7 +12,10 @@ use crate::engine::{ /// Convert a collection of blockdevs to BDAs. pub fn bds_to_bdas(bds: Vec) -> HashMap { bds.into_iter() - .map(|bd| (bd.bda.dev_uuid(), bd.bda)) + .map(|bd| { + let bda = bd.into_bda(); + (bda.dev_uuid(), bda) + }) .collect() }