Skip to content

Commit

Permalink
Merge pull request #3516 from mulkieran/issue_stratisd_3515
Browse files Browse the repository at this point in the history
Add origin field to StratFilesystem
  • Loading branch information
mulkieran authored Feb 26, 2024
2 parents c4c1545 + faa4822 commit fb888f7
Show file tree
Hide file tree
Showing 28 changed files with 441 additions and 27 deletions.
16 changes: 16 additions & 0 deletions src/bin/stratis-min/stratis-min.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ fn parse_args() -> Command {
.arg(Arg::new("pool_name").required(true))
.arg(Arg::new("fs_name").required(true))
.arg(Arg::new("new_fs_name").required(true)),
Command::new("origin")
.arg(Arg::new("pool_name").required(true))
.arg(Arg::new("fs_name").required(true)),
]),
Command::new("report"),
])
Expand Down Expand Up @@ -576,6 +579,19 @@ fn main() -> Result<(), String> {
.to_owned(),
)?;
Ok(())
} else if let Some(args) = subcommand.subcommand_matches("origin") {
filesystem::filesystem_origin(
args.get_one::<String>("pool_name")
.expect("required")
.to_owned(),
args.get_one::<String>("fs_name")
.expect("required")
.to_owned(),
)
.map(|origin| {
println!("{}", origin);
})?;
Ok(())
} else {
filesystem::filesystem_list()?;
Ok(())
Expand Down
1 change: 1 addition & 0 deletions src/dbus_api/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ pub const FILESYSTEM_POOL_PROP: &str = "Pool";
pub const FILESYSTEM_CREATED_PROP: &str = "Created";
pub const FILESYSTEM_SIZE_PROP: &str = "Size";
pub const FILESYSTEM_SIZE_LIMIT_PROP: &str = "SizeLimit";
pub const FILESYSTEM_ORIGIN_PROP: &str = "Origin";

pub const BLOCKDEV_INTERFACE_NAME_3_0: &str = "org.storage.stratis3.blockdev.r0";
pub const BLOCKDEV_INTERFACE_NAME_3_1: &str = "org.storage.stratis3.blockdev.r1";
Expand Down
14 changes: 14 additions & 0 deletions src/dbus_api/filesystem/filesystem_3_7/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// 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 dbus_tree::{Access, EmitsChangedSignal, Factory, MTSync, Property};

use crate::dbus_api::{consts, filesystem::filesystem_3_7::props::get_fs_origin, types::TData};

pub fn origin_property(f: &Factory<MTSync<TData>, TData>) -> Property<MTSync<TData>, TData> {
f.property::<(bool, String), _>(consts::FILESYSTEM_ORIGIN_PROP, ())
.access(Access::Read)
.emits_changed(EmitsChangedSignal::True)
.on_get(get_fs_origin)
}
8 changes: 8 additions & 0 deletions src/dbus_api/filesystem/filesystem_3_7/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// 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/.

mod api;
mod props;

pub use api::origin_property;
18 changes: 18 additions & 0 deletions src/dbus_api/filesystem/filesystem_3_7/props.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// 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 dbus::arg::IterAppend;
use dbus_tree::{MTSync, MethodErr, PropInfo};

use crate::dbus_api::{
filesystem::shared::{self, get_filesystem_property},
types::TData,
};

pub fn get_fs_origin(
i: &mut IterAppend<'_>,
p: &PropInfo<'_, MTSync<TData>, TData>,
) -> Result<(), MethodErr> {
get_filesystem_property(i, p, |(_, _, f)| Ok(shared::fs_origin_prop(f)))
}
7 changes: 5 additions & 2 deletions src/dbus_api/filesystem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::{

mod filesystem_3_0;
mod filesystem_3_6;
mod filesystem_3_7;
pub mod prop_conv;
mod shared;

Expand Down Expand Up @@ -124,7 +125,8 @@ pub fn create_dbus_filesystem<'a>(
.add_p(filesystem_3_0::created_property(&f))
.add_p(filesystem_3_0::size_property(&f))
.add_p(filesystem_3_0::used_property(&f))
.add_p(filesystem_3_6::size_limit_property(&f)),
.add_p(filesystem_3_6::size_limit_property(&f))
.add_p(filesystem_3_7::origin_property(&f)),
);

let path = object_path.get_name().to_owned();
Expand Down Expand Up @@ -214,7 +216,8 @@ pub fn get_fs_properties(
consts::FILESYSTEM_CREATED_PROP => shared::fs_created_prop(fs),
consts::FILESYSTEM_SIZE_PROP => shared::fs_size_prop(fs),
consts::FILESYSTEM_USED_PROP => shared::fs_used_prop(fs),
consts::FILESYSTEM_SIZE_LIMIT_PROP => shared::fs_size_limit_prop(fs)
consts::FILESYSTEM_SIZE_LIMIT_PROP => shared::fs_size_limit_prop(fs),
consts::FILESYSTEM_ORIGIN_PROP => shared::fs_origin_prop(fs)
}
}
}
8 changes: 7 additions & 1 deletion src/dbus_api/filesystem/prop_conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use devicemapper::{Bytes, Sectors};

