devicemapper/core/
deviceinfo.rs1use nix::libc::c_char;
6use semver::Version;
7
8use crate::{
9 core::{
10 device::Device,
11 dm_flags::DmFlags,
12 dm_ioctl as dmi, errors,
13 types::{DmName, DmNameBuf, DmUuid, DmUuidBuf},
14 util::str_from_c_str,
15 },
16 result::{DmError, DmResult},
17};
18
19#[derive(Clone, Debug)]
21pub struct DeviceInfo {
22 version: Version,
23
24 #[allow(dead_code)]
25 data_size: u32,
26
27 #[allow(dead_code)]
28 data_start: u32,
29
30 pub(super) target_count: u32,
31
32 open_count: i32,
33 flags: DmFlags,
34 event_nr: u32,
35 dev: Device,
36 name: Option<DmNameBuf>,
37 uuid: Option<DmUuidBuf>,
38}
39
40impl TryFrom<dmi::Struct_dm_ioctl> for DeviceInfo {
41 type Error = DmError;
42
43 fn try_from(ioctl: dmi::Struct_dm_ioctl) -> DmResult<Self> {
44 let uuid = str_from_c_str(&ioctl.uuid as &[c_char]).ok_or_else(|| {
45 errors::Error::InvalidArgument("Devicemapper UUID is not null terminated".to_string())
46 })?;
47 let uuid = if uuid.is_empty() {
48 None
49 } else {
50 Some(DmUuidBuf::new(uuid.to_string())?)
51 };
52 let name = str_from_c_str(&ioctl.name as &[c_char]).ok_or_else(|| {
53 errors::Error::InvalidArgument("Devicemapper name is not null terminated".to_string())
54 })?;
55 let name = if name.is_empty() {
56 None
57 } else {
58 Some(DmNameBuf::new(name.to_string())?)
59 };
60 Ok(DeviceInfo {
61 version: Version::new(
62 u64::from(ioctl.version[0]),
63 u64::from(ioctl.version[1]),
64 u64::from(ioctl.version[2]),
65 ),
66 data_size: ioctl.data_size,
67 data_start: ioctl.data_start,
68 target_count: ioctl.target_count,
69 open_count: ioctl.open_count,
70 flags: DmFlags::from_bits_truncate(ioctl.flags),
71 event_nr: ioctl.event_nr,
72 dev: Device::from_kdev_t(ioctl.dev as u32),
75 uuid,
76 name,
77 })
78 }
79}
80
81impl DeviceInfo {
82 pub fn new(hdr: dmi::Struct_dm_ioctl) -> DmResult<Self> {
86 DeviceInfo::try_from(hdr)
87 }
88
89 pub fn version(&self) -> &Version {
91 &self.version
92 }
93
94 pub fn open_count(&self) -> i32 {
96 self.open_count
97 }
98
99 pub fn event_nr(&self) -> u32 {
101 self.event_nr
102 }
103
104 pub fn device(&self) -> Device {
106 self.dev
107 }
108
109 pub fn name(&self) -> Option<&DmName> {
111 self.name.as_ref().map(|name| name.as_ref())
112 }
113
114 pub fn uuid(&self) -> Option<&DmUuid> {
116 self.uuid.as_ref().map(|uuid| uuid.as_ref())
117 }
118
119 pub fn flags(&self) -> DmFlags {
121 self.flags
122 }
123}