diff --git a/src/cachedev.rs b/src/cachedev.rs index 03267805..8e245324 100644 --- a/src/cachedev.rs +++ b/src/cachedev.rs @@ -14,9 +14,9 @@ use crate::{ lineardev::{LinearDev, LinearDevTargetParams}, result::{DmError, DmResult, ErrorEnum}, shared::{ - device_create, device_exists, device_match, get_status, get_status_line_fields, - make_unexpected_value_error, parse_device, parse_value, DmDevice, TargetLine, TargetParams, - TargetTable, TargetTypeBuf, + device_create, device_exists, device_match, get_status, get_status_line, + get_status_line_fields, make_unexpected_value_error, parse_device, parse_value, DmDevice, + TargetLine, TargetParams, TargetTable, TargetTypeBuf, }, units::{DataBlocks, MetaBlocks, Sectors}, }; @@ -369,6 +369,8 @@ impl FromStr for CacheDevStatus { // Note: This method is not entirely complete. In particular, *_args values // may require more or better checking or processing. fn from_str(status_line: &str) -> DmResult { + let status_line = get_status_line(status_line, &CACHE_TARGET_NAME)?; + if status_line.starts_with("Error") { return Ok(CacheDevStatus::Error); } diff --git a/src/shared.rs b/src/shared.rs index f9b15b3b..ab452ed5 100644 --- a/src/shared.rs +++ b/src/shared.rs @@ -226,6 +226,27 @@ where }) } +/// Obtain a status line from a line containing the target type as its first +/// entry. Return an error if the line does not have the expected target type. +/// Precondition: The line's first entry is the target type, followed by a +/// space, followed by the actual status values. +pub fn get_status_line<'a, 'b>( + status_line: &'a str, + expected_target_type: &'b str, +) -> DmResult<&'a str> { + let target_status_pair: Vec<&str> = status_line.splitn(2, ' ').collect(); + let target_type = target_status_pair[0]; + if target_type != expected_target_type { + let err_msg = format!( + "Expected a \"{}\" target entry but found target type \"{}\" in \"{}\"", + expected_target_type, target_type, status_line + ); + return Err(DmError::Dm(ErrorEnum::Invalid, err_msg)); + } + + Ok(target_status_pair[1]) +} + /// Get fields for a single status line. /// Return an error if an insufficient number of fields are obtained. pub fn get_status_line_fields<'a>( @@ -260,11 +281,10 @@ pub fn get_status(status_lines: &[(u64, u64, String, String)]) -> DmResult DmResult { + let status_line = get_status_line(status_line, &THIN_TARGET_NAME)?; + if status_line.starts_with("Error") { return Ok(ThinStatus::Error); } diff --git a/src/thinpooldev.rs b/src/thinpooldev.rs index 8038bf93..6141e1d5 100644 --- a/src/thinpooldev.rs +++ b/src/thinpooldev.rs @@ -9,9 +9,9 @@ use crate::{ lineardev::{LinearDev, LinearDevTargetParams}, result::{DmError, DmResult, ErrorEnum}, shared::{ - device_create, device_exists, device_match, get_status, get_status_line_fields, - make_unexpected_value_error, parse_device, parse_value, DmDevice, TargetLine, TargetParams, - TargetTable, TargetTypeBuf, + device_create, device_exists, device_match, get_status, get_status_line, + get_status_line_fields, make_unexpected_value_error, parse_device, parse_value, DmDevice, + TargetLine, TargetParams, TargetTable, TargetTypeBuf, }, units::{DataBlocks, MetaBlocks, Sectors}, }; @@ -337,6 +337,8 @@ impl FromStr for ThinPoolStatus { type Err = DmError; fn from_str(status_line: &str) -> DmResult { + let status_line = get_status_line(status_line, &THINPOOL_TARGET_NAME)?; + if status_line.starts_with("Error") { return Ok(ThinPoolStatus::Error); }