feat(procfs): 增强procfs文件系统功能 (#1713)

* feat(procfs): 增强procfs文件系统功能

- 在meminfo文件中添加SwapTotal和SwapFree字段
- 为/proc/<pid>目录实现动态owner方法,支持实时UID/GID查询
- 在pid/stat文件中改进tty_nr字段的获取逻辑
- 在procfs模板中为DirOps、FileOps和SymOps添加owner方法支持

Signed-off-by: longjin <longjin@DragonOS.org>
This commit is contained in:
LoGin 2026-01-29 13:28:15 +08:00 committed by GitHub
parent efb0f6eaaa
commit da1759ee20
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 54 additions and 3 deletions

View File

@ -64,6 +64,8 @@ impl MeminfoFileOps {
.as_bytes()
.to_owned(),
);
data.append(&mut format!("SwapTotal:\t{} kB\n", 0u64).as_bytes().to_owned());
data.append(&mut format!("SwapFree:\t{} kB\n", 0u64).as_bytes().to_owned());
data.append(
&mut format!("Dirty:\t\t{} kB\n", stats.file_dirty * page_kb)
.as_bytes()

View File

@ -156,6 +156,15 @@ impl PidDirOps {
}
impl DirOps for PidDirOps {
fn owner(&self) -> Option<(usize, usize)> {
let pcb = ProcessManager::find(self.pid)?;
if pcb.is_kthread() {
return Some((0, 0));
}
let cred = pcb.cred();
Some((cred.euid.data(), cred.egid.data()))
}
fn lookup_child(
&self,
dir: &ProcDir<Self>,

View File

@ -77,7 +77,11 @@ fn generate_linux_proc_stat_line(
// 尽量填真实值;拿不到的先填 0
let pgrp: usize = 0;
let session: usize = 0;
let tty_nr: i32 = 0;
let tty_nr: i32 = pcb
.sig_info_irqsave()
.tty()
.map(|tty| tty.core().device_number().new_encode_dev() as i32)
.unwrap_or(0);
let tpgid: i32 = 0;
let flags: u64 = 0;
let minflt: u64 = 0;

View File

@ -94,9 +94,17 @@ impl<Ops: DirOps> ProcDir<Ops> {
impl<Ops: DirOps + 'static> IndexNode for ProcDir<Ops> {
fn fs(&self) -> Arc<dyn FileSystem>;
fn as_any_ref(&self) -> &dyn core::any::Any;
fn metadata(&self) -> Result<Metadata, SystemError>;
fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError>;
fn metadata(&self) -> Result<Metadata, SystemError> {
let mut metadata = self.common.metadata()?;
if let Some((uid, gid)) = self.inner.owner() {
metadata.uid = uid;
metadata.gid = gid;
}
Ok(metadata)
}
fn read_at(
&self,
_offset: usize,
@ -241,6 +249,11 @@ pub trait DirOps: Sync + Send + Sized + Debug {
fn validate_child(&self, _child: &dyn IndexNode) -> bool {
true
}
/// 返回动态 owner用于 /proc/<pid> 等需要实时 UID/GID 的场景)
fn owner(&self) -> Option<(usize, usize)> {
None
}
}
pub fn lookup_child_from_table<Fp, F>(

View File

@ -105,6 +105,11 @@ pub trait FileOps: Sync + Send + Sized + Debug {
) -> Result<usize, SystemError> {
Err(SystemError::EPERM)
}
/// 返回动态 owner用于 /proc/<pid> 等需要实时 UID/GID 的场景)
fn owner(&self) -> Option<(usize, usize)> {
None
}
}
/// 为 ProcFile 实现 IndexNode trait
@ -113,9 +118,17 @@ pub trait FileOps: Sync + Send + Sized + Debug {
impl<F: FileOps + 'static> IndexNode for ProcFile<F> {
fn fs(&self) -> Arc<dyn FileSystem>;
fn as_any_ref(&self) -> &dyn core::any::Any;
fn metadata(&self) -> Result<Metadata, SystemError>;
fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError>;
fn metadata(&self) -> Result<Metadata, SystemError> {
let mut metadata = self.common.metadata()?;
if let Some((uid, gid)) = self.inner.owner() {
metadata.uid = uid;
metadata.gid = gid;
}
Ok(metadata)
}
fn read_at(
&self,
offset: usize,

View File

@ -118,6 +118,11 @@ pub trait SymOps: Sync + Send + Sized + Debug {
fn dynamic_inode_id(&self) -> Option<InodeId> {
None
}
/// 返回动态 owner用于 /proc/<pid> 等需要实时 UID/GID 的场景)
fn owner(&self) -> Option<(usize, usize)> {
None
}
}
/// 为 ProcSym 实现 IndexNode trait
@ -131,6 +136,11 @@ impl<S: SymOps + 'static> IndexNode for ProcSym<S> {
fn metadata(&self) -> Result<Metadata, SystemError> {
let mut metadata = self.common.metadata()?;
if let Some((uid, gid)) = self.inner.owner() {
metadata.uid = uid;
metadata.gid = gid;
}
// 如果 inner 提供了动态 inode ID如命名空间文件使用它
if let Some(dynamic_id) = self.inner.dynamic_inode_id() {
metadata.inode_id = dynamic_id;