Skip to content
This repository was archived by the owner on Jul 25, 2024. It is now read-only.

Commit 74bf6e4

Browse files
authored
Add State (#72)
Expose some functions to get the current state for a pool / dataset or all pools. These states try to be holistic views of what Pools / Datasets Properties and VDevs look like at that point in time. Signed-off-by: Joe Grund <jgrund@whamcloud.io>
1 parent e98927c commit 74bf6e4

4 files changed

Lines changed: 130 additions & 2 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libzfs/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "libzfs"
3-
version = "0.6.8"
3+
version = "0.6.9"
44
authors = ["IML Team <iml@whamcloud.com>"]
55
description = "Rust wrapper around libzfs-sys"
66
license = "MIT"

libzfs/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,6 @@ pub use zpool::Zpool;
3333

3434
pub mod libzfs;
3535
pub use libzfs::Libzfs;
36+
37+
pub mod state;
38+
pub use state::*;

libzfs/src/state.rs

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
// Copyright (c) 2018 DDN. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
//! Get the current state of ZFS on a node
6+
//!
7+
//! Uses a `Libzfs` handle to get state at that point.
8+
//! Collects into a struct that can be serialized using `serde`.
9+
//!
10+
11+
use std::io;
12+
13+
use libzfs::Libzfs;
14+
use libzfs_error::Result;
15+
use vdev::VDev;
16+
use zfs::Zfs;
17+
use zpool::Zpool;
18+
use zprop_list::ZProp;
19+
20+
/// A Pool at a point in time
21+
#[derive(Debug, Serialize, Deserialize)]
22+
pub struct Pool {
23+
pub name: String,
24+
pub guid: String,
25+
pub health: String,
26+
pub hostname: String,
27+
pub hostid: Option<u64>,
28+
pub state: String,
29+
pub readonly: bool,
30+
pub size: String,
31+
pub vdev: VDev,
32+
pub props: Vec<ZProp>,
33+
pub datasets: Vec<Dataset>,
34+
}
35+
36+
/// A Dataset at a point in time
37+
#[derive(Debug, Serialize, Deserialize)]
38+
pub struct Dataset {
39+
pub name: String,
40+
pub guid: String,
41+
pub kind: String,
42+
pub props: Vec<ZProp>,
43+
}
44+
45+
/// Takes a Zfs reference and converts it into a
46+
/// `Dataset`
47+
fn convert_to_dataset(x: &Zfs) -> Result<Dataset> {
48+
let props = x.props()?;
49+
50+
let guid = props
51+
.iter()
52+
.find(|x| x.name == "guid")
53+
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "could not find guid in props"))
54+
.map(|x| x.value.clone())?;
55+
56+
Ok(Dataset {
57+
name: x.name().into_string()?,
58+
kind: x.zfs_type_name().into_string()?,
59+
guid,
60+
props,
61+
})
62+
}
63+
64+
/// Takes a Zpool reference and converts it into a
65+
/// `Pool`
66+
fn convert_to_js_pool(p: &Zpool) -> Result<Pool> {
67+
let xs: Vec<Dataset> = p
68+
.datasets()?
69+
.iter()
70+
.map(convert_to_dataset)
71+
.collect::<Result<_>>()?;
72+
73+
let hostname = p.hostname()?;
74+
75+
let hostid = p.hostid().ok();
76+
77+
let health = p.health()?;
78+
79+
Ok(Pool {
80+
name: p.name().into_string()?,
81+
health: health.into_string()?,
82+
guid: p.guid().to_string(),
83+
hostname: hostname.into_string()?,
84+
hostid,
85+
state: p.state_name().into_string()?,
86+
readonly: p.read_only(),
87+
size: p.size().to_string(),
88+
props: vec![],
89+
vdev: p.vdev_tree()?,
90+
datasets: xs,
91+
})
92+
}
93+
94+
/// Given a pool name, try to find it and convert it to a `Pool`.
95+
/// The outer `Option` represents failure to find the pool,
96+
/// The inner `Result` represents failure during the conversion.
97+
pub fn get_pool_by_name(pool_name: &str) -> Option<Result<Pool>> {
98+
let mut libzfs = Libzfs::new();
99+
100+
libzfs
101+
.pool_by_name(&pool_name)
102+
.map(|x| convert_to_js_pool(&x))
103+
}
104+
105+
/// Given a dataset name, try to find it and convert it to a `Dataset`.
106+
/// The outer `Option` represents failure to find the dataset,
107+
/// The inner `Result` represents failure during the conversion.
108+
pub fn get_dataset_by_name(ds_name: &str) -> Option<Result<Dataset>> {
109+
let mut libzfs = Libzfs::new();
110+
111+
libzfs
112+
.dataset_by_name(&ds_name)
113+
.map(|x| convert_to_dataset(&x))
114+
}
115+
116+
/// Return all imported pools on this node.
117+
/// Returns `Err` if any imported pool fails conversion to `Pool`.
118+
pub fn get_imported_pools() -> Result<Vec<Pool>> {
119+
let mut libzfs = Libzfs::new();
120+
libzfs
121+
.get_imported_pools()?
122+
.iter()
123+
.map(convert_to_js_pool)
124+
.collect()
125+
}

0 commit comments

Comments
 (0)