Skip to content

Commit 8bb0a20

Browse files
committed
Implementation of filesystem interfaces
Signed-off-by: mulhern <[email protected]>
1 parent 06c2dc8 commit 8bb0a20

File tree

16 files changed

+1735
-18
lines changed

16 files changed

+1735
-18
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this
3+
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4+
5+
use std::sync::Arc;
6+
7+
use crate::{
8+
dbus::{consts::OK_STRING, types::DbusErrorEnum},
9+
engine::{Engine, FilesystemUuid, PoolIdentifier, PoolUuid, RenameAction},
10+
stratis::StratisError,
11+
};
12+
13+
pub async fn set_name_method(
14+
engine: &Arc<dyn Engine>,
15+
uuid: PoolUuid,
16+
fs_uuid: FilesystemUuid,
17+
name: &str,
18+
) -> ((bool, FilesystemUuid), u16, String) {
19+
let default_return = (false, FilesystemUuid::nil());
20+
21+
match engine
22+
.get_mut_pool(PoolIdentifier::Uuid(uuid))
23+
.await
24+
.ok_or_else(|| StratisError::Msg(format!("No pool associated with uuid {uuid}")))
25+
{
26+
Err(err) => (default_return, DbusErrorEnum::ERROR as u16, err.to_string()),
27+
Ok(mut guard) => {
28+
let (pool_name, _, pool) = guard.as_mut_tuple();
29+
match handle_action!(pool.rename_filesystem(&pool_name, fs_uuid, name)) {
30+
Ok(RenameAction::NoSource) => (
31+
default_return,
32+
DbusErrorEnum::ERROR as u16,
33+
format!("pool doesn't know about filesystem {fs_uuid}"),
34+
),
35+
Ok(RenameAction::Renamed(_)) => (
36+
// FIXME: send signal
37+
(true, fs_uuid),
38+
DbusErrorEnum::OK as u16,
39+
OK_STRING.to_string(),
40+
),
41+
Ok(RenameAction::Identity) => (
42+
default_return,
43+
DbusErrorEnum::OK as u16,
44+
OK_STRING.to_string(),
45+
),
46+
Err(err) => (default_return, DbusErrorEnum::ERROR as u16, err.to_string()),
47+
}
48+
}
49+
}
50+
}

src/dbus/filesystem/filesystem_3_0/mod.rs

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,125 @@
22
// License, v. 2.0. If a copy of the MPL was not distributed with this
33
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
44

5+
use std::sync::Arc;
6+
7+
use tokio::sync::RwLock;
8+
use zbus::{
9+
fdo::Error,
10+
interface,
11+
zvariant::{ObjectPath, OwnedObjectPath},
12+
Connection,
13+
};
14+
mod methods;
515
mod props;
616

