mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-25 15:02:45 +00:00
agent/device: Obtain guest major/minor numbers when creating DevNumUpdate
Currently the DevNumUpdate structure is created with a path to a device node in the VM, which is then used by update_spec_device(). However the only piece of information that update_spec_device() actually needs is the VM side major and minor numbers for the device. We can determine those when we create the DevNumUpdate structure. This means we detect errors earlier and as a bonus we don't need to make a copy of the vm path string. Since that change requires updating 2 of the log statements, we take the opportunity to update all the log statements to structured style. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
f4982130e1
commit
d6a3ebc496
@ -11,7 +11,7 @@ use std::fmt;
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::os::unix::ffi::OsStrExt;
|
use std::os::unix::ffi::OsStrExt;
|
||||||
use std::os::unix::fs::MetadataExt;
|
use std::os::unix::fs::MetadataExt;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::Path;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
@ -437,15 +437,26 @@ fn scan_scsi_bus(scsi_addr: &str) -> Result<()> {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct DevNumUpdate {
|
struct DevNumUpdate {
|
||||||
// the path to the equivalent device in the VM (used to determine
|
// the major and minor numbers for the device within the guest
|
||||||
// the correct major/minor numbers)
|
guest_major: i64,
|
||||||
vm_path: PathBuf,
|
guest_minor: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DevNumUpdate {
|
impl DevNumUpdate {
|
||||||
fn from_vm_path<T: AsRef<Path>>(vm_path: T) -> Result<Self> {
|
fn from_vm_path<T: AsRef<Path>>(vm_path: T) -> Result<Self> {
|
||||||
|
let vm_path = vm_path.as_ref();
|
||||||
|
|
||||||
|
if !vm_path.exists() {
|
||||||
|
return Err(anyhow!("VM device path {:?} doesn't exist", vm_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
let devid = fs::metadata(vm_path)?.rdev();
|
||||||
|
let guest_major = stat::major(devid) as i64;
|
||||||
|
let guest_minor = stat::minor(devid) as i64;
|
||||||
|
|
||||||
Ok(DevNumUpdate {
|
Ok(DevNumUpdate {
|
||||||
vm_path: vm_path.as_ref().to_owned(),
|
guest_major,
|
||||||
|
guest_minor,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -515,24 +526,12 @@ fn update_spec_device(
|
|||||||
.as_mut()
|
.as_mut()
|
||||||
.ok_or_else(|| anyhow!("Spec didn't container linux field"))?;
|
.ok_or_else(|| anyhow!("Spec didn't container linux field"))?;
|
||||||
|
|
||||||
if !update.num.vm_path.exists() {
|
|
||||||
return Err(anyhow!(
|
|
||||||
"vm_path:{} doesn't exist",
|
|
||||||
update.num.vm_path.display()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let meta = fs::metadata(&update.num.vm_path)?;
|
|
||||||
let dev_id = meta.rdev();
|
|
||||||
let major_id = stat::major(dev_id);
|
|
||||||
let minor_id = stat::minor(dev_id);
|
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
sl!(),
|
sl!(),
|
||||||
"update_spec_device(): vm_path={}, major: {}, minor: {}\n",
|
"update_spec_device() considering device";
|
||||||
update.num.vm_path.display(),
|
"container_path" => container_path,
|
||||||
major_id,
|
"guest_major" => update.num.guest_major,
|
||||||
minor_id
|
"guest_minor" => update.num.guest_minor,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(idxdata) = devidx.0.get(container_path) {
|
if let Some(idxdata) = devidx.0.get(container_path) {
|
||||||
@ -540,21 +539,21 @@ fn update_spec_device(
|
|||||||
let host_major = dev.major;
|
let host_major = dev.major;
|
||||||
let host_minor = dev.minor;
|
let host_minor = dev.minor;
|
||||||
|
|
||||||
dev.major = major_id as i64;
|
dev.major = update.num.guest_major;
|
||||||
dev.minor = minor_id as i64;
|
dev.minor = update.num.guest_minor;
|
||||||
if let Some(final_path) = update.final_path {
|
if let Some(final_path) = update.final_path {
|
||||||
dev.path = final_path;
|
dev.path = final_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
sl!(),
|
sl!(),
|
||||||
"change the device from path: {} major: {} minor: {} to vm device path: {} major: {} minor: {}",
|
"update_spec_device(): updating device";
|
||||||
container_path,
|
"container_path" => container_path,
|
||||||
host_major,
|
"host_major" => host_major,
|
||||||
host_minor,
|
"host_minor" => host_minor,
|
||||||
dev.path,
|
"updated_path" => &dev.path,
|
||||||
dev.major,
|
"guest_major" => dev.major,
|
||||||
dev.minor,
|
"guest_minor" => dev.minor,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Resources must be updated since they are used to identify
|
// Resources must be updated since they are used to identify
|
||||||
@ -563,12 +562,14 @@ fn update_spec_device(
|
|||||||
// unwrap is safe, because residx would be empty if there
|
// unwrap is safe, because residx would be empty if there
|
||||||
// were no resources
|
// were no resources
|
||||||
let res = &mut linux.resources.as_mut().unwrap().devices[*ridx];
|
let res = &mut linux.resources.as_mut().unwrap().devices[*ridx];
|
||||||
res.major = Some(major_id as i64);
|
res.major = Some(update.num.guest_major);
|
||||||
res.minor = Some(minor_id as i64);
|
res.minor = Some(update.num.guest_minor);
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
sl!(),
|
sl!(),
|
||||||
"set resources for device major: {} minor: {}\n", major_id, minor_id
|
"set resources for resource";
|
||||||
|
"guest_major" => update.num.guest_major,
|
||||||
|
"guest_minor" => update.num.guest_minor,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -858,9 +859,13 @@ mod tests {
|
|||||||
let (major, minor) = (7, 2);
|
let (major, minor) = (7, 2);
|
||||||
let mut spec = Spec::default();
|
let mut spec = Spec::default();
|
||||||
|
|
||||||
|
// vm_path empty
|
||||||
|
let update = DevNumUpdate::from_vm_path("");
|
||||||
|
assert!(update.is_err());
|
||||||
|
|
||||||
// container_path empty
|
// container_path empty
|
||||||
let container_path = "";
|
let container_path = "";
|
||||||
let vm_path = "";
|
let vm_path = "/dev/null";
|
||||||
let devidx = DevIndex::new(&spec);
|
let devidx = DevIndex::new(&spec);
|
||||||
let res = update_spec_device(
|
let res = update_spec_device(
|
||||||
&mut spec,
|
&mut spec,
|
||||||
@ -900,18 +905,6 @@ mod tests {
|
|||||||
..oci::LinuxDevice::default()
|
..oci::LinuxDevice::default()
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// vm_path empty
|
|
||||||
let devidx = DevIndex::new(&spec);
|
|
||||||
let res = update_spec_device(
|
|
||||||
&mut spec,
|
|
||||||
&devidx,
|
|
||||||
container_path,
|
|
||||||
DevNumUpdate::from_vm_path(vm_path).unwrap().into(),
|
|
||||||
);
|
|
||||||
assert!(res.is_err());
|
|
||||||
|
|
||||||
let vm_path = "/dev/null";
|
|
||||||
|
|
||||||
// guest and host path are not the same
|
// guest and host path are not the same
|
||||||
let devidx = DevIndex::new(&spec);
|
let devidx = DevIndex::new(&spec);
|
||||||
let res = update_spec_device(
|
let res = update_spec_device(
|
||||||
|
Loading…
Reference in New Issue
Block a user