src/tools/disks/zpool_status.rs: improve parser
This commit is contained in:
parent
547f0c97e4
commit
9438aca6c9
@ -19,10 +19,14 @@ use nom::{
|
|||||||
pub struct ZFSPoolVDevState {
|
pub struct ZFSPoolVDevState {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub lvl: u64,
|
pub lvl: u64,
|
||||||
pub state: String,
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
pub read: u64,
|
pub state: Option<String>,
|
||||||
pub write: u64,
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
pub cksum: u64,
|
pub read: Option<u64>,
|
||||||
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
|
pub write: Option<u64>,
|
||||||
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
|
pub cksum: Option<u64>,
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
pub msg: Option<String>,
|
pub msg: Option<String>,
|
||||||
}
|
}
|
||||||
@ -36,6 +40,20 @@ fn parse_zpool_status_vdev(i: &str) -> IResult<&str, ZFSPoolVDevState> {
|
|||||||
let i = n;
|
let i = n;
|
||||||
|
|
||||||
let (i, vdev_name) = notspace1(i)?;
|
let (i, vdev_name) = notspace1(i)?;
|
||||||
|
|
||||||
|
if let Ok((n, _)) = preceded(multispace0, line_ending)(i) { // sepecial device
|
||||||
|
let vdev = ZFSPoolVDevState {
|
||||||
|
name: vdev_name.to_string(),
|
||||||
|
lvl: (indent.len() as u64)/2,
|
||||||
|
state: None,
|
||||||
|
read: None,
|
||||||
|
write: None,
|
||||||
|
cksum: None,
|
||||||
|
msg: None,
|
||||||
|
};
|
||||||
|
return Ok((n, vdev));
|
||||||
|
}
|
||||||
|
|
||||||
let (i, state) = preceded(multispace1, notspace1)(i)?;
|
let (i, state) = preceded(multispace1, notspace1)(i)?;
|
||||||
let (i, read) = preceded(multispace1, parse_u64)(i)?;
|
let (i, read) = preceded(multispace1, parse_u64)(i)?;
|
||||||
let (i, write) = preceded(multispace1, parse_u64)(i)?;
|
let (i, write) = preceded(multispace1, parse_u64)(i)?;
|
||||||
@ -46,8 +64,10 @@ fn parse_zpool_status_vdev(i: &str) -> IResult<&str, ZFSPoolVDevState> {
|
|||||||
let vdev = ZFSPoolVDevState {
|
let vdev = ZFSPoolVDevState {
|
||||||
name: vdev_name.to_string(),
|
name: vdev_name.to_string(),
|
||||||
lvl: (indent.len() as u64)/2,
|
lvl: (indent.len() as u64)/2,
|
||||||
state: state.to_string(),
|
state: Some(state.to_string()),
|
||||||
read, write, cksum,
|
read: Some(read),
|
||||||
|
write: Some(write),
|
||||||
|
cksum: Some(cksum),
|
||||||
msg: msg.map(String::from),
|
msg: msg.map(String::from),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -118,8 +138,9 @@ pub fn parse_zpool_status_config_tree(i: &str) -> Result<Vec<ZFSPoolVDevState>,
|
|||||||
parse_complete("zfs status config tree", i, parse_zpool_status_tree)
|
parse_complete("zfs status config tree", i, parse_zpool_status_tree)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_zpool_status(i: &str) -> Result<Vec<(String, String)>, Error> {
|
fn parse_zpool_status(input: &str) -> Result<Vec<(String, String)>, Error> {
|
||||||
parse_complete("zfs status output", i, many0(parse_zpool_status_field))
|
let input = input.replace('\t', " "); // important!
|
||||||
|
parse_complete("zfs status output", &input, many0(parse_zpool_status_field))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vdev_list_to_tree(vdev_list: &[ZFSPoolVDevState]) -> Value {
|
pub fn vdev_list_to_tree(vdev_list: &[ZFSPoolVDevState]) -> Value {
|
||||||
@ -235,7 +256,7 @@ config:
|
|||||||
|
|
||||||
NAME STATE READ WRITE CKSUM
|
NAME STATE READ WRITE CKSUM
|
||||||
tank DEGRADED 0 0 0
|
tank DEGRADED 0 0 0
|
||||||
mirror-0 DEGRADED 0 0 0
|
mirror-0 DEGRADED 0 0 0
|
||||||
c1t0d0 ONLINE 0 0 0
|
c1t0d0 ONLINE 0 0 0
|
||||||
c1t2d0 ONLINE 0 0 0
|
c1t2d0 ONLINE 0 0 0
|
||||||
c1t1d0 UNAVAIL 0 0 0 cannot open
|
c1t1d0 UNAVAIL 0 0 0 cannot open
|
||||||
@ -251,8 +272,44 @@ errors: No known data errors
|
|||||||
println!("{} => {}", k,v);
|
println!("{} => {}", k,v);
|
||||||
if k == "config" {
|
if k == "config" {
|
||||||
let vdev_list = parse_zpool_status_config_tree(&v)?;
|
let vdev_list = parse_zpool_status_config_tree(&v)?;
|
||||||
let tree = vdev_list_to_tree(&vdev_list);
|
let _tree = vdev_list_to_tree(&vdev_list);
|
||||||
println!("TREE1 {}", serde_json::to_string_pretty(&tree)?);
|
//println!("TREE1 {}", serde_json::to_string_pretty(&tree)?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_zpool_status_parser2() -> Result<(), Error> {
|
||||||
|
|
||||||
|
// Note: this input create TABS
|
||||||
|
let output = r###" pool: btest
|
||||||
|
state: ONLINE
|
||||||
|
scan: none requested
|
||||||
|
config:
|
||||||
|
|
||||||
|
NAME STATE READ WRITE CKSUM
|
||||||
|
btest ONLINE 0 0 0
|
||||||
|
mirror-0 ONLINE 0 0 0
|
||||||
|
/dev/sda1 ONLINE 0 0 0
|
||||||
|
/dev/sda2 ONLINE 0 0 0
|
||||||
|
mirror-1 ONLINE 0 0 0
|
||||||
|
/dev/sda3 ONLINE 0 0 0
|
||||||
|
/dev/sda4 ONLINE 0 0 0
|
||||||
|
logs
|
||||||
|
/dev/sda5 ONLINE 0 0 0
|
||||||
|
|
||||||
|
errors: No known data errors
|
||||||
|
"###;
|
||||||
|
|
||||||
|
let key_value_list = parse_zpool_status(&output)?;
|
||||||
|
for (k, v) in key_value_list {
|
||||||
|
println!("{} => {}", k,v);
|
||||||
|
if k == "config" {
|
||||||
|
let vdev_list = parse_zpool_status_config_tree(&v)?;
|
||||||
|
let _tree = vdev_list_to_tree(&vdev_list);
|
||||||
|
//println!("TREE1 {}", serde_json::to_string_pretty(&tree)?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user