mirror of
https://github.com/kata-containers/kata-containers.git
synced 2026-04-12 15:02:36 +00:00
runtime-rs: Add QMP iommufd hotplug and timeout bumps
Add hotplug_iommufd() to QmpClient for attaching VFIO devices through the iommufd backend at runtime via QMP object-add + device_add. Bump QMP connection and command timeouts from 10s to 30s to accommodate the longer initialization time when VFIO devices are cold-plugged (IOMMU domain setup and device reset can be slow for GPUs). Re-export cmdline_generator types from qemu/mod.rs for downstream use. Signed-off-by: Alex Lyn <alex.lyn@antgroup.com> Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
This commit is contained in:
committed by
Fabiano Fidêncio
parent
7c6ef0e45b
commit
439c8e8ee1
@@ -33,7 +33,7 @@ use std::time::Instant;
|
||||
|
||||
/// default qmp connection read timeout
|
||||
const DEFAULT_QMP_READ_TIMEOUT: u64 = 250;
|
||||
const DEFAULT_QMP_CONNECT_DEADLINE_MS: u64 = 5000;
|
||||
const DEFAULT_QMP_CONNECT_DEADLINE_MS: u64 = 50000;
|
||||
const DEFAULT_QMP_RETRY_SLEEP_MS: u64 = 50;
|
||||
|
||||
pub struct Qmp {
|
||||
@@ -72,7 +72,7 @@ impl Qmp {
|
||||
let stream = UnixStream::connect(qmp_sock_path)?;
|
||||
|
||||
stream
|
||||
.set_read_timeout(Some(Duration::from_millis(DEFAULT_QMP_READ_TIMEOUT)))
|
||||
.set_read_timeout(Some(Duration::from_millis(5000)))
|
||||
.context("set qmp read timeout")?;
|
||||
|
||||
let mut qmp = Qmp {
|
||||
@@ -292,6 +292,59 @@ impl Qmp {
|
||||
Ok(hotplugged_mem_size)
|
||||
}
|
||||
|
||||
/// Hotplug an iommufd QOM object in QEMU and return the object id.
|
||||
#[allow(dead_code)]
|
||||
pub fn hotplug_iommufd(
|
||||
&mut self,
|
||||
suffix_or_id: &str,
|
||||
external_fdname: Option<&str>,
|
||||
) -> Result<String> {
|
||||
// Object id in QEMU (also used as fdname for getfd)
|
||||
let obj_id = if suffix_or_id.starts_with("iommufd") {
|
||||
suffix_or_id.to_string()
|
||||
} else {
|
||||
format!("iommufd{suffix_or_id}")
|
||||
};
|
||||
|
||||
{
|
||||
let file = std::fs::OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.open("/dev/iommu")
|
||||
.context("open /dev/iommu failed")?;
|
||||
self.pass_fd(file.as_raw_fd(), &obj_id)?;
|
||||
}
|
||||
|
||||
let obj = match external_fdname {
|
||||
None => qmp::object_add(qapi_qmp::ObjectOptions::iommufd {
|
||||
id: obj_id.clone(),
|
||||
iommufd: qapi_qmp::IOMMUFDProperties { fd: None },
|
||||
}),
|
||||
Some(_fdname) => qmp::object_add(qapi_qmp::ObjectOptions::iommufd {
|
||||
id: obj_id.clone(),
|
||||
iommufd: qapi_qmp::IOMMUFDProperties {
|
||||
fd: Some(obj_id.to_string()),
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
match self.qmp.execute(&obj) {
|
||||
Ok(_) => Ok(obj_id),
|
||||
Err(e) => {
|
||||
let msg = format!("{e:#}");
|
||||
if msg.contains("duplicate ID")
|
||||
|| msg.contains("already exists")
|
||||
|| msg.contains("exists")
|
||||
{
|
||||
Ok(obj_id)
|
||||
} else {
|
||||
Err(anyhow!(e))
|
||||
.with_context(|| format!("object-add iommufd failed (id={obj_id})"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hotplug_memory(&mut self, size: u64) -> Result<()> {
|
||||
let memdev_idx = self
|
||||
.qmp
|
||||
|
||||
Reference in New Issue
Block a user