7-
pub use props::name_prop;
17+
pub use methods::set_name_method;
18+
pub use props::{created_prop, devnode_prop, name_prop, pool_prop, size_prop, used_prop};
19+
20+
use crate::{
21+
dbus::{filesystem::shared::filesystem_prop, manager::Manager},
22+
engine::{Engine, FilesystemUuid, Lockable, Name, PoolUuid},
23+
stratis::StratisResult,
24+
};
25+
26+
pub struct FilesystemR0 {
27+
engine: Arc<dyn Engine>,
28+
manager: Lockable<Arc<RwLock<Manager>>>,
29+
parent_uuid: PoolUuid,
30+
uuid: FilesystemUuid,
31+
}
32+
33+
impl FilesystemR0 {
34+
fn new(
35+
engine: Arc<dyn Engine>,
36+
manager: Lockable<Arc<RwLock<Manager>>>,
37+
parent_uuid: PoolUuid,
38+
uuid: FilesystemUuid,
39+
) -> Self {
40+
FilesystemR0 {
41+
engine,
42+
manager,
43+
parent_uuid,
44+
uuid,
45+
}
46+
}
47+
48+
pub async fn register(
49+
engine: Arc<dyn Engine>,
50+
connection: &Arc<Connection>,
51+
manager: &Lockable<Arc<RwLock<Manager>>>,
52+
path: ObjectPath<'_>,
53+
parent_uuid: PoolUuid,
54+
uuid: FilesystemUuid,
55+
) -> StratisResult<()> {
56+
let filesystem = Self::new(engine, manager.clone(), parent_uuid, uuid);
57+
58+
connection.object_server().at(path, filesystem).await?;
59+
Ok(())
60+
}
61+
62+
pub async fn unregister(
63+
connection: &Arc<Connection>,
64+
path: ObjectPath<'_>,
65+
) -> StratisResult<()> {
66+
connection
67+
.object_server()
68+
.remove::<FilesystemR0, _>(path)
69+
.await?;
70+
Ok(())
71+
}
72+
}
73+
74+
#[interface(
75+
name = "org.storage.stratis3.filesystem.r0",
76+
introspection_docs = false
77+
)]
78+
impl FilesystemR0 {
79+
#[zbus(out_args("result", "return_code", "return_string"))]
80+
#[allow(non_snake_case)]
81+
async fn SetName(&self, name: &str) -> ((bool, FilesystemUuid), u16, String) {
82+
set_name_method(&self.engine, self.parent_uuid, self.uuid, name).await
83+
}
84+
85+
#[zbus(property(emits_changed_signal = "const"))]
86+
#[allow(non_snake_case)]
87+
async fn Created(&self) -> Result<String, Error> {
88+
filesystem_prop(&self.engine, self.parent_uuid, self.uuid, created_prop).await
89+
}
90+
91+
#[zbus(property(emits_changed_signal = "invalidates"))]
92+
#[allow(non_snake_case)]
93+
async fn Devnode(&self) -> Result<String, Error> {
94+
filesystem_prop(&self.engine, self.parent_uuid, self.uuid, devnode_prop).await
95+
}
96+
97+
#[zbus(property)]
98+
#[allow(non_snake_case)]
99+
async fn Name(&self) -> Result<Name, Error> {
100+
filesystem_prop(&self.engine, self.parent_uuid, self.uuid, name_prop).await
101+
}
102+
103+
#[zbus(property(emits_changed_signal = "const"))]
104+
#[allow(non_snake_case)]
105+
async fn Pool(&self) -> Result<OwnedObjectPath, Error> {
106+
pool_prop(self.manager.read().await, self.parent_uuid)
107+
}
108+
109+
#[zbus(property)]
110+
#[allow(non_snake_case)]
111+
async fn Size(&self) -> Result<String, Error> {
112+
filesystem_prop(&self.engine, self.parent_uuid, self.uuid, size_prop).await
113+
}
114+
115+
#[zbus(property)]
116+
#[allow(non_snake_case)]
117+
async fn Used(&self) -> Result<(bool, String), Error> {
118+
filesystem_prop(&self.engine, self.parent_uuid, self.uuid, used_prop).await
119+
}
120+
121+
#[zbus(property(emits_changed_signal = "const"))]
122+
#[allow(non_snake_case)]
123+
fn Uuid(&self) -> FilesystemUuid {
124+
self.uuid
125+
}
126+
}

src/dbus/filesystem/filesystem_3_0/props.rs

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,53 @@
22
// License, v. 2.0. If a copy of the MPL was not distributed with this
33
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
44

5-
use crate::engine::{Filesystem, FilesystemUuid, Name};
5+
use tokio::sync::OwnedRwLockReadGuard;
66

