Skip to content

Commit

Permalink
Merge pull request #3712 from mulkieran/issue_stratisd_3621_a
Browse files Browse the repository at this point in the history
Support snapshot revert
  • Loading branch information
mulkieran authored Oct 30, 2024
2 parents f11bb98 + 5aae2f3 commit fd48484
Show file tree
Hide file tree
Showing 24 changed files with 1,202 additions and 175 deletions.
1 change: 1 addition & 0 deletions src/dbus_api/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ 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 FILESYSTEM_MERGE_SCHEDULED_PROP: &str = "MergeScheduled";

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
18 changes: 17 additions & 1 deletion src/dbus_api/filesystem/filesystem_3_7/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,27 @@

use dbus_tree::{Access, EmitsChangedSignal, Factory, MTSync, Property};

use crate::dbus_api::{consts, filesystem::filesystem_3_7::props::get_fs_origin, types::TData};
use crate::dbus_api::{
consts,
filesystem::filesystem_3_7::props::{
get_fs_merge_scheduled, get_fs_origin, set_fs_merge_scheduled,
},
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)
}

pub fn merge_scheduled_property(
f: &Factory<MTSync<TData>, TData>,
) -> Property<MTSync<TData>, TData> {
f.property::<bool, _>(consts::FILESYSTEM_MERGE_SCHEDULED_PROP, ())
.access(Access::ReadWrite)
.emits_changed(EmitsChangedSignal::True)
.on_get(get_fs_merge_scheduled)
.on_set(set_fs_merge_scheduled)
}
2 changes: 1 addition & 1 deletion src/dbus_api/filesystem/filesystem_3_7/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
mod api;
mod props;

pub use api::origin_property;
pub use api::{merge_scheduled_property, origin_property};
46 changes: 42 additions & 4 deletions src/dbus_api/filesystem/filesystem_3_7/props.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@
// 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::arg::{Iter, IterAppend};
use dbus_tree::{MTSync, MethodErr, PropInfo};

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

pub fn get_fs_origin(
Expand All @@ -16,3 +20,37 @@ pub fn get_fs_origin(
) -> Result<(), MethodErr> {
get_filesystem_property(i, p, |(_, _, f)| Ok(shared::fs_origin_prop(f)))
}

pub fn get_fs_merge_scheduled(
i: &mut IterAppend<'_>,
p: &PropInfo<'_, MTSync<TData>, TData>,
) -> Result<(), MethodErr> {
get_filesystem_property(i, p, |(_, _, f)| Ok(shared::fs_merge_scheduled_prop(f)))
}

/// Set the merge scheduled property on a filesystem
pub fn set_fs_merge_scheduled(
i: &mut Iter<'_>,
p: &PropInfo<'_, MTSync<TData>, TData>,
) -> Result<(), MethodErr> {
let merge_scheduled: bool = i
.get()
.ok_or_else(|| MethodErr::failed("Value required as argument to set property"))?;

let res = shared::set_fs_property_to_display(
p,
consts::FILESYSTEM_MERGE_SCHEDULED_PROP,
|(_, uuid, p)| shared::set_fs_merge_scheduled_prop(uuid, p, merge_scheduled),
);

match res {
Ok(PropChangeAction::NewValue(v)) => {
p.tree
.get_data()
.push_fs_merge_scheduled_change(p.path.get_name(), v);
Ok(())
}
Ok(PropChangeAction::Identity) => Ok(()),
Err(e) => Err(e),
}
}
6 changes: 4 additions & 2 deletions src/dbus_api/filesystem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ pub fn create_dbus_filesystem<'a>(
.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_7::origin_property(&f)),
.add_p(filesystem_3_7::origin_property(&f))
.add_p(filesystem_3_7::merge_scheduled_property(&f)),
);

