mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-28 19:54:35 +00:00
agent: implement NVDIMM/PMEM block driver
Support pmem-csi[1] k8s pluging, unlike SCSI and virtio devices, NVDIMM/PMEM devices support DAX, improving IO Read and Write operations. fixes #1289 Signed-off-by: Julio Montes <julio.montes@intel.com> [1]: https://github.com/intel/pmem-csi
This commit is contained in:
parent
f09128d8c7
commit
12551de8a2
@ -162,6 +162,14 @@ pub async fn get_pci_device_name(sandbox: &Arc<Mutex<Sandbox>>, pci_id: &str) ->
|
||||
get_device_name(sandbox, &pci_addr).await
|
||||
}
|
||||
|
||||
pub async fn get_pmem_device_name(
|
||||
sandbox: &Arc<Mutex<Sandbox>>,
|
||||
pmem_devname: &str,
|
||||
) -> Result<String> {
|
||||
let dev_sub_path = format!("/{}/{}", SCSI_BLOCK_SUFFIX, pmem_devname);
|
||||
get_device_name(sandbox, &dev_sub_path).await
|
||||
}
|
||||
|
||||
/// Scan SCSI bus for the given SCSI address(SCSI-Id and LUN)
|
||||
fn scan_scsi_bus(scsi_addr: &str) -> Result<()> {
|
||||
let tokens: Vec<&str> = scsi_addr.split(':').collect();
|
||||
|
@ -58,6 +58,13 @@ pub fn create_pci_root_bus_path() -> String {
|
||||
ret
|
||||
}
|
||||
|
||||
// From https://www.kernel.org/doc/Documentation/acpi/namespace.txt
|
||||
// The Linux kernel's core ACPI subsystem creates struct acpi_device
|
||||
// objects for ACPI namespace objects representing devices, power resources
|
||||
// processors, thermal zones. Those objects are exported to user space via
|
||||
// sysfs as directories in the subtree under /sys/devices/LNXSYSTM:00
|
||||
pub const ACPI_DEV_PATH: &str = "/devices/LNXSYSTM";
|
||||
|
||||
pub const SYSFS_CPU_ONLINE_PATH: &str = "/sys/devices/system/cpu";
|
||||
|
||||
pub const SYSFS_MEMORY_BLOCK_SIZE_PATH: &str = "/sys/devices/system/memory/block_size_bytes";
|
||||
|
@ -22,7 +22,9 @@ use regex::Regex;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
|
||||
use crate::device::{get_pci_device_name, get_scsi_device_name, online_device};
|
||||
use crate::device::{
|
||||
get_pci_device_name, get_pmem_device_name, get_scsi_device_name, online_device,
|
||||
};
|
||||
use crate::linux_abi::*;
|
||||
use crate::protocols::agent::Storage;
|
||||
use crate::Sandbox;
|
||||
@ -122,7 +124,7 @@ lazy_static! {
|
||||
];
|
||||
}
|
||||
|
||||
pub const STORAGE_HANDLER_LIST: [&str; 7] = [
|
||||
pub const STORAGE_HANDLER_LIST: [&str; 8] = [
|
||||
DRIVERBLKTYPE,
|
||||
DRIVER9PTYPE,
|
||||
DRIVERVIRTIOFSTYPE,
|
||||
@ -130,6 +132,7 @@ pub const STORAGE_HANDLER_LIST: [&str; 7] = [
|
||||
DRIVERMMIOBLKTYPE,
|
||||
DRIVERLOCALTYPE,
|
||||
DRIVERSCSITYPE,
|
||||
DRIVERNVDIMMTYPE,
|
||||
];
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -347,6 +350,32 @@ fn common_storage_handler(logger: &Logger, storage: &Storage) -> Result<String>
|
||||
mount_storage(logger, storage).and(Ok(mount_point))
|
||||
}
|
||||
|
||||
// nvdimm_storage_handler handles the storage for NVDIMM driver.
|
||||
async fn nvdimm_storage_handler(
|
||||
logger: &Logger,
|
||||
storage: &Storage,
|
||||
sandbox: Arc<Mutex<Sandbox>>,
|
||||
) -> Result<String> {
|
||||
let mut storage = storage.clone();
|
||||
// If hot-plugged, get the device node path based on the PCI address else
|
||||
// use the virt path provided in Storage Source
|
||||
let pmem_devname = match storage.source.strip_prefix("/dev/") {
|
||||
Some(dev) => dev,
|
||||
None => {
|
||||
return Err(anyhow!(
|
||||
"Storage source '{}' must start with /dev/",
|
||||
storage.source
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
// Retrieve the device path from NVDIMM address.
|
||||
let dev_path = get_pmem_device_name(&sandbox, pmem_devname).await?;
|
||||
storage.source = dev_path;
|
||||
|
||||
common_storage_handler(logger, &storage)
|
||||
}
|
||||
|
||||
// mount_storage performs the mount described by the storage structure.
|
||||
fn mount_storage(logger: &Logger, storage: &Storage) -> Result<()> {
|
||||
let logger = logger.new(o!("subsystem" => "mount"));
|
||||
@ -441,6 +470,7 @@ pub async fn add_storages(
|
||||
}
|
||||
DRIVERLOCALTYPE => local_storage_handler(&logger, &storage, sandbox.clone()).await,
|
||||
DRIVERSCSITYPE => virtio_scsi_storage_handler(&logger, &storage, sandbox.clone()).await,
|
||||
DRIVERNVDIMMTYPE => nvdimm_storage_handler(&logger, &storage, sandbox.clone()).await,
|
||||
_ => {
|
||||
return Err(anyhow!(
|
||||
"Failed to find the storage handler {}",
|
||||
|
@ -54,7 +54,10 @@ impl Uevent {
|
||||
let pci_root_bus_path = create_pci_root_bus_path();
|
||||
self.action == U_EVENT_ACTION_ADD
|
||||
&& self.subsystem == "block"
|
||||
&& self.devpath.starts_with(&pci_root_bus_path)
|
||||
&& {
|
||||
self.devpath.starts_with(pci_root_bus_path.as_str())
|
||||
|| self.devpath.starts_with(ACPI_DEV_PATH) // NVDIMM/PMEM devices
|
||||
}
|
||||
&& self.devname != ""
|
||||
}
|
||||
|
||||
@ -80,11 +83,18 @@ impl Uevent {
|
||||
|
||||
// blk block device
|
||||
devpath.starts_with(pci_p.as_str()) ||
|
||||
// scsi block device
|
||||
{
|
||||
(*dev_addr).ends_with(SCSI_BLOCK_SUFFIX) &&
|
||||
devpath.contains(*dev_addr)
|
||||
}
|
||||
// scsi block device
|
||||
{
|
||||
(*dev_addr).ends_with(SCSI_BLOCK_SUFFIX) &&
|
||||
devpath.contains(*dev_addr)
|
||||
} ||
|
||||
// nvdimm/pmem device
|
||||
{
|
||||
let pmem_suffix = format!("/{}/{}", SCSI_BLOCK_SUFFIX, self.devname);
|
||||
devpath.starts_with(ACPI_DEV_PATH) &&
|
||||
devpath.ends_with(pmem_suffix.as_str()) &&
|
||||
dev_addr.ends_with(pmem_suffix.as_str())
|
||||
}
|
||||
})
|
||||
.map(|(k, sender)| {
|
||||
let devname = self.devname.clone();
|
||||
|
Loading…
Reference in New Issue
Block a user