mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-28 16:27:50 +00:00
agent: PCI path type
Introduce a Rust type to represent a "PCI path" - that is a way of locating a PCI device from a given root by listing the slots of all the bridges leading to it and finally the slot of the device itself. It's implemented as a vector of the previously added pci::Slot type, and includes the necessary validation and conversions to/from strings. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
b22259ad9b
commit
7464d055a7
@ -4,6 +4,7 @@
|
|||||||
//
|
//
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::ops::Deref;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
@ -48,9 +49,50 @@ impl fmt::Display for Slot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct Path(Vec<Slot>);
|
||||||
|
|
||||||
|
impl Path {
|
||||||
|
pub fn new(slots: Vec<Slot>) -> anyhow::Result<Self> {
|
||||||
|
if slots.is_empty() {
|
||||||
|
return Err(anyhow!("PCI path must have at least one element"));
|
||||||
|
}
|
||||||
|
Ok(Path(slots))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let Path be treated as a slice of Slots
|
||||||
|
impl Deref for Path {
|
||||||
|
type Target = [Slot];
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Path {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
|
let sslots: Vec<String> = self
|
||||||
|
.0
|
||||||
|
.iter()
|
||||||
|
.map(std::string::ToString::to_string)
|
||||||
|
.collect();
|
||||||
|
write!(f, "{}", sslots.join("/"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Path {
|
||||||
|
type Err = anyhow::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> anyhow::Result<Self> {
|
||||||
|
let rslots: anyhow::Result<Vec<Slot>> = s.split('/').map(Slot::from_str).collect();
|
||||||
|
Path::new(rslots?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::pci::Slot;
|
use crate::pci::{Path, Slot};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -85,4 +127,42 @@ mod tests {
|
|||||||
let slot = Slot::from_str("");
|
let slot = Slot::from_str("");
|
||||||
assert!(slot.is_err());
|
assert!(slot.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_path() {
|
||||||
|
let slot3 = Slot::new(0x03).unwrap();
|
||||||
|
let slot4 = Slot::new(0x04).unwrap();
|
||||||
|
let slot5 = Slot::new(0x05).unwrap();
|
||||||
|
|
||||||
|
// Valid paths
|
||||||
|
let pcipath = Path::new(vec![slot3]).unwrap();
|
||||||
|
assert_eq!(format!("{}", pcipath), "03");
|
||||||
|
let pcipath2 = Path::from_str("03").unwrap();
|
||||||
|
assert_eq!(pcipath, pcipath2);
|
||||||
|
assert_eq!(pcipath.len(), 1);
|
||||||
|
assert_eq!(pcipath[0], slot3);
|
||||||
|
|
||||||
|
let pcipath = Path::new(vec![slot3, slot4]).unwrap();
|
||||||
|
assert_eq!(format!("{}", pcipath), "03/04");
|
||||||
|
let pcipath2 = Path::from_str("03/04").unwrap();
|
||||||
|
assert_eq!(pcipath, pcipath2);
|
||||||
|
assert_eq!(pcipath.len(), 2);
|
||||||
|
assert_eq!(pcipath[0], slot3);
|
||||||
|
assert_eq!(pcipath[1], slot4);
|
||||||
|
|
||||||
|
let pcipath = Path::new(vec![slot3, slot4, slot5]).unwrap();
|
||||||
|
assert_eq!(format!("{}", pcipath), "03/04/05");
|
||||||
|
let pcipath2 = Path::from_str("03/04/05").unwrap();
|
||||||
|
assert_eq!(pcipath, pcipath2);
|
||||||
|
assert_eq!(pcipath.len(), 3);
|
||||||
|
assert_eq!(pcipath[0], slot3);
|
||||||
|
assert_eq!(pcipath[1], slot4);
|
||||||
|
assert_eq!(pcipath[2], slot5);
|
||||||
|
|
||||||
|
// Bad paths
|
||||||
|
assert!(Path::new(vec!()).is_err());
|
||||||
|
assert!(Path::from_str("20").is_err());
|
||||||
|
assert!(Path::from_str("//").is_err());
|
||||||
|
assert!(Path::from_str("xyz").is_err());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user