mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-29 04:04:45 +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
|
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)
|
/// Scan SCSI bus for the given SCSI address(SCSI-Id and LUN)
|
||||||
fn scan_scsi_bus(scsi_addr: &str) -> Result<()> {
|
fn scan_scsi_bus(scsi_addr: &str) -> Result<()> {
|
||||||
let tokens: Vec<&str> = scsi_addr.split(':').collect();
|
let tokens: Vec<&str> = scsi_addr.split(':').collect();
|
||||||
|
@ -58,6 +58,13 @@ pub fn create_pci_root_bus_path() -> String {
|
|||||||
ret
|
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_CPU_ONLINE_PATH: &str = "/sys/devices/system/cpu";
|
||||||
|
|
||||||
pub const SYSFS_MEMORY_BLOCK_SIZE_PATH: &str = "/sys/devices/system/memory/block_size_bytes";
|
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::fs::File;
|
||||||
use std::io::{BufRead, BufReader};
|
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::linux_abi::*;
|
||||||
use crate::protocols::agent::Storage;
|
use crate::protocols::agent::Storage;
|
||||||
use crate::Sandbox;
|
use crate::Sandbox;
|
||||||
@ -122,7 +124,7 @@ lazy_static! {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const STORAGE_HANDLER_LIST: [&str; 7] = [
|
pub const STORAGE_HANDLER_LIST: [&str; 8] = [
|
||||||
DRIVERBLKTYPE,
|
DRIVERBLKTYPE,
|
||||||
DRIVER9PTYPE,
|
DRIVER9PTYPE,
|
||||||
DRIVERVIRTIOFSTYPE,
|
DRIVERVIRTIOFSTYPE,
|
||||||
@ -130,6 +132,7 @@ pub const STORAGE_HANDLER_LIST: [&str; 7] = [
|
|||||||
DRIVERMMIOBLKTYPE,
|
DRIVERMMIOBLKTYPE,
|
||||||
DRIVERLOCALTYPE,
|
DRIVERLOCALTYPE,
|
||||||
DRIVERSCSITYPE,
|
DRIVERSCSITYPE,
|
||||||
|
DRIVERNVDIMMTYPE,
|
||||||
];
|
];
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[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))
|
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.
|
// mount_storage performs the mount described by the storage structure.
|
||||||
fn mount_storage(logger: &Logger, storage: &Storage) -> Result<()> {
|
fn mount_storage(logger: &Logger, storage: &Storage) -> Result<()> {
|
||||||
let logger = logger.new(o!("subsystem" => "mount"));
|
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,
|
DRIVERLOCALTYPE => local_storage_handler(&logger, &storage, sandbox.clone()).await,
|
||||||
DRIVERSCSITYPE => virtio_scsi_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!(
|
return Err(anyhow!(
|
||||||
"Failed to find the storage handler {}",
|
"Failed to find the storage handler {}",
|
||||||
|
@ -54,7 +54,10 @@ impl Uevent {
|
|||||||
let pci_root_bus_path = create_pci_root_bus_path();
|
let pci_root_bus_path = create_pci_root_bus_path();
|
||||||
self.action == U_EVENT_ACTION_ADD
|
self.action == U_EVENT_ACTION_ADD
|
||||||
&& self.subsystem == "block"
|
&& 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 != ""
|
&& self.devname != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,6 +87,13 @@ impl Uevent {
|
|||||||
{
|
{
|
||||||
(*dev_addr).ends_with(SCSI_BLOCK_SUFFIX) &&
|
(*dev_addr).ends_with(SCSI_BLOCK_SUFFIX) &&
|
||||||
devpath.contains(*dev_addr)
|
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)| {
|
.map(|(k, sender)| {
|
||||||
|
Loading…
Reference in New Issue
Block a user