Move FS things to PosixThread

This commit is contained in:
Ruihan Li
2024-12-01 11:41:23 +08:00
committed by Tate, Hongliang Tian
parent fe7e4884c9
commit 36fc1d3757
65 changed files with 268 additions and 215 deletions

View File

@ -18,7 +18,7 @@ use super::{
use crate::{
cpu::LinuxAbi,
current_userspace,
fs::{file_table::FileTable, fs_resolver::FsResolver, utils::FileCreationMask},
fs::{file_table::FileTable, thread_info::ThreadFsInfo},
prelude::*,
process::posix_thread::allocate_posix_tid,
thread::{AsThread, Tid},
@ -213,15 +213,6 @@ fn clone_child_task(
);
}
// This is valid combination in Linux. But we do not support it yet.
if !clone_flags.contains(CloneFlags::CLONE_FILES) || !clone_flags.contains(CloneFlags::CLONE_FS)
{
return_errno_with_message!(
Errno::EINVAL,
"`CLONE_THREAD` without `CLONE_FILES` or `CLONE_FS` is not supported"
);
}
let Context {
process,
posix_thread,
@ -232,6 +223,12 @@ fn clone_child_task(
// clone system V semaphore
clone_sysvsem(clone_flags)?;
// clone file table
let child_file_table = clone_files(posix_thread.file_table(), clone_flags);
// clone fs
let child_fs = clone_fs(posix_thread.fs(), clone_flags);
let child_root_vmar = process.root_vmar();
let child_user_space = {
let child_vm_space = child_root_vmar.vm_space().clone();
@ -257,7 +254,9 @@ fn clone_child_task(
let thread_builder = PosixThreadBuilder::new(child_tid, child_user_space, credentials)
.process(posix_thread.weak_process())
.sig_mask(sig_mask);
.sig_mask(sig_mask)
.file_table(child_file_table)
.fs(child_fs);
thread_builder.build()
};
@ -307,16 +306,10 @@ fn clone_child_process(
};
// clone file table
let child_file_table = clone_files(process.file_table(), clone_flags);
let child_file_table = clone_files(posix_thread.file_table(), clone_flags);
// clone fs
let child_fs = clone_fs(process.fs(), clone_flags);
// clone umask
let child_umask = {
let parent_umask = process.umask().read().get();
Arc::new(RwLock::new(FileCreationMask::new(parent_umask)))
};
let child_fs = clone_fs(posix_thread.fs(), clone_flags);
// clone sig dispositions
let child_sig_dispositions = clone_sighand(process.sig_dispositions(), clone_flags);
@ -345,6 +338,8 @@ fn clone_child_process(
PosixThreadBuilder::new(child_tid, child_user_space, credentials)
.thread_name(Some(child_thread_name))
.sig_mask(child_sig_mask)
.file_table(child_file_table)
.fs(child_fs)
};
let mut process_builder =
@ -353,9 +348,6 @@ fn clone_child_process(
process_builder
.main_thread_builder(child_thread_builder)
.process_vm(child_process_vm)
.file_table(child_file_table)
.fs(child_fs)
.umask(child_umask)
.sig_dispositions(child_sig_dispositions)
.nice(child_nice);
@ -460,14 +452,11 @@ fn clone_cpu_context(
child_context
}
fn clone_fs(
parent_fs: &Arc<RwMutex<FsResolver>>,
clone_flags: CloneFlags,
) -> Arc<RwMutex<FsResolver>> {
fn clone_fs(parent_fs: &Arc<ThreadFsInfo>, clone_flags: CloneFlags) -> Arc<ThreadFsInfo> {
if clone_flags.contains(CloneFlags::CLONE_FS) {
parent_fs.clone()
} else {
Arc::new(RwMutex::new(parent_fs.read().clone()))
Arc::new(parent_fs.as_ref().clone())
}
}

View File

@ -41,8 +41,13 @@ pub fn do_exit_group(term_status: TermStatus) {
child.enqueue_signal(signal);
}
// Close all files then exit the process
let files = current.file_table().lock().close_all();
// Close all files then exit the process.
//
// FIXME: This is obviously wrong in a number of ways, since different threads can have
// different file tables, and different processes can share the same file table.
let main_thread = current.main_thread().unwrap();
let mut files = main_thread.as_posix_thread().unwrap().file_table().lock();
files.close_all();
drop(files);
// Move children to the init process

View File

@ -6,6 +6,7 @@ use ostd::{cpu::CpuSet, task::Task, user::UserSpace};
use super::{thread_table, PosixThread};
use crate::{
fs::{file_table::FileTable, thread_info::ThreadFsInfo},
prelude::*,
process::{
posix_thread::name::ThreadName,
@ -29,6 +30,8 @@ pub struct PosixThreadBuilder {
thread_name: Option<ThreadName>,
set_child_tid: Vaddr,
clear_child_tid: Vaddr,
file_table: Option<Arc<SpinLock<FileTable>>>,
fs: Option<Arc<ThreadFsInfo>>,
sig_mask: AtomicSigMask,
sig_queues: SigQueues,
priority: Priority,
@ -44,6 +47,8 @@ impl PosixThreadBuilder {
thread_name: None,
set_child_tid: 0,
clear_child_tid: 0,
file_table: None,
fs: None,
sig_mask: AtomicSigMask::new_empty(),
sig_queues: SigQueues::new(),
priority: Priority::default(),
@ -70,6 +75,16 @@ impl PosixThreadBuilder {
self
}
pub fn file_table(mut self, file_table: Arc<SpinLock<FileTable>>) -> Self {
self.file_table = Some(file_table);
self
}
pub fn fs(mut self, fs: Arc<ThreadFsInfo>) -> Self {
self.fs = Some(fs);
self
}
pub fn sig_mask(mut self, sig_mask: AtomicSigMask) -> Self {
self.sig_mask = sig_mask;
self
@ -89,11 +104,18 @@ impl PosixThreadBuilder {
thread_name,
set_child_tid,
clear_child_tid,
file_table,
fs,
sig_mask,
sig_queues,
priority,
} = self;
let file_table =
file_table.unwrap_or_else(|| Arc::new(SpinLock::new(FileTable::new_with_stdio())));
let fs = fs.unwrap_or_else(|| Arc::new(ThreadFsInfo::default()));
Arc::new_cyclic(|weak_task| {
let posix_thread = {
let prof_clock = ProfClock::new();
@ -107,6 +129,8 @@ impl PosixThreadBuilder {
set_child_tid: Mutex::new(set_child_tid),
clear_child_tid: Mutex::new(clear_child_tid),
credentials,
file_table,
fs,
sig_mask,
sig_queues,
sig_context: Mutex::new(None),

View File

@ -20,6 +20,7 @@ use super::{
};
use crate::{
events::Observer,
fs::{file_table::FileTable, thread_info::ThreadFsInfo},
prelude::*,
process::signal::constants::SIGCONT,
thread::{AsThread, Thread, Tid},
@ -58,6 +59,12 @@ pub struct PosixThread {
/// Process credentials. At the kernel level, credentials are a per-thread attribute.
credentials: Credentials,
// Files
/// File table
file_table: Arc<SpinLock<FileTable>>,
/// File system
fs: Arc<ThreadFsInfo>,
// Signal
/// Blocked signals
sig_mask: AtomicSigMask,
@ -107,6 +114,14 @@ impl PosixThread {
&self.clear_child_tid
}
pub fn file_table(&self) -> &Arc<SpinLock<FileTable>> {
&self.file_table
}
pub fn fs(&self) -> &Arc<ThreadFsInfo> {
&self.fs
}
/// Get the reference to the signal mask of the thread.
///
/// Note that while this function offers mutable access to the signal mask,

View File

@ -8,7 +8,10 @@ use ostd::{
use super::{builder::PosixThreadBuilder, name::ThreadName, PosixThread};
use crate::{
fs::fs_resolver::{FsPath, FsResolver, AT_FDCWD},
fs::{
fs_resolver::{FsPath, AT_FDCWD},
thread_info::ThreadFsInfo,
},
prelude::*,
process::{process_vm::ProcessVm, program_loader::load_program_to_vm, Credentials, Process},
thread::{AsThread, Thread, Tid},
@ -35,22 +38,22 @@ impl AsPosixThread for Task {
/// Creates a task for running an executable file.
///
/// This function should _only_ be used to create the init user task.
#[allow(clippy::too_many_arguments)]
pub fn create_posix_task_from_executable(
tid: Tid,
credentials: Credentials,
process_vm: &ProcessVm,
fs_resolver: &FsResolver,
executable_path: &str,
process: Weak<Process>,
argv: Vec<CString>,
envp: Vec<CString>,
) -> Result<Arc<Task>> {
let elf_file = {
let fs = ThreadFsInfo::default();
let (_, elf_load_info) = {
let fs_resolver = fs.resolver().read();
let fs_path = FsPath::new(AT_FDCWD, executable_path)?;
fs_resolver.lookup(&fs_path)?
let elf_file = fs.resolver().read().lookup(&fs_path)?;
load_program_to_vm(process_vm, elf_file, argv, envp, &fs_resolver, 1)?
};
let (_, elf_load_info) = load_program_to_vm(process_vm, elf_file, argv, envp, fs_resolver, 1)?;
let vm_space = process_vm.root_vmar().vm_space().clone();
let mut cpu_ctx = UserContext::default();
@ -60,6 +63,7 @@ pub fn create_posix_task_from_executable(
let thread_name = Some(ThreadName::new_from_executable_path(executable_path)?);
let thread_builder = PosixThreadBuilder::new(tid, user_space, credentials)
.thread_name(thread_name)
.process(process);
.process(process)
.fs(Arc::new(fs));
Ok(thread_builder.build())
}

View File

@ -4,7 +4,6 @@
use super::{Pid, Process};
use crate::{
fs::{file_table::FileTable, fs_resolver::FsResolver, utils::FileCreationMask},
prelude::*,
process::{
posix_thread::{create_posix_task_from_executable, PosixThreadBuilder},
@ -27,9 +26,6 @@ pub struct ProcessBuilder<'a> {
argv: Option<Vec<CString>>,
envp: Option<Vec<CString>>,
process_vm: Option<ProcessVm>,
file_table: Option<Arc<SpinLock<FileTable>>>,
fs: Option<Arc<RwMutex<FsResolver>>>,
umask: Option<Arc<RwLock<FileCreationMask>>>,
resource_limits: Option<ResourceLimits>,
sig_dispositions: Option<Arc<Mutex<SigDispositions>>>,
credentials: Option<Credentials>,
@ -46,9 +42,6 @@ impl<'a> ProcessBuilder<'a> {
argv: None,
envp: None,
process_vm: None,
file_table: None,
fs: None,
umask: None,
resource_limits: None,
sig_dispositions: None,
credentials: None,
@ -66,21 +59,6 @@ impl<'a> ProcessBuilder<'a> {
self
}
pub fn file_table(&mut self, file_table: Arc<SpinLock<FileTable>>) -> &mut Self {
self.file_table = Some(file_table);
self
}
pub fn fs(&mut self, fs: Arc<RwMutex<FsResolver>>) -> &mut Self {
self.fs = Some(fs);
self
}
pub fn umask(&mut self, umask: Arc<RwLock<FileCreationMask>>) -> &mut Self {
self.umask = Some(umask);
self
}
pub fn resource_limits(&mut self, resource_limits: ResourceLimits) -> &mut Self {
self.resource_limits = Some(resource_limits);
self
@ -139,9 +117,6 @@ impl<'a> ProcessBuilder<'a> {
argv,
envp,
process_vm,
file_table,
fs,
umask,
resource_limits,
sig_dispositions,
credentials,
@ -150,18 +125,6 @@ impl<'a> ProcessBuilder<'a> {
let process_vm = process_vm.or_else(|| Some(ProcessVm::alloc())).unwrap();
let file_table = file_table
.or_else(|| Some(Arc::new(SpinLock::new(FileTable::new_with_stdio()))))
.unwrap();
let fs = fs
.or_else(|| Some(Arc::new(RwMutex::new(FsResolver::new()))))
.unwrap();
let umask = umask
.or_else(|| Some(Arc::new(RwLock::new(FileCreationMask::default()))))
.unwrap();
let resource_limits = resource_limits
.or_else(|| Some(ResourceLimits::default()))
.unwrap();
@ -180,9 +143,6 @@ impl<'a> ProcessBuilder<'a> {
threads,
executable_path.to_string(),
process_vm,
fs,
file_table,
umask,
resource_limits,
nice,
sig_dispositions,
@ -197,7 +157,6 @@ impl<'a> ProcessBuilder<'a> {
pid,
credentials.unwrap(),
process.vm(),
&process.fs().read(),
executable_path,
Arc::downgrade(&process),
argv.unwrap(),

View File

@ -18,7 +18,6 @@ use super::{
};
use crate::{
device::tty::open_ntty_as_controlling_terminal,
fs::{file_table::FileTable, fs_resolver::FsResolver, utils::FileCreationMask},
prelude::*,
sched::priority::{AtomicNice, Nice},
thread::{AsThread, Thread},
@ -81,12 +80,6 @@ pub struct Process {
children: Mutex<BTreeMap<Pid, Arc<Process>>>,
/// Process group
pub(super) process_group: Mutex<Weak<ProcessGroup>>,
/// File table
file_table: Arc<SpinLock<FileTable>>,
/// FsResolver
fs: Arc<RwMutex<FsResolver>>,
/// umask
umask: Arc<RwLock<FileCreationMask>>,
/// resource limits
resource_limits: Mutex<ResourceLimits>,
/// Scheduling priority nice value
@ -185,10 +178,6 @@ impl Process {
executable_path: String,
process_vm: ProcessVm,
fs: Arc<RwMutex<FsResolver>>,
file_table: Arc<SpinLock<FileTable>>,
umask: Arc<RwLock<FileCreationMask>>,
resource_limits: ResourceLimits,
nice: Nice,
sig_dispositions: Arc<Mutex<SigDispositions>>,
@ -209,9 +198,6 @@ impl Process {
parent: ParentProcess::new(parent),
children: Mutex::new(BTreeMap::new()),
process_group: Mutex::new(Weak::new()),
file_table,
fs,
umask,
sig_dispositions,
parent_death_signal: AtomicSigNum::new_empty(),
exit_signal: AtomicSigNum::new_empty(),
@ -620,20 +606,6 @@ impl Process {
self.process_vm.init_stack_reader()
}
// ************** File system ****************
pub fn file_table(&self) -> &Arc<SpinLock<FileTable>> {
&self.file_table
}
pub fn fs(&self) -> &Arc<RwMutex<FsResolver>> {
&self.fs
}
pub fn umask(&self) -> &Arc<RwLock<FileCreationMask>> {
&self.umask
}
// ****************** Signal ******************
pub fn sig_dispositions(&self) -> &Arc<Mutex<SigDispositions>> {
@ -742,9 +714,6 @@ mod test {
vec![],
String::new(),
ProcessVm::alloc(),
Arc::new(RwMutex::new(FsResolver::new())),
Arc::new(SpinLock::new(FileTable::new())),
Arc::new(RwLock::new(FileCreationMask::default())),
ResourceLimits::default(),
Nice::default(),
Arc::new(Mutex::new(SigDispositions::default())),