7-
pub fn name_prop(name: Name, _: FilesystemUuid, _: &dyn Filesystem) -> Name {
7+
use chrono::SecondsFormat;
8+
use zbus::{fdo::Error, zvariant::OwnedObjectPath};
9+
10+
use crate::{
11+
dbus::{util::option_to_tuple, Manager},
12+
engine::{Filesystem, FilesystemUuid, Name, PoolUuid, SharedGuard},
13+
};
14+
15+
pub fn created_prop(_: Name, _: Name, _: FilesystemUuid, fs: &dyn Filesystem) -> String {
16+
fs.created().to_rfc3339_opts(SecondsFormat::Secs, true)
17+
}
18+
19+
pub fn devnode_prop(
20+
pool_name: Name,
21+
fs_name: Name,
22+
_: FilesystemUuid,
23+
fs: &dyn Filesystem,
24+
) -> String {
25+
fs.path_to_mount_filesystem(&pool_name, &fs_name)
26+
.display()
27+
.to_string()
28+
}
29+
30+
pub fn name_prop(_: Name, name: Name, _: FilesystemUuid, _: &dyn Filesystem) -> Name {
831
name
932
}
33+
34+
pub fn pool_prop(
35+
guard: SharedGuard<OwnedRwLockReadGuard<Manager>>,
36+
pool_uuid: PoolUuid,
37+
) -> Result<OwnedObjectPath, Error> {
38+
guard
39+
.pool_get_path(&pool_uuid)
40+
.ok_or_else(|| {
41+
Error::Failed(format!(
42+
"No object path associated with pool UUID {pool_uuid}"
43+
))
44+
})
45+
.cloned()
46+
}
47+
48+
pub fn size_prop(_: Name, _: Name, _: FilesystemUuid, fs: &dyn Filesystem) -> String {
49+
(*fs.size()).to_string()
50+
}
51+
52+
pub fn used_prop(_: Name, _: Name, _: FilesystemUuid, fs: &dyn Filesystem) -> (bool, String) {
53+
option_to_tuple(fs.used().ok().map(|u| (*u).to_string()), String::new())
54+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this
3+
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4+
5+
use std::sync::Arc;
6+
7+
use tokio::sync::RwLock;
8+
use zbus::{
9+
fdo::Error,
10+
interface,
11+
zvariant::{ObjectPath, OwnedObjectPath},
12+
Connection,
13+
};
14+
15+
use crate::{
16+
dbus::{
17+
filesystem::{
18+
filesystem_3_0::{
19+
created_prop, devnode_prop, name_prop, pool_prop, set_name_method, size_prop,
20+
used_prop,
21+
},
22+
shared::filesystem_prop,
23+
},
24+
manager::Manager,
25+
},
26+
engine::{Engine, FilesystemUuid, Lockable, Name, PoolUuid},
27+
stratis::StratisResult,
28+
};
29+
30+
pub struct FilesystemR1 {
31+
engine: Arc<dyn Engine>,
32+
manager: Lockable<Arc<RwLock<Manager>>>,
33+
parent_uuid: PoolUuid,
34+
uuid: FilesystemUuid,
35+
}
36+
37+
impl FilesystemR1 {
38+
fn new(
39+
engine: Arc<dyn Engine>,
40+
manager: Lockable<Arc<RwLock<Manager>>>,
41+
parent_uuid: PoolUuid,
42+
uuid: FilesystemUuid,
43+
) -> Self {
44+
FilesystemR1 {
45+
engine,
46+
manager,
47+
parent_uuid,
48+
uuid,
49+
}
50+
}
51+
52+
pub async fn register(
53+
engine: Arc<dyn Engine>,
54+
connection: &Arc<Connection>,
55+
manager: &Lockable<Arc<RwLock<Manager>>>,
56+
path: ObjectPath<'_>,
57+
parent_uuid: PoolUuid,
58+
uuid: FilesystemUuid,
59+
) -> StratisResult<()> {
60+
let filesystem = Self::new(engine, manager.clone(), parent_uuid, uuid);
61+
62+
connection.object_server().at(path, filesystem).await?;
63+
Ok(())
64+
}
65+
66+
pub async fn unregister(
67+
connection: &Arc<Connection>,
68+
path: ObjectPath<'_>,
69+
) -> StratisResult<()> {
70+
connection
71+
.object_server()
72+
.remove::<FilesystemR1, _>(path)
73+
.await?;
74+
Ok(())
75+
}
76+
}
77+
78+
#[interface(
79+
name = "org.storage.stratis3.filesystem.r1",
80+
introspection_docs = false
81+
)]
82+
impl FilesystemR1 {
83+
#[zbus(out_args("result", "return_code", "return_string"))]
84+
#[allow(non_snake_case)]
85+
async fn SetName(&self, name: &str) -> ((bool, FilesystemUuid), u16, String) {
86+
set_name_method(&self.engine, self.parent_uuid, self.uuid, name).await
87+
}
88+
89+
#[zbus(property(emits_changed_signal = "const"))]
90+
#[allow(non_snake_case)]
91+
async fn Created(&self) -> Result<String, Error> {
92+
filesystem_prop(&self.engine, self.parent_uuid, self.uuid, created_prop).await
93+
}
94+
95+
#[zbus(property(emits_changed_signal = "invalidates"))]
96+
#[allow(non_snake_case)]
97+
async fn Devnode(&self) -> Result<String, Error> {
98+
filesystem_prop(&self.engine, self.parent_uuid, self.uuid, devnode_prop).await
99+
}
100+
101+
#[zbus(property)]
102+
#[allow(non_snake_case)]
103+
async fn Name(&self) -> Result<Name, Error> {
104+
filesystem_prop(&self.engine, self.parent_uuid, self.uuid, name_prop).await
105+
}
106+
107+
#[zbus(property(emits_changed_signal = "const"))]
108+
#[allow(non_snake_case)]
109+
async fn Pool(&self) -> Result<OwnedObjectPath, Error> {
110+
pool_prop(self.manager.read().await, self.parent_uuid)
111+
}
112+
113+
#[zbus(property)]
114+
#[allow(non_snake_case)]
115+
async fn Size(&self) -> Result<String, Error> {
116+
filesystem_prop(&self.engine, self.parent_uuid, self.uuid, size_prop).await
117+
}
118+
119+
#[zbus(property)]
120+
#[allow(non_snake_case)]
121+
async fn Used(&self) -> Result<(bool, String), Error> {
122+
filesystem_prop(&self.engine, self.parent_uuid, self.uuid, used_prop).await
123+
}
124+
125+
#[zbus(property(emits_changed_signal = "const"))]
126+
#[allow(non_snake_case)]
127+
fn Uuid(&self) -> FilesystemUuid {
128+
self.uuid
129+
}
130+
}

0 commit comments

Comments
 (0)