Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add D-Bus method to get filesystem metadata #3656

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading