Provide dummy supports for some cgroup attributes required by Podman

This commit is contained in:
Chen Chengjun 2025-12-10 06:34:07 +00:00 committed by Ruihan Li
parent 0e3ef19ada
commit d92f388ae1
3 changed files with 87 additions and 12 deletions

View File

@ -3,7 +3,11 @@
use alloc::sync::Arc;
use aster_systree::{Error, Result, SysAttrSetBuilder, SysPerms, SysStr};
use ostd::mm::{VmReader, VmWriter};
use aster_util::printer::VmPrinter;
use ostd::{
cpu::num_cpus,
mm::{VmReader, VmWriter},
};
/// A sub-controller responsible for CPU resource management in the cgroup subsystem.
pub struct CpuSetController {
@ -29,8 +33,23 @@ impl CpuSetController {
}
impl super::SubControl for CpuSetController {
fn read_attr_at(&self, _name: &str, _offset: usize, _writer: &mut VmWriter) -> Result<usize> {
Err(Error::AttributeError)
fn read_attr_at(&self, name: &str, offset: usize, writer: &mut VmWriter) -> Result<usize> {
let mut printer = VmPrinter::new_skip(writer, offset);
match name {
"cpuset.cpus.effective" => {
let num_cpus = num_cpus();
if num_cpus == 1 {
writeln!(printer, "0")?;
} else {
writeln!(printer, "0-{}", num_cpus - 1)?;
}
}
// Currently we only support a single memory node.
"cpuset.mems.effective" => writeln!(printer, "0")?,
_ => return Err(Error::AttributeError),
}
Ok(printer.bytes_written())
}
fn write_attr(&self, _name: &str, _reader: &mut VmReader) -> Result<usize> {

View File

@ -1,15 +1,19 @@
// SPDX-License-Identifier: MPL-2.0
use alloc::sync::Arc;
use core::sync::atomic::{AtomicU32, Ordering};
use aster_systree::{Error, Result, SysAttrSetBuilder, SysPerms, SysStr};
use aster_systree::{Error, MAX_ATTR_SIZE, Result, SysAttrSetBuilder, SysPerms, SysStr};
use aster_util::printer::VmPrinter;
use ostd::mm::{VmReader, VmWriter};
use crate::{process::posix_thread::PID_MAX, util::ReadCString};
/// A sub-controller responsible for PID resource management in the cgroup subsystem.
///
/// This controller will only provide interfaces in non-root cgroup nodes.
pub struct PidsController {
_private: (),
max_pid: AtomicU32,
}
impl PidsController {
@ -21,18 +25,59 @@ impl PidsController {
}
impl super::SubControl for PidsController {
fn read_attr_at(&self, _name: &str, _offset: usize, _writer: &mut VmWriter) -> Result<usize> {
Err(Error::AttributeError)
fn read_attr_at(&self, name: &str, offset: usize, writer: &mut VmWriter) -> Result<usize> {
let mut printer = VmPrinter::new_skip(writer, offset);
match name {
"pids.max" => {
let max_pid = self.max_pid.load(Ordering::Relaxed);
if max_pid == u32::MAX {
writeln!(printer, "max")?;
} else {
writeln!(printer, "{}", max_pid)?;
}
}
_ => return Err(Error::AttributeError),
}
Ok(printer.bytes_written())
}
fn write_attr(&self, _name: &str, _reader: &mut VmReader) -> Result<usize> {
Err(Error::AttributeError)
fn write_attr(&self, name: &str, reader: &mut VmReader) -> Result<usize> {
match name {
"pids.max" => {
let (content, len) = reader
.read_cstring_until_end(MAX_ATTR_SIZE)
.map_err(|_| Error::PageFault)?;
let value = content
.to_str()
.map_err(|_| Error::InvalidOperation)?
.trim();
let value = if value == "max" {
u32::MAX
} else if let Ok(value) = value.parse::<u32>() {
if value >= PID_MAX {
return Err(Error::InvalidOperation);
}
log::warn!("The cgroup's PID limit '{}' will not be enforced", value);
value
} else {
return Err(Error::InvalidOperation);
};
self.max_pid.store(value, Ordering::Relaxed);
Ok(len)
}
_ => Err(Error::AttributeError),
}
}
}
impl super::SubControlStatic for PidsController {
fn new(_is_root: bool) -> Self {
Self { _private: () }
Self {
max_pid: AtomicU32::new(u32::MAX),
}
}
fn type_() -> super::SubCtrlType {

View File

@ -350,6 +350,10 @@ impl CgroupNode {
SysStr::from("cgroup.events"),
SysPerms::DEFAULT_RO_ATTR_PERMS,
);
builder.add(
SysStr::from("cgroup.freeze"),
SysPerms::DEFAULT_RW_ATTR_PERMS,
);
Controller::init_attr_set(&mut builder, false);
@ -597,8 +601,8 @@ inherit_sys_branch_node!(CgroupNode, fields, {
};
writeln!(printer, "populated {}", res)?;
// Currently we have not enabled the "frozen" attribute
// so the "frozen" field is always zero.
// Currently we have not enabled writing to the "cgroup.freeze"
// attribute so the "frozen" field is always zero.
writeln!(printer, "frozen {}", 0)?;
Ok::<usize, Error>(printer.bytes_written())
@ -627,6 +631,13 @@ inherit_sys_branch_node!(CgroupNode, fields, {
})
.ok_or(Error::IsDead)?
}
"cgroup.freeze" => self
.with_inner(|_| {
writeln!(printer, "0")?;
Ok::<usize, Error>(printer.bytes_written())
})
.ok_or(Error::IsDead)?,
// TODO: Add support for reading other attributes.
_ => self
// This read may target a stale controller if the cgroup's sub-controllers