From 030b1c7fdfc1a73a9805f724c54d738ac83c421d Mon Sep 17 00:00:00 2001 From: LI Qing Date: Thu, 14 Oct 2021 17:00:34 +0800 Subject: [PATCH] Fix the memory leak in procfs --- src/libos/src/fs/procfs/pid/mod.rs | 37 ++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/libos/src/fs/procfs/pid/mod.rs b/src/libos/src/fs/procfs/pid/mod.rs index a3297d0b..b2e55a04 100644 --- a/src/libos/src/fs/procfs/pid/mod.rs +++ b/src/libos/src/fs/procfs/pid/mod.rs @@ -51,9 +51,6 @@ impl LockedPidDirINode { // exe let exe_inode = ProcExeSymINode::new(&file.process_ref); file.entries.insert(String::from("exe"), exe_inode); - // fd - let fd_inode = LockedProcFdDirINode::new(&file.process_ref, file.this.upgrade().unwrap()); - file.entries.insert(String::from("fd"), fd_inode); // root let root_inode = ProcRootSymINode::new(&file.process_ref); file.entries.insert(String::from("root"), root_inode); @@ -77,6 +74,16 @@ impl DirProcINode for LockedPidDirINode { if name == ".." { return Ok(Arc::clone(&file.parent)); } + // The 'fd' entry holds 1 Arc of LockedPidDirINode, so the LockedPidDirINode + // ifself will hold 2 Arcs. This makes it cannot be dropped automatically. + // We initialize the 'fd' here to avoid this. + // TODO:: Try to find a better solution. + if name == "fd" { + let fd_inode = + LockedProcFdDirINode::new(&file.process_ref, file.this.upgrade().unwrap()); + return Ok(fd_inode); + } + if let Some(inode) = file.entries.get(name) { Ok(Arc::clone(inode)) } else { @@ -90,12 +97,13 @@ impl DirProcINode for LockedPidDirINode { 1 => Ok(String::from("..")), i => { let file = self.0.read().unwrap(); - let name = file - .entries - .keys() - .nth(i - 2) - .ok_or(FsError::EntryNotFound)?; - Ok(name.to_owned()) + if let Some(name) = file.entries.keys().nth(i - 2) { + Ok(name.to_owned()) + } else if i == file.entries.len() + 2 { + Ok(String::from("fd")) + } else { + Err(FsError::EntryNotFound) + } } } } @@ -114,6 +122,17 @@ impl DirProcINode for LockedPidDirINode { write_inode_entry!(&mut ctx, name, inode, &mut total_written_len); } + // Write the fd entry + if idx <= 2 + file.entries.len() { + write_entry!( + &mut ctx, + "fd", + PROC_INO, + vfs::FileType::Dir, + &mut total_written_len + ); + } + Ok(total_written_len) } }