Skip to content

Commit

Permalink
Support block devices
Browse files Browse the repository at this point in the history
  • Loading branch information
nbdd0121 committed Oct 8, 2024
1 parent c54ec38 commit 7059bf7
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 24 deletions.
2 changes: 1 addition & 1 deletion src/cgroup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use std::mem::ManuallyDrop;
use std::path::{Path, PathBuf};

// The numerical representation below needs to match BPF_DEVCG constants.
#[allow(unused)]
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DeviceType {
Block = 1,
Character = 2,
Expand Down
30 changes: 19 additions & 11 deletions src/dev/device.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use std::fmt::{self, Display, Formatter};
use std::path::{Path, PathBuf};

use crate::cgroup::DeviceType;

#[derive(Debug, Clone)]
pub struct DevNode {
pub path: PathBuf,
pub ty: DeviceType,
pub devnum: (u32, u32),
}

Expand All @@ -16,17 +19,22 @@ pub struct Device {

impl Device {
pub fn from_udev(device: udev::Device) -> Self {
let devnode = device
.devnum()
.zip(device.devnode())
.map(|(devnum, devnode)| {
let major = rustix::fs::major(devnum);
let minor = rustix::fs::minor(devnum);
DevNode {
path: devnode.to_owned(),
devnum: (major, minor),
}
});
let devnode = device.devnode().and_then(|devnode| {
let devnum = device.devnum()?;
let major = rustix::fs::major(devnum);
let minor = rustix::fs::minor(devnum);
// Only block subsystem produce block device, everything else are character device.
let ty = if device.subsystem()? == "block" {
DeviceType::Block
} else {
DeviceType::Character
};
Some(DevNode {
path: devnode.to_owned(),
ty,
devnum: (major, minor),
})
});
Self { device, devnode }
}

Expand Down
10 changes: 7 additions & 3 deletions src/hotplug/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,12 @@ impl HotPlug {
.filter_map(|dev| dev.matches(&device))
.collect();

self.container.device(devnode.devnum, Access::all()).await?;
self.container.mknod(&devnode.path, devnode.devnum).await?;
self.container
.device(devnode.ty, devnode.devnum, Access::all())
.await?;
self.container
.mknod(&devnode.path, devnode.ty, devnode.devnum)
.await?;
for symlink in &symlinks {
self.container.symlink(&devnode.path, symlink).await?;
}
Expand All @@ -89,7 +93,7 @@ impl HotPlug {

let devnode = device.devnode().unwrap();
self.container
.device(devnode.devnum, Access::empty())
.device(devnode.ty, devnode.devnum, Access::empty())
.await?;
self.container.rm(&devnode.path).await?;
for symlink in &device.symlinks {
Expand Down
30 changes: 21 additions & 9 deletions src/runc/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,12 @@ impl Container {
Ok(())
}

pub async fn mknod(&self, node: &Path, (major, minor): (u32, u32)) -> Result<()> {
pub async fn mknod(
&self,
node: &Path,
ty: DeviceType,
(major, minor): (u32, u32),
) -> Result<()> {
let ns = crate::util::namespace::MntNamespace::of_pid(self.pid)?;
ns.enter(|| {
if let Some(parent) = node.parent() {
Expand All @@ -225,7 +230,11 @@ impl Container {
rustix::fs::mknodat(
rustix::fs::CWD,
node,
FileType::CharacterDevice,
if ty == DeviceType::Character {
FileType::CharacterDevice
} else {
FileType::BlockDevice
},
Mode::from(0o644),
rustix::fs::makedev(major, minor),
)?;
Expand All @@ -252,13 +261,16 @@ impl Container {
})
}

pub async fn device(&self, (major, minor): (u32, u32), access: Access) -> Result<()> {
self.cgroup_device_filter.lock().await.set_permission(
DeviceType::Character,
major,
minor,
access,
)?;
pub async fn device(
&self,
ty: DeviceType,
(major, minor): (u32, u32),
access: Access,
) -> Result<()> {
self.cgroup_device_filter
.lock()
.await
.set_permission(ty, major, minor, access)?;
Ok(())
}
}

0 comments on commit 7059bf7

Please sign in to comment.