agent: Move device code with nvdimm driver to nvdimm_device_handler

Move device code with nvdimm driver to nvdimm_device_handler, including
nvdimm device and pmem device.

Signed-off-by: ChengyuZhu6 <chengyu.zhu@intel.com>
This commit is contained in:
ChengyuZhu6 2024-08-27 06:10:55 +08:00
parent bbf934161b
commit 0738d75a92
2 changed files with 78 additions and 62 deletions

View File

@ -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<Mutex<Sandbox>>, 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<Mutex<Sandbox>>,
) -> Result<SpecUpdate> {
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()?;

View File

@ -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<SpecUpdate> {
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<Mutex<Sandbox>>, 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()
}
}