-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add abstraction layer for block devices
- Loading branch information
Showing
8 changed files
with
394 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
mod shared; | ||
pub mod v1; | ||
|
||
pub use shared::StratBlockDev; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<String>, | ||
hardware_info: Option<String>, | ||
underlying_device: UnderlyingDevice, | ||
blksizes: BlockSizes, | ||
) -> BDAResult<StratBlockDev> { | ||
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<Utc>, 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<PerDevSegments> { | ||
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<Option<&Name>> { | ||
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<Option<Sectors>> { | ||
match self { | ||
StratBlockDev::V1(bd) => bd.calc_new_size(), | ||
} | ||
} | ||
|
||
pub fn scan_blkdev_size_v1(physical_path: &Path, is_encrypted: bool) -> StratisResult<Sectors> { | ||
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<bool> { | ||
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<Utc> { | ||
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<Sectors> { | ||
match self { | ||
StratBlockDev::V1(bd) => bd.new_size(), | ||
} | ||
} | ||
} | ||
|
||
impl<'a> Into<Value> for &'a StratBlockDev { | ||
fn into(self) -> Value { | ||
match self { | ||
StratBlockDev::V1(bd) => bd.into(), | ||
} | ||
} | ||
} | ||
|
||
impl Recordable<BaseBlockDevSave> for StratBlockDev { | ||
fn record(&self) -> BaseBlockDevSave { | ||
match self { | ||
StratBlockDev::V1(bd) => bd.record(), | ||
} | ||
} | ||
} | ||
|
||
pub struct StratBlockDevState { | ||
pub(super) new_size: Option<Sectors>, | ||
} | ||
|
||
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), | ||
} | ||
} | ||
} |
Oops, something went wrong.