diff --git a/src/agent/src/device.rs b/src/agent/src/device.rs index 6b3704ce5e..3dd6244301 100644 --- a/src/agent/src/device.rs +++ b/src/agent/src/device.rs @@ -29,8 +29,7 @@ use protocols::agent::Device; use tracing::instrument; use kata_types::device::{ - DRIVER_NVDIMM_TYPE, DRIVER_SCSI_TYPE, DRIVER_VFIO_AP_TYPE, DRIVER_VFIO_PCI_GK_TYPE, - DRIVER_VFIO_PCI_TYPE, + DRIVER_SCSI_TYPE, DRIVER_VFIO_AP_TYPE, DRIVER_VFIO_PCI_GK_TYPE, DRIVER_VFIO_PCI_TYPE, }; // Convenience function to obtain the scope logger. @@ -205,52 +204,6 @@ pub async fn get_scsi_device_name( Ok(format!("{}/{}", SYSTEM_DEV_PATH, &uev.devname)) } -#[derive(Debug)] -struct PmemBlockMatcher { - suffix: String, -} - -impl PmemBlockMatcher { - fn new(devname: &str) -> PmemBlockMatcher { - let suffix = format!(r"/block/{}", devname); - - PmemBlockMatcher { suffix } - } -} - -impl UeventMatcher for PmemBlockMatcher { - fn is_match(&self, uev: &Uevent) -> bool { - uev.subsystem == BLOCK - && uev.devpath.starts_with(ACPI_DEV_PATH) - && uev.devpath.ends_with(&self.suffix) - && !uev.devname.is_empty() - } -} - -#[instrument] -pub async fn wait_for_pmem_device(sandbox: &Arc>, devpath: &str) -> Result<()> { - let devname = match devpath.strip_prefix("/dev/") { - Some(dev) => dev, - None => { - return Err(anyhow!( - "Storage source '{}' must start with /dev/", - devpath - )) - } - }; - - let matcher = PmemBlockMatcher::new(devname); - let uev = wait_for_uevent(sandbox, matcher).await?; - if uev.devname != devname { - return Err(anyhow!( - "Unexpected device name {} for pmem device (expected {})", - uev.devname, - devname - )); - } - Ok(()) -} - #[derive(Debug)] struct PciMatcher { devpath: String, @@ -714,20 +667,6 @@ async fn virtio_scsi_device_handler( .into()) } -#[instrument] -async fn virtio_nvdimm_device_handler( - device: &Device, - _sandbox: &Arc>, -) -> Result { - if device.vm_path.is_empty() { - return Err(anyhow!("Invalid path for nvdimm device")); - } - - Ok(DeviceInfo::new(device.vm_path(), true) - .context("New device info")? - .into()) -} - fn split_vfio_pci_option(opt: &str) -> Option<(&str, &str)> { let mut tokens = opt.split('='); let hostbdf = tokens.next()?; diff --git a/src/agent/src/device/nvdimm_device_handler.rs b/src/agent/src/device/nvdimm_device_handler.rs new file mode 100644 index 0000000000..8d5c41439b --- /dev/null +++ b/src/agent/src/device/nvdimm_device_handler.rs @@ -0,0 +1,77 @@ +// Copyright (c) 2019 Ant Financial +// Copyright (c) 2024 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +use crate::device::{DeviceContext, DeviceHandler, DeviceInfo, SpecUpdate, BLOCK}; +use crate::linux_abi::ACPI_DEV_PATH; +use crate::sandbox::Sandbox; +use crate::uevent::{wait_for_uevent, Uevent, UeventMatcher}; +use anyhow::{anyhow, Context, Result}; +use protocols::agent::Device; +use std::sync::Arc; +use tokio::sync::Mutex; +use tracing::instrument; + +#[derive(Debug)] +pub struct VirtioNvdimmDeviceHandler {} + +#[async_trait::async_trait] +impl DeviceHandler for VirtioNvdimmDeviceHandler { + #[instrument] + async fn device_handler(&self, device: &Device, ctx: &mut DeviceContext) -> Result { + if device.vm_path.is_empty() { + return Err(anyhow!("Invalid path for nvdimm device")); + } + Ok(DeviceInfo::new(device.vm_path(), true) + .context("New device info")? + .into()) + } +} + +#[instrument] +pub async fn wait_for_pmem_device(sandbox: &Arc>, devpath: &str) -> Result<()> { + let devname = match devpath.strip_prefix("/dev/") { + Some(dev) => dev, + None => { + return Err(anyhow!( + "Storage source '{}' must start with /dev/", + devpath + )) + } + }; + + let matcher = PmemBlockMatcher::new(devname); + let uev = wait_for_uevent(sandbox, matcher).await?; + if uev.devname != devname { + return Err(anyhow!( + "Unexpected device name {} for pmem device (expected {})", + uev.devname, + devname + )); + } + Ok(()) +} + +#[derive(Debug)] +pub struct PmemBlockMatcher { + suffix: String, +} + +impl PmemBlockMatcher { + pub fn new(devname: &str) -> PmemBlockMatcher { + let suffix = format!(r"/block/{}", devname); + + PmemBlockMatcher { suffix } + } +} + +impl UeventMatcher for PmemBlockMatcher { + fn is_match(&self, uev: &Uevent) -> bool { + uev.subsystem == BLOCK + && uev.devpath.starts_with(ACPI_DEV_PATH) + && uev.devpath.ends_with(&self.suffix) + && !uev.devname.is_empty() + } +}