Skip to content

Commit

Permalink
Add abstraction layer for block devices
Browse files Browse the repository at this point in the history
  • Loading branch information
jbaublitz committed Apr 10, 2023
1 parent 64caaf4 commit 18c3b73
Show file tree
Hide file tree
Showing 8 changed files with 394 additions and 32 deletions.
4 changes: 4 additions & 0 deletions src/engine/strat_engine/backstore/blockdev/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
mod shared;
pub mod v1;

pub use shared::StratBlockDev;
372 changes: 372 additions & 0 deletions src/engine/strat_engine/backstore/blockdev/shared.rs
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),
}
}
}
Loading

0 comments on commit 18c3b73

Please sign in to comment.