Skip to content

Commit

Permalink
Merge pull request #3656 from mulkieran/debug-filesystem-metadata
Browse files Browse the repository at this point in the history
Add D-Bus method to get filesystem metadata
  • Loading branch information
mulkieran authored Aug 2, 2024
2 parents 6920703 + b2e1777 commit 7f16aac
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/dbus_api/pool/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ pub fn create_dbus_pool<'a>(
.add_m(pool_3_0::rename_method(&f))
.add_m(pool_3_3::grow_physical_device_method(&f))
.add_m(pool_3_7::get_metadata_method(&f))
.add_m(pool_3_7::get_fs_metadata_method(&f))
.add_p(pool_3_0::name_property(&f))
.add_p(pool_3_0::uuid_property(&f))
.add_p(pool_3_0::encrypted_property(&f))
Expand Down
15 changes: 14 additions & 1 deletion src/dbus_api/pool/pool_3_7/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use dbus_tree::{Access, EmitsChangedSignal, Factory, MTSync, Method, Property};
use crate::dbus_api::{
consts,
pool::pool_3_7::{
methods::{destroy_filesystems, metadata},
methods::{destroy_filesystems, fs_metadata, metadata},
props::get_pool_metadata_version,
},
types::TData,
Expand Down Expand Up @@ -47,3 +47,16 @@ pub fn metadata_version_property(
.emits_changed(EmitsChangedSignal::Const)
.on_get(get_pool_metadata_version)
}

pub fn get_fs_metadata_method(f: &Factory<MTSync<TData>, TData>) -> Method<MTSync<TData>, TData> {
f.method("FilesystemMetadata", (), fs_metadata)
.in_arg(("fs_name", "(bs)"))
.in_arg(("current", "b"))
// A string representing the pool's filesystem metadata in serialized
// JSON format.
//
// Rust representation: String
.out_arg(("results", "s"))
.out_arg(("return_code", "q"))
.out_arg(("return_string", "s"))
}
46 changes: 45 additions & 1 deletion src/dbus_api/pool/pool_3_7/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
dbus_api::{
consts::filesystem_interface_list,
types::{DbusErrorEnum, TData, OK_STRING},
util::{engine_to_dbus_err_tuple, get_next_arg},
util::{engine_to_dbus_err_tuple, get_next_arg, tuple_to_option},
},
engine::{EngineAction, FilesystemUuid, StratisUuid},
};
Expand Down Expand Up @@ -148,3 +148,47 @@ pub fn metadata(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodResult {
};
Ok(vec![msg])
}