let path = object_path.get_name().to_owned();
Expand Down Expand Up @@ -217,7 +218,8 @@ pub fn get_fs_properties(
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_ORIGIN_PROP => shared::fs_origin_prop(fs)
consts::FILESYSTEM_ORIGIN_PROP => shared::fs_origin_prop(fs),
consts::FILESYSTEM_MERGE_SCHEDULED_PROP => shared::fs_merge_scheduled_prop(fs)
}
}
}
15 changes: 15 additions & 0 deletions src/dbus_api/filesystem/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,3 +207,18 @@ pub fn fs_used_prop(fs: &dyn Filesystem) -> (bool, String) {
pub fn fs_origin_prop(fs: &dyn Filesystem) -> (bool, String) {
prop_conv::fs_origin_to_prop(fs.origin())
}

/// Generate D-Bus representation of merge scheduled property
pub fn fs_merge_scheduled_prop(fs: &dyn Filesystem) -> bool {
fs.merge_scheduled()
}

#[inline]
pub fn set_fs_merge_scheduled_prop(
uuid: FilesystemUuid,
pool: &mut dyn Pool,
schedule: bool,
) -> Result<PropChangeAction<bool>, String> {
pool.set_fs_merge_scheduled(uuid, schedule)
.map_err(|e| e.to_string())
}
18 changes: 9 additions & 9 deletions src/dbus_api/pool/pool_3_7/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,16 @@ pub fn destroy_filesystems(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodRe
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)
for (sn_op, origin) in m.tree.iter().filter_map(|op| {
op.get_data().as_ref().and_then(|data| match data.uuid {
StratisUuid::Fs(uuid) => updated_uuids
.iter()
.find(|(u, _)| *u == uuid)
.map(|(_, origin)| (op, *origin)),
_ => None,
})
}) {
dbus_context.push_filesystem_origin_change(sn_op.get_name());
dbus_context.push_filesystem_origin_change(sn_op.get_name(), origin);
}

changed_uuids
Expand Down
32 changes: 27 additions & 5 deletions src/dbus_api/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,16 +203,15 @@ impl DbusTreeHandler {
}
}

fn handle_fs_origin_change(&self, item: Path<'static>) {
let origin_prop = fs_origin_to_prop(None);
fn handle_fs_origin_change(&self, item: Path<'static>, new_origin: Option<FilesystemUuid>) {
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())
box_variant!(fs_origin_to_prop(new_origin))
}
},
)
Expand Down Expand Up @@ -873,6 +872,25 @@ impl DbusTreeHandler {
}
}

/// Send a signal indicating that the filesystem merge scheduled value has
/// changed.
fn handle_fs_merge_scheduled_change(&self, path: Path<'static>, new_scheduled: bool) {
if let Err(e) = self.property_changed_invalidated_signal(
&path,
prop_hashmap!(
consts::FILESYSTEM_INTERFACE_NAME_3_7 => {
Vec::new(),
consts::FILESYSTEM_MERGE_SCHEDULED_PROP.to_string() =>
box_variant!(new_scheduled)
}
),
) {
warn!(
"Failed to send a signal over D-Bus indicating filesystem merge scheduled value change: {e}"
);
}
}

