use nix::libc::c_char;
use semver::Version;
use crate::{
core::{
device::Device,
dm_flags::DmFlags,
dm_ioctl as dmi, errors,
types::{DmName, DmNameBuf, DmUuid, DmUuidBuf},
util::str_from_c_str,
},
result::{DmError, DmResult},
};
#[derive(Clone, Debug)]
pub struct DeviceInfo {
version: Version,
#[allow(dead_code)]
data_size: u32,
#[allow(dead_code)]
data_start: u32,
pub(super) target_count: u32,
open_count: i32,
flags: DmFlags,
event_nr: u32,
dev: Device,
name: Option<DmNameBuf>,
uuid: Option<DmUuidBuf>,
}
impl TryFrom<dmi::Struct_dm_ioctl> for DeviceInfo {
type Error = DmError;
fn try_from(ioctl: dmi::Struct_dm_ioctl) -> DmResult<Self> {
let uuid = str_from_c_str(&ioctl.uuid as &[c_char]).ok_or_else(|| {
errors::Error::InvalidArgument("Devicemapper UUID is not null terminated".to_string())
})?;
let uuid = if uuid.is_empty() {
None
} else {
Some(DmUuidBuf::new(uuid.to_string())?)
};
let name = str_from_c_str(&ioctl.name as &[c_char]).ok_or_else(|| {
errors::Error::InvalidArgument("Devicemapper name is not null terminated".to_string())
})?;
let name = if name.is_empty() {
None
} else {
Some(DmNameBuf::new(name.to_string())?)
};
Ok(DeviceInfo {
version: Version::new(
u64::from(ioctl.version[0]),
u64::from(ioctl.version[1]),
u64::from(ioctl.version[2]),
),
data_size: ioctl.data_size,
data_start: ioctl.data_start,
target_count: ioctl.target_count,
open_count: ioctl.open_count,
flags: DmFlags::from_bits_truncate(ioctl.flags),
event_nr: ioctl.event_nr,
dev: Device::from_kdev_t(ioctl.dev as u32),
uuid,
name,
})
}
}
impl DeviceInfo {
pub fn new(hdr: dmi::Struct_dm_ioctl) -> DmResult<Self> {
DeviceInfo::try_from(hdr)
}
pub fn version(&self) -> &Version {
&self.version
}
pub fn open_count(&self) -> i32 {
self.open_count
}
pub fn event_nr(&self) -> u32 {
self.event_nr
}
pub fn device(&self) -> Device {
self.dev
}
pub fn name(&self) -> Option<&DmName> {
self.name.as_ref().map(|name| name.as_ref())
}
pub fn uuid(&self) -> Option<&DmUuid> {
self.uuid.as_ref().map(|uuid| uuid.as_ref())
}
pub fn flags(&self) -> DmFlags {
self.flags
}
}