|
@@ -16,8 +16,8 @@ use alloc::{
|
|
|
use cred::INIT_CRED;
|
|
|
use hashbrown::HashMap;
|
|
|
use log::{debug, error, info, warn};
|
|
|
-use process_group::{Pgid, ProcessGroup, ALL_PROCESS_GROUP};
|
|
|
-use session::{Session, Sid, ALL_SESSION};
|
|
|
+use pid::{alloc_pid, Pid, PidLink, PidType};
|
|
|
+use process_group::Pgid;
|
|
|
use system_error::SystemError;
|
|
|
|
|
|
use crate::{
|
|
@@ -36,7 +36,7 @@ use crate::{
|
|
|
},
|
|
|
ipc::{
|
|
|
signal::RestartBlock,
|
|
|
- signal_types::{SigInfo, SigPending, SignalStruct},
|
|
|
+ signal_types::{SigInfo, SigPending, SignalFlags, SignalStruct},
|
|
|
},
|
|
|
libs::{
|
|
|
align::AlignedBox,
|
|
@@ -46,8 +46,7 @@ use crate::{
|
|
|
futex::{Futex, RobustListHead},
|
|
|
},
|
|
|
lock_free_flags::LockFreeFlags,
|
|
|
- mutex::Mutex,
|
|
|
- rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
|
|
|
+ rwlock::{RwLock, RwLockReadGuard, RwLockUpgradableGuard, RwLockWriteGuard},
|
|
|
spinlock::{SpinLock, SpinLockGuard},
|
|
|
wait_queue::WaitQueue,
|
|
|
},
|
|
@@ -72,6 +71,7 @@ use crate::{
|
|
|
use timer::AlarmTimer;
|
|
|
|
|
|
use self::{cred::Cred, kthread::WorkerPrivate};
|
|
|
+use crate::process::namespace::nsproxy::NsProxy;
|
|
|
|
|
|
pub mod abi;
|
|
|
pub mod cred;
|
|
@@ -82,17 +82,20 @@ pub mod fork;
|
|
|
pub mod geteuid;
|
|
|
pub mod idle;
|
|
|
pub mod kthread;
|
|
|
+pub mod namespace;
|
|
|
pub mod pid;
|
|
|
pub mod process_group;
|
|
|
pub mod resource;
|
|
|
pub mod session;
|
|
|
+pub mod signal;
|
|
|
pub mod stdio;
|
|
|
pub mod syscall;
|
|
|
pub mod timer;
|
|
|
pub mod utils;
|
|
|
|
|
|
/// 系统中所有进程的pcb
|
|
|
-static ALL_PROCESS: SpinLock<Option<HashMap<Pid, Arc<ProcessControlBlock>>>> = SpinLock::new(None);
|
|
|
+static ALL_PROCESS: SpinLock<Option<HashMap<RawPid, Arc<ProcessControlBlock>>>> =
|
|
|
+ SpinLock::new(None);
|
|
|
|
|
|
pub static mut PROCESS_SWITCH_RESULT: Option<PerCpuVar<SwitchResult>> = None;
|
|
|
|
|
@@ -138,8 +141,6 @@ impl ProcessManager {
|
|
|
};
|
|
|
|
|
|
ALL_PROCESS.lock_irqsave().replace(HashMap::new());
|
|
|
- ALL_PROCESS_GROUP.lock_irqsave().replace(HashMap::new());
|
|
|
- ALL_SESSION.lock_irqsave().replace(HashMap::new());
|
|
|
Self::init_switch_result();
|
|
|
Self::arch_init();
|
|
|
debug!("process arch init done.");
|
|
@@ -180,12 +181,12 @@ impl ProcessManager {
|
|
|
/// 获取当前进程的pid
|
|
|
///
|
|
|
/// 如果进程管理器未初始化完成,那么返回0
|
|
|
- pub fn current_pid() -> Pid {
|
|
|
+ pub fn current_pid() -> RawPid {
|
|
|
if unlikely(unsafe { !__PROCESS_MANAGEMENT_INIT_DONE }) {
|
|
|
- return Pid(0);
|
|
|
+ return RawPid(0);
|
|
|
}
|
|
|
|
|
|
- return ProcessManager::current_pcb().pid();
|
|
|
+ return ProcessManager::current_pcb().raw_pid();
|
|
|
}
|
|
|
|
|
|
/// 增加当前进程的锁持有计数
|
|
@@ -213,7 +214,7 @@ impl ProcessManager {
|
|
|
/// ## 返回值
|
|
|
///
|
|
|
/// 如果找到了对应的进程,那么返回该进程的pcb,否则返回None
|
|
|
- pub fn find(pid: Pid) -> Option<Arc<ProcessControlBlock>> {
|
|
|
+ pub fn find(pid: RawPid) -> Option<Arc<ProcessControlBlock>> {
|
|
|
return ALL_PROCESS.lock_irqsave().as_ref()?.get(&pid).cloned();
|
|
|
}
|
|
|
|
|
@@ -231,11 +232,11 @@ impl ProcessManager {
|
|
|
.lock_irqsave()
|
|
|
.as_mut()
|
|
|
.unwrap()
|
|
|
- .insert(pcb.pid(), pcb.clone());
|
|
|
+ .insert(pcb.raw_pid(), pcb.clone());
|
|
|
}
|
|
|
|
|
|
/// ### 获取所有进程的pid
|
|
|
- pub fn get_all_processes() -> Vec<Pid> {
|
|
|
+ pub fn get_all_processes() -> Vec<RawPid> {
|
|
|
let mut pids = Vec::new();
|
|
|
for (pid, _) in ALL_PROCESS.lock_irqsave().as_ref().unwrap().iter() {
|
|
|
pids.push(*pid);
|
|
@@ -373,11 +374,13 @@ impl ProcessManager {
|
|
|
}
|
|
|
return Err(SystemError::EINTR);
|
|
|
}
|
|
|
+
|
|
|
/// 当子进程退出后向父进程发送通知
|
|
|
+ #[inline(never)]
|
|
|
fn exit_notify() {
|
|
|
let current = ProcessManager::current_pcb();
|
|
|
// 让INIT进程收养所有子进程
|
|
|
- if current.pid() != Pid(1) {
|
|
|
+ if current.raw_pid() != RawPid(1) {
|
|
|
unsafe {
|
|
|
current
|
|
|
.adopt_childen()
|
|
@@ -388,15 +391,16 @@ impl ProcessManager {
|
|
|
return;
|
|
|
}
|
|
|
let parent_pcb = r.unwrap();
|
|
|
- let r = crate::ipc::kill::kill_process(parent_pcb.pid(), Signal::SIGCHLD);
|
|
|
- if r.is_err() {
|
|
|
+
|
|
|
+ let r = crate::ipc::kill::kill_process_by_pcb(parent_pcb.clone(), Signal::SIGCHLD);
|
|
|
+ if let Err(e) = r {
|
|
|
warn!(
|
|
|
- "failed to send kill signal to {:?}'s parent pcb {:?}",
|
|
|
- current.pid(),
|
|
|
- parent_pcb.pid()
|
|
|
+ "failed to send kill signal to {:?}'s parent pcb {:?}: {:?}",
|
|
|
+ current.raw_pid(),
|
|
|
+ parent_pcb.raw_pid(),
|
|
|
+ e
|
|
|
);
|
|
|
}
|
|
|
- // todo: 这里需要向父进程发送SIGCHLD信号
|
|
|
// todo: 这里还需要根据线程组的信息,决定信号的发送
|
|
|
}
|
|
|
}
|
|
@@ -414,7 +418,7 @@ impl ProcessManager {
|
|
|
pub fn exit(exit_code: usize) -> ! {
|
|
|
// 检查是否是init进程尝试退出,如果是则产生panic
|
|
|
let current_pcb = ProcessManager::current_pcb();
|
|
|
- if current_pcb.pid() == Pid(1) {
|
|
|
+ if current_pcb.raw_pid() == RawPid(1) {
|
|
|
log::error!(
|
|
|
"Init process (pid=1) attempted to exit with code {}. This should not happen and indicates a serious system error.",
|
|
|
exit_code
|
|
@@ -428,7 +432,8 @@ impl ProcessManager {
|
|
|
// 关中断
|
|
|
let _irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
|
|
|
|
|
- let pid: Pid;
|
|
|
+ let pid: Arc<Pid>;
|
|
|
+ let raw_pid = ProcessManager::current_pid();
|
|
|
{
|
|
|
let pcb = ProcessManager::current_pcb();
|
|
|
pid = pcb.pid();
|
|
@@ -483,20 +488,24 @@ impl ProcessManager {
|
|
|
}
|
|
|
}
|
|
|
pcb.sig_info_mut().set_tty(None);
|
|
|
- pcb.clear_pg_and_session_reference();
|
|
|
drop(pcb);
|
|
|
ProcessManager::exit_notify();
|
|
|
}
|
|
|
|
|
|
__schedule(SchedMode::SM_NONE);
|
|
|
- error!("pid {pid:?} exited but sched again!");
|
|
|
+ error!("raw_pid {raw_pid:?} exited but sched again!");
|
|
|
#[allow(clippy::empty_loop)]
|
|
|
loop {
|
|
|
spin_loop();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- pub unsafe fn release(pid: Pid) {
|
|
|
+ /// 从全局进程列表中删除一个进程
|
|
|
+ ///
|
|
|
+ /// # 参数
|
|
|
+ ///
|
|
|
+ /// - `pid` : 进程的**全局** pid
|
|
|
+ pub(super) unsafe fn release(pid: RawPid) {
|
|
|
let pcb = ProcessManager::find(pid);
|
|
|
if pcb.is_some() {
|
|
|
// log::debug!("release pid {}", pid);
|
|
@@ -557,7 +566,7 @@ impl ProcessManager {
|
|
|
let cpu_id = pcb.sched_info().on_cpu();
|
|
|
|
|
|
if let Some(cpu_id) = cpu_id {
|
|
|
- if pcb.pid() == cpu_rq(cpu_id.data() as usize).current().pid() {
|
|
|
+ if pcb.raw_pid() == cpu_rq(cpu_id.data() as usize).current().raw_pid() {
|
|
|
kick_cpu(cpu_id).expect("ProcessManager::kick(): Failed to kick cpu");
|
|
|
}
|
|
|
}
|
|
@@ -578,14 +587,25 @@ pub unsafe fn switch_finish_hook() {
|
|
|
ProcessManager::switch_finish_hook();
|
|
|
}
|
|
|
|
|
|
-int_like!(Pid, AtomicPid, usize, AtomicUsize);
|
|
|
+int_like!(RawPid, AtomicRawPid, usize, AtomicUsize);
|
|
|
|
|
|
-impl fmt::Display for Pid {
|
|
|
+impl fmt::Display for RawPid {
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
write!(f, "{}", self.0)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+impl RawPid {
|
|
|
+ /// 该RawPid暂未分配,待会会初始化它。
|
|
|
+ /// 这个状态只应当出现在进程/线程创建的过程中
|
|
|
+ pub const UNASSIGNED: RawPid = RawPid(usize::MAX - 1);
|
|
|
+ pub const MAX_VALID: RawPid = RawPid(usize::MAX - 32);
|
|
|
+
|
|
|
+ pub fn is_valid(&self) -> bool {
|
|
|
+ self.0 >= Self::MAX_VALID.0
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
|
pub enum ProcessState {
|
|
|
/// The process is running on a CPU or in a run queue.
|
|
@@ -668,6 +688,8 @@ bitflags! {
|
|
|
const HAS_PENDING_SIGNAL = 1 << 9;
|
|
|
/// 进程需要恢复之前保存的信号掩码
|
|
|
const RESTORE_SIG_MASK = 1 << 10;
|
|
|
+ /// Forked but didn't exec
|
|
|
+ const FORKNOEXEC = 1 << 11;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -694,9 +716,17 @@ impl ProcessFlags {
|
|
|
#[derive(Debug)]
|
|
|
pub struct ProcessControlBlock {
|
|
|
/// 当前进程的pid
|
|
|
- pid: Pid,
|
|
|
+ pid: RawPid,
|
|
|
/// 当前进程的线程组id(这个值在同一个线程组内永远不变)
|
|
|
- tgid: Pid,
|
|
|
+ tgid: RawPid,
|
|
|
+
|
|
|
+ thread_pid: RwLock<Option<Arc<Pid>>>,
|
|
|
+ /// PID链接数组
|
|
|
+ pid_links: [PidLink; PidType::PIDTYPE_MAX],
|
|
|
+
|
|
|
+ /// namespace代理
|
|
|
+ nsproxy: RwLock<Arc<NsProxy>>,
|
|
|
+
|
|
|
basic: RwLock<ProcessBasicInfo>,
|
|
|
/// 当前进程的自旋锁持有计数
|
|
|
preempt_count: AtomicUsize,
|
|
@@ -726,7 +756,7 @@ pub struct ProcessControlBlock {
|
|
|
real_parent_pcb: RwLock<Weak<ProcessControlBlock>>,
|
|
|
|
|
|
/// 子进程链表
|
|
|
- children: RwLock<Vec<Pid>>,
|
|
|
+ children: RwLock<Vec<RawPid>>,
|
|
|
|
|
|
/// 等待队列
|
|
|
wait_queue: WaitQueue,
|
|
@@ -744,14 +774,11 @@ pub struct ProcessControlBlock {
|
|
|
robust_list: RwLock<Option<RobustListHead>>,
|
|
|
|
|
|
/// 进程作为主体的凭证集
|
|
|
- cred: SpinLock<Cred>,
|
|
|
+ cred: SpinLock<Arc<Cred>>,
|
|
|
self_ref: Weak<ProcessControlBlock>,
|
|
|
|
|
|
restart_block: SpinLock<Option<RestartBlock>>,
|
|
|
|
|
|
- /// 进程组
|
|
|
- process_group: Mutex<Weak<ProcessGroup>>,
|
|
|
-
|
|
|
/// 进程的可执行文件路径
|
|
|
executable_path: RwLock<String>,
|
|
|
}
|
|
@@ -792,17 +819,41 @@ impl ProcessControlBlock {
|
|
|
|
|
|
#[inline(never)]
|
|
|
fn do_create_pcb(name: String, kstack: KernelStack, is_idle: bool) -> Arc<Self> {
|
|
|
- let (pid, ppid, cwd, cred, tty) = if is_idle {
|
|
|
+ // 初始化namespace代理
|
|
|
+ let nsproxy = if is_idle {
|
|
|
+ // idle进程使用root namespace
|
|
|
+ NsProxy::new_root()
|
|
|
+ } else {
|
|
|
+ // 其他进程继承父进程的namespace
|
|
|
+ ProcessManager::current_pcb().nsproxy().clone()
|
|
|
+ };
|
|
|
+
|
|
|
+ let (raw_pid, ppid, cwd, cred, tty): (
|
|
|
+ RawPid,
|
|
|
+ RawPid,
|
|
|
+ String,
|
|
|
+ Arc<Cred>,
|
|
|
+ Option<Arc<TtyCore>>,
|
|
|
+ ) = if is_idle {
|
|
|
let cred = INIT_CRED.clone();
|
|
|
- (Pid(0), Pid(0), "/".to_string(), cred, None)
|
|
|
+ (RawPid(0), RawPid(0), "/".to_string(), cred, None)
|
|
|
} else {
|
|
|
- let ppid = ProcessManager::current_pcb().pid();
|
|
|
- let mut cred = ProcessManager::current_pcb().cred();
|
|
|
- cred.cap_permitted = cred.cap_ambient;
|
|
|
- cred.cap_effective = cred.cap_ambient;
|
|
|
+ let ppid = ProcessManager::current_pcb().task_pid_vnr();
|
|
|
+ let cred = ProcessManager::current_pcb().cred();
|
|
|
+ if cred.cap_ambient != cred.cap_permitted || cred.cap_ambient != cred.cap_effective {
|
|
|
+ todo!("create a new cred for child.")
|
|
|
+ // cred.cap_permitted = cred.cap_ambient;
|
|
|
+ // cred.cap_effective = cred.cap_ambient;
|
|
|
+ }
|
|
|
+
|
|
|
let cwd = ProcessManager::current_pcb().basic().cwd();
|
|
|
let tty = ProcessManager::current_pcb().sig_info_irqsave().tty();
|
|
|
- (Self::generate_pid(), ppid, cwd, cred, tty)
|
|
|
+
|
|
|
+ // Here, UNASSIGNED is used to represent an unallocated pid,
|
|
|
+ // which will be allocated later in `copy_process`.
|
|
|
+ let raw_pid = RawPid::UNASSIGNED;
|
|
|
+
|
|
|
+ (raw_pid, ppid, cwd, cred, tty)
|
|
|
};
|
|
|
|
|
|
let basic_info = ProcessBasicInfo::new(ppid, name.clone(), cwd, None);
|
|
@@ -811,16 +862,20 @@ impl ProcessControlBlock {
|
|
|
|
|
|
let sched_info = ProcessSchedulerInfo::new(None);
|
|
|
|
|
|
- let ppcb: Weak<ProcessControlBlock> = ProcessManager::find(ppid)
|
|
|
+ let ppcb: Weak<ProcessControlBlock> = ProcessManager::find_task_by_vpid(ppid)
|
|
|
.map(|p| Arc::downgrade(&p))
|
|
|
.unwrap_or_default();
|
|
|
|
|
|
// 使用 Arc::new_cyclic 避免在栈上创建巨大的结构体
|
|
|
let pcb = Arc::new_cyclic(|weak| {
|
|
|
let arch_info = SpinLock::new(ArchPCBInfo::new(&kstack));
|
|
|
+
|
|
|
let pcb = Self {
|
|
|
- pid,
|
|
|
- tgid: pid,
|
|
|
+ pid: raw_pid,
|
|
|
+ tgid: raw_pid,
|
|
|
+ thread_pid: RwLock::new(None),
|
|
|
+ pid_links: core::array::from_fn(|_| PidLink::default()),
|
|
|
+ nsproxy: RwLock::new(nsproxy),
|
|
|
basic: basic_info,
|
|
|
preempt_count,
|
|
|
flags,
|
|
@@ -843,7 +898,6 @@ impl ProcessControlBlock {
|
|
|
cred: SpinLock::new(cred),
|
|
|
self_ref: weak.clone(),
|
|
|
restart_block: SpinLock::new(None),
|
|
|
- process_group: Mutex::new(Weak::new()),
|
|
|
executable_path: RwLock::new(name),
|
|
|
};
|
|
|
|
|
@@ -875,45 +929,9 @@ impl ProcessControlBlock {
|
|
|
.unwrap()
|
|
|
};
|
|
|
|
|
|
- // 将当前pcb加入父进程的子进程哈希表中
|
|
|
- if pcb.pid() > Pid(1) {
|
|
|
- if let Some(ppcb_arc) = pcb.parent_pcb.read_irqsave().upgrade() {
|
|
|
- let mut children = ppcb_arc.children.write_irqsave();
|
|
|
- children.push(pcb.pid());
|
|
|
- } else {
|
|
|
- panic!("parent pcb is None");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if pcb.pid() > Pid(0) && !is_idle {
|
|
|
- let process_group = ProcessGroup::new(pcb.clone());
|
|
|
- *pcb.process_group.lock() = Arc::downgrade(&process_group);
|
|
|
- ProcessManager::add_process_group(process_group.clone());
|
|
|
-
|
|
|
- let session = Session::new(process_group.clone());
|
|
|
- process_group.process_group_inner.lock().session = Arc::downgrade(&session);
|
|
|
- session.session_inner.lock().leader = Some(pcb.clone());
|
|
|
- ProcessManager::add_session(session);
|
|
|
-
|
|
|
- ProcessManager::add_pcb(pcb.clone());
|
|
|
- }
|
|
|
- // log::debug!(
|
|
|
- // "A new process is created, pid: {:?}, pgid: {:?}, sid: {:?}",
|
|
|
- // pcb.pid(),
|
|
|
- // pcb.process_group().unwrap().pgid(),
|
|
|
- // pcb.session().unwrap().sid()
|
|
|
- // );
|
|
|
-
|
|
|
return pcb;
|
|
|
}
|
|
|
|
|
|
- /// 生成一个新的pid
|
|
|
- #[inline(always)]
|
|
|
- fn generate_pid() -> Pid {
|
|
|
- static NEXT_PID: AtomicPid = AtomicPid::new(Pid(1));
|
|
|
- return NEXT_PID.fetch_add(Pid(1), Ordering::SeqCst);
|
|
|
- }
|
|
|
-
|
|
|
/// 返回当前进程的锁持有计数
|
|
|
#[inline(always)]
|
|
|
pub fn preempt_count(&self) -> usize {
|
|
@@ -938,7 +956,7 @@ impl ProcessControlBlock {
|
|
|
}
|
|
|
|
|
|
#[inline(always)]
|
|
|
- pub fn contain_child(&self, pid: &Pid) -> bool {
|
|
|
+ pub fn contain_child(&self, pid: &RawPid) -> bool {
|
|
|
let children = self.children.read();
|
|
|
return children.contains(pid);
|
|
|
}
|
|
@@ -1010,15 +1028,10 @@ impl ProcessControlBlock {
|
|
|
}
|
|
|
|
|
|
#[inline(always)]
|
|
|
- pub fn pid(&self) -> Pid {
|
|
|
+ pub fn raw_pid(&self) -> RawPid {
|
|
|
return self.pid;
|
|
|
}
|
|
|
|
|
|
- #[inline(always)]
|
|
|
- pub fn tgid(&self) -> Pid {
|
|
|
- return self.tgid;
|
|
|
- }
|
|
|
-
|
|
|
#[inline(always)]
|
|
|
pub fn fs_struct(&self) -> Arc<FsStruct> {
|
|
|
self.fs.read().clone()
|
|
@@ -1039,7 +1052,7 @@ impl ProcessControlBlock {
|
|
|
}
|
|
|
|
|
|
#[inline(always)]
|
|
|
- pub fn cred(&self) -> Cred {
|
|
|
+ pub fn cred(&self) -> Arc<Cred> {
|
|
|
self.cred.lock().clone()
|
|
|
}
|
|
|
|
|
@@ -1051,6 +1064,15 @@ impl ProcessControlBlock {
|
|
|
self.executable_path.read().clone()
|
|
|
}
|
|
|
|
|
|
+ pub fn real_parent_pcb(&self) -> Option<Arc<ProcessControlBlock>> {
|
|
|
+ return self.real_parent_pcb.read_irqsave().upgrade();
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 判断当前进程是否是全局的init进程
|
|
|
+ pub fn is_global_init(&self) -> bool {
|
|
|
+ self.task_tgid_vnr().unwrap() == RawPid(1)
|
|
|
+ }
|
|
|
+
|
|
|
/// 根据文件描述符序号,获取socket对象的Arc指针
|
|
|
///
|
|
|
/// ## 参数
|
|
@@ -1079,12 +1101,53 @@ impl ProcessControlBlock {
|
|
|
|
|
|
/// 当前进程退出时,让初始进程收养所有子进程
|
|
|
unsafe fn adopt_childen(&self) -> Result<(), SystemError> {
|
|
|
- match ProcessManager::find(Pid(1)) {
|
|
|
+ match ProcessManager::find_task_by_vpid(RawPid(1)) {
|
|
|
Some(init_pcb) => {
|
|
|
let childen_guard = self.children.write();
|
|
|
+ if Arc::ptr_eq(&self.self_ref.upgrade().unwrap(), &init_pcb) {
|
|
|
+ // 当前进程是namespace的init进程,由父进程所在的pidns的init进程去收养子进程
|
|
|
+ if let Some(parent_pcb) = self.real_parent_pcb() {
|
|
|
+ assert!(
|
|
|
+ !Arc::ptr_eq(&parent_pcb, &init_pcb),
|
|
|
+ "adopt_childen: parent_pcb is init_pcb, pid: {}",
|
|
|
+ self.raw_pid()
|
|
|
+ );
|
|
|
+ let parent_init = ProcessManager::find_task_by_pid_ns(
|
|
|
+ RawPid(1),
|
|
|
+ &parent_pcb.active_pid_ns(),
|
|
|
+ );
|
|
|
+ if parent_init.is_none() {
|
|
|
+ log::warn!(
|
|
|
+ "adopt_childen: parent_init is None, pid: {}",
|
|
|
+ self.raw_pid()
|
|
|
+ );
|
|
|
+ return Ok(());
|
|
|
+ }
|
|
|
+ let parent_init = parent_init.unwrap();
|
|
|
+ let mut parent_children_guard = parent_init.children.write();
|
|
|
+ childen_guard.iter().for_each(|pid| {
|
|
|
+ log::debug!(
|
|
|
+ "adopt_childen: pid {} is adopted by parent init pid {}",
|
|
|
+ pid,
|
|
|
+ parent_init.raw_pid()
|
|
|
+ );
|
|
|
+ parent_children_guard.push(*pid);
|
|
|
+ });
|
|
|
+
|
|
|
+ return Ok(());
|
|
|
+ } else {
|
|
|
+ log::warn!("adopt_childen: parent_pcb is None, pid: {}", self.raw_pid());
|
|
|
+ return Ok(());
|
|
|
+ }
|
|
|
+ }
|
|
|
let mut init_childen_guard = init_pcb.children.write();
|
|
|
|
|
|
childen_guard.iter().for_each(|pid| {
|
|
|
+ log::debug!(
|
|
|
+ "adopt_childen: pid {} is adopted by init pid {}",
|
|
|
+ pid,
|
|
|
+ init_pcb.raw_pid()
|
|
|
+ );
|
|
|
init_childen_guard.push(*pid);
|
|
|
});
|
|
|
|
|
@@ -1108,6 +1171,10 @@ impl ProcessControlBlock {
|
|
|
self.sig_info.read_irqsave()
|
|
|
}
|
|
|
|
|
|
+ pub fn sig_info_upgradable(&self) -> RwLockUpgradableGuard<ProcessSignalInfo> {
|
|
|
+ self.sig_info.upgradeable_read_irqsave()
|
|
|
+ }
|
|
|
+
|
|
|
pub fn try_siginfo_irqsave(&self, times: u8) -> Option<RwLockReadGuard<ProcessSignalInfo>> {
|
|
|
for _ in 0..times {
|
|
|
if let Some(r) = self.sig_info.try_read_irqsave() {
|
|
@@ -1205,7 +1272,7 @@ impl ProcessControlBlock {
|
|
|
drop(old)
|
|
|
}
|
|
|
|
|
|
- pub fn children_read_irqsave(&self) -> RwLockReadGuard<Vec<Pid>> {
|
|
|
+ pub fn children_read_irqsave(&self) -> RwLockReadGuard<Vec<RawPid>> {
|
|
|
self.children.read_irqsave()
|
|
|
}
|
|
|
|
|
@@ -1213,6 +1280,10 @@ impl ProcessControlBlock {
|
|
|
self.thread.read_irqsave()
|
|
|
}
|
|
|
|
|
|
+ pub fn threads_write_irqsave(&self) -> RwLockWriteGuard<ThreadInfo> {
|
|
|
+ self.thread.write_irqsave()
|
|
|
+ }
|
|
|
+
|
|
|
pub fn restart_block(&self) -> SpinLockGuard<Option<RestartBlock>> {
|
|
|
self.restart_block.lock()
|
|
|
}
|
|
@@ -1235,19 +1306,50 @@ impl ProcessControlBlock {
|
|
|
.state()
|
|
|
.is_exited()
|
|
|
}
|
|
|
+
|
|
|
+ pub fn exit_code(&self) -> Option<usize> {
|
|
|
+ self.sched_info
|
|
|
+ .inner_lock_read_irqsave()
|
|
|
+ .state()
|
|
|
+ .exit_code()
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 获取进程的namespace代理
|
|
|
+ pub fn nsproxy(&self) -> Arc<NsProxy> {
|
|
|
+ self.nsproxy.read().clone()
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 设置进程的namespace代理
|
|
|
+ ///
|
|
|
+ /// ## 参数
|
|
|
+ /// - `nsproxy` : 新的namespace代理
|
|
|
+ ///
|
|
|
+ /// ## 返回值
|
|
|
+ /// 返回旧的namespace代理
|
|
|
+ pub fn set_nsproxy(&self, nsproxy: Arc<NsProxy>) -> Arc<NsProxy> {
|
|
|
+ let mut guard = self.nsproxy.write();
|
|
|
+ let old = guard.clone();
|
|
|
+ *guard = nsproxy;
|
|
|
+ return old;
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn is_thread_group_leader(&self) -> bool {
|
|
|
+ self.exit_signal.load(Ordering::SeqCst) != Signal::INVALID
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
impl Drop for ProcessControlBlock {
|
|
|
fn drop(&mut self) {
|
|
|
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
|
|
+ // log::debug!("Drop ProcessControlBlock: pid: {}", self.raw_pid(),);
|
|
|
+ self.__exit_signal();
|
|
|
// 在ProcFS中,解除进程的注册
|
|
|
- procfs_unregister_pid(self.pid())
|
|
|
- .unwrap_or_else(|e| panic!("procfs_unregister_pid failed: error: {e:?}"));
|
|
|
-
|
|
|
+ procfs_unregister_pid(self.raw_pid())
|
|
|
+ .unwrap_or_else(|e: SystemError| panic!("procfs_unregister_pid failed: error: {e:?}"));
|
|
|
if let Some(ppcb) = self.parent_pcb.read_irqsave().upgrade() {
|
|
|
ppcb.children
|
|
|
.write_irqsave()
|
|
|
- .retain(|pid| *pid != self.pid());
|
|
|
+ .retain(|pid| *pid != self.raw_pid());
|
|
|
}
|
|
|
|
|
|
// log::debug!("Drop pid: {:?}", self.pid());
|
|
@@ -1265,6 +1367,9 @@ pub struct ThreadInfo {
|
|
|
vfork_done: Option<Arc<Completion>>,
|
|
|
/// 线程组的组长
|
|
|
group_leader: Weak<ProcessControlBlock>,
|
|
|
+
|
|
|
+ /// 当前线程为组长时,该字段存储组内所有线程的pcb
|
|
|
+ group_tasks: Vec<Weak<ProcessControlBlock>>,
|
|
|
}
|
|
|
|
|
|
impl Default for ThreadInfo {
|
|
@@ -1280,12 +1385,24 @@ impl ThreadInfo {
|
|
|
set_child_tid: None,
|
|
|
vfork_done: None,
|
|
|
group_leader: Weak::default(),
|
|
|
+ group_tasks: Vec::new(),
|
|
|
}
|
|
|
}
|
|
|
|
|
|
pub fn group_leader(&self) -> Option<Arc<ProcessControlBlock>> {
|
|
|
return self.group_leader.upgrade();
|
|
|
}
|
|
|
+
|
|
|
+ pub fn thread_group_empty(&self) -> bool {
|
|
|
+ let group_leader = self.group_leader();
|
|
|
+ if let Some(leader) = group_leader {
|
|
|
+ if Arc::ptr_eq(&leader, &ProcessManager::current_pcb()) {
|
|
|
+ return self.group_tasks.is_empty();
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// 进程的基本信息
|
|
@@ -1294,7 +1411,7 @@ impl ThreadInfo {
|
|
|
#[derive(Debug)]
|
|
|
pub struct ProcessBasicInfo {
|
|
|
/// 当前进程的父进程的pid
|
|
|
- ppid: Pid,
|
|
|
+ ppid: RawPid,
|
|
|
/// 进程的名字
|
|
|
name: String,
|
|
|
|
|
@@ -1311,7 +1428,7 @@ pub struct ProcessBasicInfo {
|
|
|
impl ProcessBasicInfo {
|
|
|
#[inline(never)]
|
|
|
pub fn new(
|
|
|
- ppid: Pid,
|
|
|
+ ppid: RawPid,
|
|
|
name: String,
|
|
|
cwd: String,
|
|
|
user_vm: Option<Arc<AddressSpace>>,
|
|
@@ -1326,7 +1443,7 @@ impl ProcessBasicInfo {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- pub fn ppid(&self) -> Pid {
|
|
|
+ pub fn ppid(&self) -> RawPid {
|
|
|
return self.ppid;
|
|
|
}
|
|
|
|
|
@@ -1863,8 +1980,18 @@ pub struct ProcessSignalInfo {
|
|
|
sig_pending: SigPending,
|
|
|
// sig_shared_pending 中存储当前线程所属进程要处理的信号
|
|
|
sig_shared_pending: SigPending,
|
|
|
+ flags: SignalFlags,
|
|
|
// 当前进程对应的tty
|
|
|
tty: Option<Arc<TtyCore>>,
|
|
|
+ has_child_subreaper: bool,
|
|
|
+
|
|
|
+ /// 标记当前进程是否是一个“子进程收割者”
|
|
|
+ ///
|
|
|
+ /// todo: 在prctl里面实现设置这个标志位的功能
|
|
|
+ is_child_subreaper: bool,
|
|
|
+
|
|
|
+ /// boolean value for session group leader
|
|
|
+ pub is_session_leader: bool,
|
|
|
}
|
|
|
|
|
|
impl ProcessSignalInfo {
|
|
@@ -1908,6 +2035,10 @@ impl ProcessSignalInfo {
|
|
|
self.tty = tty;
|
|
|
}
|
|
|
|
|
|
+ pub fn flags(&self) -> SignalFlags {
|
|
|
+ self.flags
|
|
|
+ }
|
|
|
+
|
|
|
/// 从 pcb 的 siginfo中取出下一个要处理的信号,先处理线程信号,再处理进程信号
|
|
|
///
|
|
|
/// ## 参数
|
|
@@ -1929,6 +2060,22 @@ impl ProcessSignalInfo {
|
|
|
return res;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ pub fn has_child_subreaper(&self) -> bool {
|
|
|
+ self.has_child_subreaper
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn set_has_child_subreaper(&mut self, has_child_subreaper: bool) {
|
|
|
+ self.has_child_subreaper = has_child_subreaper;
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn is_child_subreaper(&self) -> bool {
|
|
|
+ self.is_child_subreaper
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn set_is_child_subreaper(&mut self, is_child_subreaper: bool) {
|
|
|
+ self.is_child_subreaper = is_child_subreaper;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
impl Default for ProcessSignalInfo {
|
|
@@ -1939,6 +2086,10 @@ impl Default for ProcessSignalInfo {
|
|
|
sig_pending: SigPending::default(),
|
|
|
sig_shared_pending: SigPending::default(),
|
|
|
tty: None,
|
|
|
+ has_child_subreaper: false,
|
|
|
+ is_child_subreaper: false,
|
|
|
+ is_session_leader: false,
|
|
|
+ flags: SignalFlags::empty(),
|
|
|
}
|
|
|
}
|
|
|
}
|