use crate::dbus_api::util::option_to_tuple;
use crate::{dbus_api::util::option_to_tuple, engine::FilesystemUuid};

/// Generate D-Bus representation of filesystem size property.
#[inline]
Expand All @@ -23,3 +23,9 @@ pub fn fs_used_to_prop(used: Option<Bytes>) -> (bool, String) {
pub fn fs_size_limit_to_prop(limit: Option<Sectors>) -> (bool, String) {
option_to_tuple(limit.map(|u| (*u.bytes()).to_string()), String::new())
}

/// Generate D-Bus representation of filesystem origin property.
#[inline]
pub fn fs_origin_to_prop(origin: Option<FilesystemUuid>) -> (bool, String) {
option_to_tuple(origin.map(|u| (uuid_to_string!(u))), String::new())
}
5 changes: 5 additions & 0 deletions src/dbus_api/filesystem/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,8 @@ pub fn fs_size_prop(fs: &dyn Filesystem) -> String {
pub fn fs_used_prop(fs: &dyn Filesystem) -> (bool, String) {
prop_conv::fs_used_to_prop(fs.used().ok())
}

/// Generate D-Bus representation of origin property.
pub fn fs_origin_prop(fs: &dyn Filesystem) -> (bool, String) {
prop_conv::fs_origin_to_prop(fs.origin())
}
3 changes: 2 additions & 1 deletion src/dbus_api/pool/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ mod pool_3_1;
mod pool_3_3;
mod pool_3_5;
mod pool_3_6;
mod pool_3_7;
pub mod prop_conv;
mod shared;

Expand Down Expand Up @@ -245,7 +246,7 @@ pub fn create_dbus_pool<'a>(
.add(
f.interface(consts::POOL_INTERFACE_NAME_3_7, ())
.add_m(pool_3_6::create_filesystems_method(&f))
.add_m(pool_3_0::destroy_filesystems_method(&f))
.add_m(pool_3_7::destroy_filesystems_method(&f))
.add_m(pool_3_0::snapshot_filesystem_method(&f))
.add_m(pool_3_0::add_blockdevs_method(&f))
.add_m(pool_3_0::bind_clevis_method(&f))
Expand Down
2 changes: 1 addition & 1 deletion src/dbus_api/pool/pool_3_0/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ pub fn destroy_filesystems(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodRe
Ok(uuids) => {
// Only get changed values here as non-existent filesystems will have been filtered out
// before calling destroy_filesystems
let uuid_vec: Vec<String> = if let Some(ref changed_uuids) = uuids.changed() {
let uuid_vec: Vec<String> = if let Some((ref changed_uuids, _)) = uuids.changed() {
for uuid in changed_uuids {
let op = filesystem_map
.get(uuid)
Expand Down
21 changes: 21 additions & 0 deletions src/dbus_api/pool/pool_3_7/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// 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 dbus_tree::{Factory, MTSync, Method};

use crate::dbus_api::{pool::pool_3_7::methods::destroy_filesystems, types::TData};

pub fn destroy_filesystems_method(
f: &Factory<MTSync<TData>, TData>,
) -> Method<MTSync<TData>, TData> {
f.method("DestroyFilesystems", (), destroy_filesystems)
.in_arg(("filesystems", "ao"))
// b: true if filesystems were destroyed
// as: Array of UUIDs of destroyed filesystems
//
// Rust representation: (bool, Vec<String>)
.out_arg(("results", "(bas)"))
.out_arg(("return_code", "q"))
.out_arg(("return_string", "s"))
}
108 changes: 108 additions & 0 deletions src/dbus_api/pool/pool_3_7/methods.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// 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::collections::HashMap;

use dbus::{arg::Array, Message};
use dbus_tree::{MTSync, MethodInfo, MethodResult};

use crate::{
dbus_api::{
consts::filesystem_interface_list,
types::{DbusErrorEnum, TData, OK_STRING},
util::{engine_to_dbus_err_tuple, get_next_arg},
},
engine::{EngineAction, FilesystemUuid, StratisUuid},
};

pub fn destroy_filesystems(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodResult {
let message: &Message = m.msg;
let mut iter = message.iter_init();

let filesystems: Array<'_, dbus::Path<'static>, _> = get_next_arg(&mut iter, 0)?;

let dbus_context = m.tree.get_data();
let object_path = m.path.get_name();
let return_message = message.method_return();
let default_return: (bool, Vec<String>) = (false, Vec::new());

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 guard = get_mut_pool!(dbus_context.engine; pool_uuid; default_return; return_message);
let (pool_name, _, pool) = guard.as_mut_tuple();

let mut filesystem_map: HashMap<FilesystemUuid, dbus::Path<'static>> = HashMap::new();
for path in filesystems {
if let Some((u, path)) = m.tree.get(&path).and_then(|op| {
op.get_data()
.as_ref()
.map(|d| (&d.uuid, op.get_name().clone()))
}) {
let uuid = *typed_uuid!(u; Fs; default_return; return_message);
filesystem_map.insert(uuid, path);
}
}

let result = handle_action!(
pool.destroy_filesystems(
&pool_name,
&filesystem_map.keys().cloned().collect::<Vec<_>>(),
),
dbus_context,
pool_path.get_name()
);
let msg = match result {
Ok(uuids) => {
// Only get changed values here as non-existent filesystems will have been filtered out
// before calling destroy_filesystems
let uuid_vec: Vec<String> =
if let Some((ref changed_uuids, ref updated_uuids)) = uuids.changed() {
for uuid in changed_uuids {
let op = filesystem_map
.get(uuid)
.expect("'uuids' is a subset of filesystem_map.keys()");
dbus_context.push_remove(op, filesystem_interface_list());
}

for sn_op in m.tree.iter().filter(|op| {
op.get_data()
.as_ref()
.map(|data| match data.uuid {
StratisUuid::Fs(uuid) => updated_uuids.contains(&uuid),
_ => false,
})
.unwrap_or(false)
}) {
dbus_context.push_filesystem_origin_change(sn_op.get_name());
}

changed_uuids
.iter()
.map(|uuid| uuid_to_string!(uuid))
.collect()
} else {
Vec::new()
};
return_message.append3(
(true, uuid_vec),
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])
}
8 changes: 8 additions & 0 deletions src/dbus_api/pool/pool_3_7/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// 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/.

mod api;
mod methods;

pub use api::destroy_filesystems_method;
27 changes: 26 additions & 1 deletion src/dbus_api/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ use crate::{
blockdev_user_info_to_prop,
},
consts,
filesystem::prop_conv::{fs_size_limit_to_prop, fs_size_to_prop, fs_used_to_prop},
filesystem::prop_conv::{
fs_origin_to_prop, fs_size_limit_to_prop, fs_size_to_prop, fs_used_to_prop,
},
pool::prop_conv::{
avail_actions_to_prop, clevis_info_to_prop, key_desc_to_prop, pool_alloc_to_prop,
pool_size_to_prop, pool_used_to_prop,
Expand Down Expand Up @@ -201,6 +203,25 @@ impl DbusTreeHandler {
}
}

fn handle_fs_origin_change(&self, item: Path<'static>) {
let origin_prop = fs_origin_to_prop(None);
if self
.property_changed_invalidated_signal(
&item,
prop_hashmap! {
consts::FILESYSTEM_INTERFACE_NAME_3_7 => {
vec![],
consts::FILESYSTEM_ORIGIN_PROP.to_string() =>
box_variant!(origin_prop.clone())
}
},
)
.is_err()
{
warn!("Signal on filesystem origin change was not sent to the D-Bus client");
}
}

/// Handle a pool name change in the engine.
fn handle_pool_name_change(
&self,
Expand Down Expand Up @@ -1195,6 +1216,10 @@ impl DbusTreeHandler {
self.handle_fs_name_change(item, new_name);
Ok(true)
}
DbusAction::FsOriginChange(item) => {
self.handle_fs_origin_change(item);
Ok(true)
}
DbusAction::PoolNameChange(item, new_name) => {
if let Some(read_lock) =
poll_exit_and_future(self.should_exit.recv(), self.tree.read())?
Expand Down
11 changes: 11 additions & 0 deletions src/dbus_api/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ pub enum DbusAction {
StoppedPoolsChange(StoppedPoolsInfo),
BlockdevUserInfoChange(Path<'static>, Option<String>),
BlockdevTotalPhysicalSizeChange(Path<'static>, Sectors),
FsOriginChange(Path<'static>),
FsSizeLimitChange(Path<'static>, Option<Sectors>),
FsBackgroundChange(
FilesystemUuid,
Expand Down Expand Up @@ -487,6 +488,16 @@ impl DbusContext {
)
}
}

/// Send changed signal for changed filesystem origin property.
pub fn push_filesystem_origin_change(&self, path: &Path<'static>) {
if let Err(e) = self.sender.send(DbusAction::FsOriginChange(path.clone())) {
warn!(
"Filesystem origin change event could not be sent to the processing thread; no signal will be sent out for the filesystem origin state change: {}",
e,
)
}
}
}

#[derive(Debug)]
Expand Down
5 changes: 4 additions & 1 deletion src/engine/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ pub trait Filesystem: Debug {

/// Get filesystem size limit.
fn size_limit(&self) -> Option<Sectors>;

/// Get filesystem snapshot origin.
fn origin(&self) -> Option<FilesystemUuid>;
}

pub trait BlockDev: Debug {
Expand Down Expand Up @@ -207,7 +210,7 @@ pub trait Pool: Debug + Send + Sync {
&mut self,
pool_name: &str,
fs_uuids: &[FilesystemUuid],
) -> StratisResult<SetDeleteAction<FilesystemUuid>>;
) -> StratisResult<SetDeleteAction<FilesystemUuid, FilesystemUuid>>;

/// Rename filesystem
/// Rename pool with uuid to new_name.
Expand Down
Loading

0 comments on commit fb888f7

Please sign in to comment.