pub fn fs_metadata(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodResult {
let default_return = String::new();

let message: &Message = m.msg;

let return_message = message.method_return();

let dbus_context = m.tree.get_data();
let object_path = m.path.get_name();

let pool_path = m
.tree
.get(object_path)
.expect("implicit argument must be in tree");
let pool_uuid = typed_uuid!(
get_data!(pool_path; default_return; return_message).uuid;
Pool;
default_return;
return_message
);

let mut iter = message.iter_init();
let filesystem_name: Option<&str> = tuple_to_option(get_next_arg(&mut iter, 0)?);
let current: bool = get_next_arg(&mut iter, 1)?;

let guard = get_pool!(dbus_context.engine; pool_uuid; default_return; return_message);
let (_, _, pool) = guard.as_tuple();

let result = if current {
pool.current_fs_metadata(filesystem_name)
} else {
pool.last_fs_metadata(filesystem_name)
};

let msg = match result {
Ok(v) => return_message.append3(v, DbusErrorEnum::OK as u16, OK_STRING.to_string()),
Err(err) => {
let (rc, rs) = engine_to_dbus_err_tuple(&err);
return_message.append3(default_return, rc, rs)
}
};
Ok(vec![msg])
}
5 changes: 4 additions & 1 deletion src/dbus_api/pool/pool_3_7/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ mod api;
mod methods;
mod props;

pub use api::{destroy_filesystems_method, get_metadata_method, metadata_version_property};
pub use api::{
destroy_filesystems_method, get_fs_metadata_method, get_metadata_method,
metadata_version_property,
};
6 changes: 6 additions & 0 deletions src/engine/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,12 @@ pub trait Pool: Debug + Send + Sync {

/// Get the metadata version for a given pool.
fn metadata_version(&self) -> StratSigblockVersion;

/// Get the filesystem metadata that would be written if written now.
fn current_fs_metadata(&self, fs_name: Option<&str>) -> StratisResult<String>;

/// Get the last written filesystem metadata.
fn last_fs_metadata(&self, fs_name: Option<&str>) -> StratisResult<String>;
}

pub type HandleEvents<P> = (
Expand Down
28 changes: 27 additions & 1 deletion src/engine/sim_engine/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,25 @@ use serde_json::{Map, Value};
use devicemapper::{Bytes, Sectors};

use crate::{
engine::{types::FilesystemUuid, Filesystem},
engine::{
types::{FilesystemUuid, Name},
Filesystem,
},
stratis::{StratisError, StratisResult},
};

#[derive(Debug, Eq, PartialEq, Serialize)]
pub struct FilesystemSave {
name: String,
uuid: FilesystemUuid,
size: Sectors,
created: u64,
#[serde(skip_serializing_if = "Option::is_none")]
fs_size_limit: Option<Sectors>,
#[serde(skip_serializing_if = "Option::is_none")]
origin: Option<FilesystemUuid>,
}

#[derive(Debug)]
pub struct SimFilesystem {
rand: u32,
Expand Down Expand Up @@ -73,6 +88,17 @@ impl SimFilesystem {
self.origin = None;
changed
}

pub fn record(&self, name: &Name, uuid: FilesystemUuid) -> FilesystemSave {
FilesystemSave {
name: name.to_owned(),
uuid,
size: self.size,
created: self.created.timestamp() as u64,
fs_size_limit: self.size_limit,
origin: self.origin,
}
}
}

impl Filesystem for SimFilesystem {
Expand Down
23 changes: 23 additions & 0 deletions src/engine/sim_engine/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,29 @@ impl Pool for SimPool {
fn metadata_version(&self) -> StratSigblockVersion {
StratSigblockVersion::V2
}

fn current_fs_metadata(&self, fs_name: Option<&str>) -> StratisResult<String> {
serde_json::to_string(
&self
.filesystems
.iter()
.filter_map(|(name, uuid, fs)| {
if fs_name.map(|n| *n == **name).unwrap_or(true) {
Some((uuid, fs.record(name, *uuid)))
} else {
None
}
})
.collect::<HashMap<_, _>>(),
)
.map_err(|e| e.into())
}

fn last_fs_metadata(&self, fs_name: Option<&str>) -> StratisResult<String> {
// The sim pool doesn't write data, so the last fs metadata and the
// current fs metadata are, by definition, the same.
self.current_fs_metadata(fs_name)
}
}

#[cfg(test)]
Expand Down
14 changes: 14 additions & 0 deletions src/engine/strat_engine/pool/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,4 +348,18 @@ impl Pool for AnyPool {
AnyPool::V2(p) => p.metadata_version(),
}
}

fn current_fs_metadata(&self, fs_name: Option<&str>) -> StratisResult<String> {
match self {
AnyPool::V1(p) => p.current_fs_metadata(fs_name),
AnyPool::V2(p) => p.current_fs_metadata(fs_name),
}
}

fn last_fs_metadata(&self, fs_name: Option<&str>) -> StratisResult<String> {
match self {
AnyPool::V1(p) => p.last_fs_metadata(fs_name),
AnyPool::V2(p) => p.last_fs_metadata(fs_name),
}
}
}
8 changes: 8 additions & 0 deletions src/engine/strat_engine/pool/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1293,6 +1293,14 @@ impl Pool for StratPool {
fn metadata_version(&self) -> StratSigblockVersion {
StratSigblockVersion::V1
}

fn current_fs_metadata(&self, fs_name: Option<&str>) -> StratisResult<String> {
self.thin_pool.current_fs_metadata(fs_name)
}

fn last_fs_metadata(&self, fs_name: Option<&str>) -> StratisResult<String> {
self.thin_pool.last_fs_metadata(fs_name)
}
}

pub struct StratPoolState {
Expand Down
8 changes: 8 additions & 0 deletions src/engine/strat_engine/pool/v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1200,6 +1200,14 @@ impl Pool for StratPool {
fn metadata_version(&self) -> StratSigblockVersion {
StratSigblockVersion::V2
}

fn current_fs_metadata(&self, fs_name: Option<&str>) -> StratisResult<String> {
self.thin_pool.current_fs_metadata(fs_name)
}

fn last_fs_metadata(&self, fs_name: Option<&str>) -> StratisResult<String> {
self.thin_pool.last_fs_metadata(fs_name)
}
}

pub struct StratPoolState {
Expand Down
37 changes: 37 additions & 0 deletions src/engine/strat_engine/thinpool/thinpool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,43 @@ impl<B> ThinPool<B> {
pub fn clear_out_of_meta_flag(&mut self) {
self.out_of_meta_space = false;
}

/// Calculate filesystem metadata from current state
pub fn current_fs_metadata(&self, fs_name: Option<&str>) -> StratisResult<String> {
serde_json::to_string(
&self
.filesystems
.iter()
.filter_map(|(name, uuid, fs)| {
if fs_name.map(|n| *n == **name).unwrap_or(true) {
Some((*uuid, fs.record(name, *uuid)))
} else {
None
}
})
.collect::<HashMap<_, _>>(),
)
.map_err(|e| e.into())
}

/// Read filesystem metadata from mdv
pub fn last_fs_metadata(&self, fs_name: Option<&str>) -> StratisResult<String> {
serde_json::to_string(
&self
.mdv
.filesystems()?
.iter()
.filter_map(|fssave| {
if fs_name.map(|n| *n == fssave.name).unwrap_or(true) {
Some((fssave.uuid, fssave))
} else {
None
}
})
.collect::<HashMap<_, _>>(),
)
.map_err(|e| e.into())
}
}

impl ThinPool<v1::Backstore> {
Expand Down
7 changes: 7 additions & 0 deletions tests/client-dbus/src/stratisd_client_dbus/_introspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,13 @@
<arg name="return_code" type="q" direction="out" />
<arg name="return_string" type="s" direction="out" />
</method>
<method name="FilesystemMetadata">
<arg name="fs_name" type="(bs)" direction="in" />
<arg name="current" type="b" direction="in" />
<arg name="results" type="s" direction="out" />
<arg name="return_code" type="q" direction="out" />
<arg name="return_string" type="s" direction="out" />
</method>
<method name="GrowPhysicalDevice">
<arg name="dev" type="s" direction="in" />
<arg name="results" type="b" direction="out" />
Expand Down

0 comments on commit 7f16aac

Please sign in to comment.