/// Send a signal indicating that the blockdev user info has changed.
fn handle_blockdev_user_info_change(&self, path: Path<'static>, new_user_info: Option<String>) {
let user_info_prop = blockdev_user_info_to_prop(new_user_info);
Expand Down Expand Up @@ -1216,8 +1234,8 @@ impl DbusTreeHandler {
self.handle_fs_name_change(item, new_name);
Ok(true)
}
DbusAction::FsOriginChange(item) => {
self.handle_fs_origin_change(item);
DbusAction::FsOriginChange(item, new_origin) => {
self.handle_fs_origin_change(item, new_origin);
Ok(true)
}
DbusAction::PoolNameChange(item, new_name) => {
Expand Down Expand Up @@ -1254,6 +1272,10 @@ impl DbusTreeHandler {
self.handle_fs_size_limit_change(path, new_limit);
Ok(true)
}
DbusAction::FsMergeScheduledChange(path, new_scheduled) => {
self.handle_fs_merge_scheduled_change(path, new_scheduled);
Ok(true)
}
DbusAction::PoolOverprovModeChange(path, new_mode) => {
self.handle_pool_overprov_mode_change(path, new_mode);
Ok(true)
Expand Down
26 changes: 23 additions & 3 deletions src/dbus_api/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,9 @@ pub enum DbusAction {
StoppedPoolsChange(StoppedPoolsInfo),
BlockdevUserInfoChange(Path<'static>, Option<String>),
BlockdevTotalPhysicalSizeChange(Path<'static>, Sectors),
FsOriginChange(Path<'static>),
FsOriginChange(Path<'static>, Option<FilesystemUuid>),
FsSizeLimitChange(Path<'static>, Option<Sectors>),
FsMergeScheduledChange(Path<'static>, bool),
FsBackgroundChange(
FilesystemUuid,
SignalChange<Option<Bytes>>,
Expand Down Expand Up @@ -490,14 +491,33 @@ 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())) {
pub fn push_filesystem_origin_change(
&self,
path: &Path<'static>,
origin: Option<FilesystemUuid>,
) {
if let Err(e) = self
.sender
.send(DbusAction::FsOriginChange(path.clone(), origin))
{
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,
)
}
}

/// Send changed signal for pool MergeScheduled property.
pub fn push_fs_merge_scheduled_change(&self, item: &Path<'static>, new_merge_scheduled: bool) {
if let Err(e) = self.sender.send(DbusAction::FsMergeScheduledChange(
item.clone(),
new_merge_scheduled,
)) {
warn!(
"D-Bus filesystem merge scheduled change event could not be sent to the processing thread; no signal will be sent out for the merge scheduled change of filesystem with path {item}: {e}"
)
}
}
}

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

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

fn merge_scheduled(&self) -> bool;
}

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

/// Rename filesystem
/// Rename pool with uuid to new_name.
Expand Down Expand Up @@ -356,6 +358,13 @@ pub trait Pool: Debug + Send + Sync {

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

/// Set whether a merge of the filesystem is scheduled.
fn set_fs_merge_scheduled(
&mut self,
fs: FilesystemUuid,
new_scheduled: bool,
) -> StratisResult<PropChangeAction<bool>>;
}

pub type HandleEvents<P> = (
Expand Down
29 changes: 26 additions & 3 deletions src/engine/sim_engine/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ pub struct FilesystemSave {
fs_size_limit: Option<Sectors>,
#[serde(skip_serializing_if = "Option::is_none")]
origin: Option<FilesystemUuid>,
#[serde(default)]
merge: bool,
}

#[derive(Debug)]
Expand All @@ -36,6 +38,7 @@ pub struct SimFilesystem {
size: Sectors,
size_limit: Option<Sectors>,
origin: Option<FilesystemUuid>,
merge_scheduled: bool,
}

impl SimFilesystem {
Expand All @@ -57,6 +60,7 @@ impl SimFilesystem {
size,
size_limit,
origin,
merge_scheduled: false,
})
}

Expand All @@ -83,9 +87,9 @@ impl SimFilesystem {
}
}

pub fn unset_origin(&mut self) -> bool {
let changed = self.origin.is_some();
self.origin = None;
pub fn set_origin(&mut self, value: Option<FilesystemUuid>) -> bool {
let changed = self.origin != value;
self.origin = value;
changed
}

Expand All @@ -97,6 +101,21 @@ impl SimFilesystem {
created: self.created.timestamp() as u64,
fs_size_limit: self.size_limit,
origin: self.origin,
merge: self.merge_scheduled,
}
}

/// Set the merge scheduled value for the filesystem.
pub fn set_merge_scheduled(&mut self, scheduled: bool) -> StratisResult<bool> {
if self.merge_scheduled == scheduled {
Ok(false)
} else if scheduled && self.origin.is_none() {
Err(StratisError::Msg(
"Filesystem has no origin filesystem; can not schedule a merge".into(),
))
} else {
self.merge_scheduled = scheduled;
Ok(true)
}
}
}
Expand Down Expand Up @@ -131,6 +150,10 @@ impl Filesystem for SimFilesystem {
fn origin(&self) -> Option<FilesystemUuid> {
self.origin
}

fn merge_scheduled(&self) -> bool {
self.merge_scheduled
}
}

impl<'a> Into<Value> for &'a SimFilesystem {
Expand Down
Loading

0 comments on commit fd48484

Please sign in to comment.