process.rs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. use super::{
  2. process_group::ProcessGroupBuilder, signal::RaiseResult, thread::ThreadBuilder, ProcessGroup,
  3. ProcessList, Session, Signal, Thread,
  4. };
  5. use crate::{
  6. kernel::mem::MMList,
  7. prelude::*,
  8. rcu::{rcu_sync, RCUPointer, RCUReadGuard},
  9. sync::{CondVar, RwSemReadGuard, SpinGuard},
  10. };
  11. use alloc::{
  12. collections::{btree_map::BTreeMap, vec_deque::VecDeque},
  13. sync::{Arc, Weak},
  14. };
  15. use bindings::{ECHILD, EINTR, EPERM, ESRCH};
  16. use core::sync::atomic::{AtomicU32, Ordering};
  17. use eonix_sync::{AsProof as _, AsProofMut as _, Locked, Proof, ProofMut};
  18. use pointers::BorrowedArc;
  19. pub struct ProcessBuilder {
  20. mm_list: Option<MMList>,
  21. parent: Option<Arc<Process>>,
  22. thread_builder: Option<ThreadBuilder>,
  23. pgroup: Option<Arc<ProcessGroup>>,
  24. session: Option<Arc<Session>>,
  25. }
  26. #[derive(Debug)]
  27. pub struct Process {
  28. /// Process id
  29. ///
  30. /// This should never change during the life of the process.
  31. pub pid: u32,
  32. pub wait_list: WaitList,
  33. pub mm_list: MMList,
  34. /// Parent process
  35. ///
  36. /// `parent` must be valid during the whole life of the process.
  37. /// The only case where it may be `None` is when it is the init process
  38. /// or the process is kernel thread.
  39. pub(super) parent: RCUPointer<Process>,
  40. /// Process group
  41. ///
  42. /// `pgroup` must be valid during the whole life of the process.
  43. /// The only case where it may be `None` is when the process is kernel thread.
  44. pub(super) pgroup: RCUPointer<ProcessGroup>,
  45. /// Session
  46. ///
  47. /// `session` must be valid during the whole life of the process.
  48. /// The only case where it may be `None` is when the process is kernel thread.
  49. pub(super) session: RCUPointer<Session>,
  50. /// All things related to the process list.
  51. pub(super) inner: Locked<ProcessInner, ProcessList>,
  52. }
  53. #[derive(Debug)]
  54. pub(super) struct ProcessInner {
  55. pub(super) children: BTreeMap<u32, Weak<Process>>,
  56. pub(super) threads: BTreeMap<u32, Weak<Thread>>,
  57. }
  58. #[derive(Debug)]
  59. pub struct WaitList {
  60. wait_procs: Spin<VecDeque<WaitObject>>,
  61. cv_wait_procs: CondVar,
  62. }
  63. pub struct NotifyBatch<'waitlist, 'process, 'cv> {
  64. wait_procs: SpinGuard<'waitlist, VecDeque<WaitObject>>,
  65. process: &'process Process,
  66. cv: &'cv CondVar,
  67. needs_notify: bool,
  68. }
  69. pub struct Entry<'waitlist, 'proclist, 'cv> {
  70. wait_procs: SpinGuard<'waitlist, VecDeque<WaitObject>>,
  71. process_list: RwSemReadGuard<'proclist, ProcessList>,
  72. cv: &'cv CondVar,
  73. want_stop: bool,
  74. want_continue: bool,
  75. }
  76. pub struct DrainExited<'waitlist> {
  77. wait_procs: SpinGuard<'waitlist, VecDeque<WaitObject>>,
  78. }
  79. #[derive(Debug, Clone, Copy, PartialEq, Eq)]
  80. pub enum WaitType {
  81. Exited(u32),
  82. Signaled(Signal),
  83. Stopped(Signal),
  84. Continued,
  85. }
  86. #[derive(Debug, Clone, Copy)]
  87. pub struct WaitObject {
  88. pub pid: u32,
  89. pub code: WaitType,
  90. }
  91. impl WaitType {
  92. pub fn to_wstatus(self) -> u32 {
  93. match self {
  94. WaitType::Exited(status) => (status & 0xff) << 8,
  95. WaitType::Signaled(signal) if signal.is_coredump() => u32::from(signal) | 0x80,
  96. WaitType::Signaled(signal) => u32::from(signal),
  97. WaitType::Stopped(signal) => 0x7f | (u32::from(signal) << 8),
  98. WaitType::Continued => 0xffff,
  99. }
  100. }
  101. }
  102. impl WaitObject {
  103. pub fn stopped(&self) -> Option<Signal> {
  104. if let WaitType::Stopped(signal) = self.code {
  105. Some(signal)
  106. } else {
  107. None
  108. }
  109. }
  110. pub fn is_continue(&self) -> bool {
  111. matches!(self.code, WaitType::Continued)
  112. }
  113. }
  114. impl ProcessBuilder {
  115. pub fn new() -> Self {
  116. Self {
  117. mm_list: None,
  118. parent: None,
  119. thread_builder: None,
  120. pgroup: None,
  121. session: None,
  122. }
  123. }
  124. pub fn mm_list(mut self, mm_list: MMList) -> Self {
  125. self.mm_list = Some(mm_list);
  126. self
  127. }
  128. pub fn parent(mut self, parent: Arc<Process>) -> Self {
  129. self.parent = Some(parent);
  130. self
  131. }
  132. pub fn thread_builder(mut self, thread_builder: ThreadBuilder) -> Self {
  133. self.thread_builder = Some(thread_builder);
  134. self
  135. }
  136. pub fn pgroup(mut self, pgroup: Arc<ProcessGroup>) -> Self {
  137. self.pgroup = Some(pgroup);
  138. self
  139. }
  140. pub fn session(mut self, session: Arc<Session>) -> Self {
  141. self.session = Some(session);
  142. self
  143. }
  144. fn alloc_pid() -> u32 {
  145. static NEXT_PID: AtomicU32 = AtomicU32::new(1);
  146. NEXT_PID.fetch_add(1, Ordering::Relaxed)
  147. }
  148. pub fn build(self, process_list: &mut ProcessList) -> (Arc<Thread>, Arc<Process>) {
  149. let mm_list = self.mm_list.unwrap_or_else(|| MMList::new());
  150. let process = Arc::new(Process {
  151. pid: Self::alloc_pid(),
  152. wait_list: WaitList::new(),
  153. mm_list,
  154. parent: RCUPointer::empty(),
  155. pgroup: RCUPointer::empty(),
  156. session: RCUPointer::empty(),
  157. inner: Locked::new(
  158. ProcessInner {
  159. children: BTreeMap::new(),
  160. threads: BTreeMap::new(),
  161. },
  162. process_list,
  163. ),
  164. });
  165. process_list.add_process(&process);
  166. let thread_builder = self.thread_builder.expect("Thread builder is not set");
  167. let thread = thread_builder
  168. .process(process.clone())
  169. .tid(process.pid)
  170. .build(process_list);
  171. let session = match self.session {
  172. Some(session) => session,
  173. None => Session::new(&process, process_list),
  174. };
  175. let pgroup = match self.pgroup {
  176. Some(pgroup) => {
  177. pgroup.add_member(&process, process_list.prove_mut());
  178. pgroup
  179. }
  180. None => ProcessGroupBuilder::new()
  181. .leader(&process)
  182. .session(session.clone())
  183. .build(process_list),
  184. };
  185. if let Some(parent) = &self.parent {
  186. parent.add_child(&process, process_list.prove_mut());
  187. }
  188. // SAFETY: We are holding the process list lock.
  189. unsafe {
  190. process.parent.swap(self.parent);
  191. process.pgroup.swap(Some(pgroup));
  192. process.session.swap(Some(session));
  193. }
  194. (thread, process)
  195. }
  196. }
  197. impl Process {
  198. pub fn raise(&self, signal: Signal, procs: Proof<'_, ProcessList>) {
  199. let inner = self.inner.access(procs);
  200. for thread in inner.threads.values().map(|t| t.upgrade().unwrap()) {
  201. if let RaiseResult::Finished = thread.raise(signal) {
  202. break;
  203. }
  204. }
  205. }
  206. pub(super) fn add_child(&self, child: &Arc<Process>, procs: ProofMut<'_, ProcessList>) {
  207. assert!(self
  208. .inner
  209. .access_mut(procs)
  210. .children
  211. .insert(child.pid, Arc::downgrade(child))
  212. .is_none());
  213. }
  214. pub(super) fn add_thread(&self, thread: &Arc<Thread>, procs: ProofMut<'_, ProcessList>) {
  215. assert!(self
  216. .inner
  217. .access_mut(procs)
  218. .threads
  219. .insert(thread.tid, Arc::downgrade(thread))
  220. .is_none());
  221. }
  222. pub fn wait(
  223. &self,
  224. no_block: bool,
  225. trace_stop: bool,
  226. trace_continue: bool,
  227. ) -> KResult<Option<WaitObject>> {
  228. let wait_object = {
  229. let mut waits = self.wait_list.entry(trace_stop, trace_continue);
  230. loop {
  231. if let Some(object) = waits.get() {
  232. break object;
  233. }
  234. if self
  235. .inner
  236. .access(waits.process_list.prove())
  237. .children
  238. .is_empty()
  239. {
  240. return Err(ECHILD);
  241. }
  242. if no_block {
  243. return Ok(None);
  244. }
  245. waits.wait()?;
  246. }
  247. };
  248. if wait_object.stopped().is_some() || wait_object.is_continue() {
  249. Ok(Some(wait_object))
  250. } else {
  251. let mut procs = ProcessList::get().lock();
  252. procs.remove_process(wait_object.pid);
  253. assert!(self
  254. .inner
  255. .access_mut(procs.prove_mut())
  256. .children
  257. .remove(&wait_object.pid)
  258. .is_some());
  259. Ok(Some(wait_object))
  260. }
  261. }
  262. /// Create a new session for the process.
  263. pub fn setsid(self: &Arc<Self>) -> KResult<u32> {
  264. let mut process_list = ProcessList::get().lock();
  265. // If there exists a session that has the same sid as our pid, we can't create a new
  266. // session. The standard says that we should create a new process group and be the
  267. // only process in the new process group and session.
  268. if process_list.try_find_session(self.pid).is_some() {
  269. return Err(EPERM);
  270. }
  271. let session = Session::new(self, &mut process_list);
  272. let pgroup = ProcessGroupBuilder::new()
  273. .leader(self)
  274. .session(session.clone())
  275. .build(&mut process_list);
  276. {
  277. let _old_session = unsafe { self.session.swap(Some(session.clone())) }.unwrap();
  278. let old_pgroup = unsafe { self.pgroup.swap(Some(pgroup.clone())) }.unwrap();
  279. old_pgroup.remove_member(self.pid, process_list.prove_mut());
  280. rcu_sync();
  281. }
  282. Ok(pgroup.pgid)
  283. }
  284. /// Set the process group id of the process to `pgid`.
  285. ///
  286. /// This function does the actual work.
  287. fn do_setpgid(self: &Arc<Self>, pgid: u32, procs: &mut ProcessList) -> KResult<()> {
  288. // SAFETY: We are holding the process list lock.
  289. let session = unsafe { self.session.load_locked().unwrap() };
  290. let pgroup = unsafe { self.pgroup.load_locked().unwrap() };
  291. // Changing the process group of a session leader is not allowed.
  292. if session.sid == self.pid {
  293. return Err(EPERM);
  294. }
  295. let new_pgroup = if let Some(new_pgroup) = procs.try_find_pgroup(pgid) {
  296. // Move us to an existing process group.
  297. // Check that the two groups are in the same session.
  298. if new_pgroup.session.upgrade().unwrap().sid != session.sid {
  299. return Err(EPERM);
  300. }
  301. // If we are already in the process group, we are done.
  302. if new_pgroup.pgid == pgroup.pgid {
  303. return Ok(());
  304. }
  305. new_pgroup.add_member(self, procs.prove_mut());
  306. new_pgroup
  307. } else {
  308. // Create a new process group only if `pgid` matches our `pid`.
  309. if pgid != self.pid {
  310. return Err(EPERM);
  311. }
  312. ProcessGroupBuilder::new()
  313. .leader(self)
  314. .session(session.clone())
  315. .build(procs)
  316. };
  317. pgroup.remove_member(self.pid, procs.prove_mut());
  318. {
  319. let _old_pgroup = unsafe { self.pgroup.swap(Some(new_pgroup)) }.unwrap();
  320. rcu_sync();
  321. }
  322. Ok(())
  323. }
  324. /// Set the process group id of the process `pid` to `pgid`.
  325. ///
  326. /// This function should be called on the process that issued the syscall in order to do
  327. /// permission checks.
  328. pub fn setpgid(self: &Arc<Self>, pid: u32, pgid: u32) -> KResult<()> {
  329. let mut procs = ProcessList::get().lock();
  330. // We may set pgid of either the calling process or a child process.
  331. if pid == self.pid {
  332. self.do_setpgid(pgid, procs.as_mut())
  333. } else {
  334. let child = {
  335. // If `pid` refers to one of our children, the thread leaders must be
  336. // in out children list.
  337. let children = &self.inner.access(procs.prove()).children;
  338. let child = {
  339. let child = children.get(&pid);
  340. child.and_then(Weak::upgrade).ok_or(ESRCH)?
  341. };
  342. // Changing the process group of a child is only allowed
  343. // if we are in the same session.
  344. if child.session(procs.prove()).sid != self.session(procs.prove()).sid {
  345. return Err(EPERM);
  346. }
  347. child
  348. };
  349. // TODO: Check whether we, as a child, have already performed an `execve`.
  350. // If so, we should return `Err(EACCES)`.
  351. child.do_setpgid(pgid, procs.as_mut())
  352. }
  353. }
  354. /// Provide locked (consistent) access to the session.
  355. pub fn session<'r>(&'r self, _procs: Proof<'r, ProcessList>) -> BorrowedArc<'r, Session> {
  356. // SAFETY: We are holding the process list lock.
  357. unsafe { self.session.load_locked() }.unwrap()
  358. }
  359. /// Provide locked (consistent) access to the process group.
  360. pub fn pgroup<'r>(&'r self, _procs: Proof<'r, ProcessList>) -> BorrowedArc<'r, ProcessGroup> {
  361. // SAFETY: We are holding the process list lock.
  362. unsafe { self.pgroup.load_locked() }.unwrap()
  363. }
  364. /// Provide locked (consistent) access to the parent process.
  365. pub fn parent<'r>(&'r self, _procs: Proof<'r, ProcessList>) -> BorrowedArc<'r, Process> {
  366. // SAFETY: We are holding the process list lock.
  367. unsafe { self.parent.load_locked() }.unwrap()
  368. }
  369. /// Provide RCU locked (maybe inconsistent) access to the session.
  370. pub fn session_rcu(&self) -> RCUReadGuard<'_, BorrowedArc<Session>> {
  371. self.session.load().unwrap()
  372. }
  373. /// Provide RCU locked (maybe inconsistent) access to the process group.
  374. pub fn pgroup_rcu(&self) -> RCUReadGuard<'_, BorrowedArc<ProcessGroup>> {
  375. self.pgroup.load().unwrap()
  376. }
  377. /// Provide RCU locked (maybe inconsistent) access to the parent process.
  378. pub fn parent_rcu(&self) -> Option<RCUReadGuard<'_, BorrowedArc<Process>>> {
  379. self.parent.load()
  380. }
  381. pub fn notify(&self, wait: WaitObject, procs: Proof<'_, ProcessList>) {
  382. self.wait_list.notify(wait);
  383. self.raise(Signal::SIGCHLD, procs);
  384. }
  385. pub fn notify_batch(&self) -> NotifyBatch<'_, '_, '_> {
  386. NotifyBatch {
  387. wait_procs: self.wait_list.wait_procs.lock(),
  388. process: self,
  389. cv: &self.wait_list.cv_wait_procs,
  390. needs_notify: false,
  391. }
  392. }
  393. }
  394. impl WaitList {
  395. pub fn new() -> Self {
  396. Self {
  397. wait_procs: Spin::new(VecDeque::new()),
  398. cv_wait_procs: CondVar::new(),
  399. }
  400. }
  401. fn notify(&self, wait: WaitObject) {
  402. let mut wait_procs = self.wait_procs.lock();
  403. wait_procs.push_back(wait);
  404. self.cv_wait_procs.notify_all();
  405. }
  406. pub fn drain_exited(&self) -> DrainExited {
  407. DrainExited {
  408. wait_procs: self.wait_procs.lock(),
  409. }
  410. }
  411. /// # Safety
  412. /// Locks `ProcessList` and `WaitList` at the same time. When `wait` is called,
  413. /// releases the lock on `ProcessList` and `WaitList` and waits on `cv_wait_procs`.
  414. pub fn entry(&self, want_stop: bool, want_continue: bool) -> Entry {
  415. Entry {
  416. process_list: ProcessList::get().lock_shared(),
  417. wait_procs: self.wait_procs.lock(),
  418. cv: &self.cv_wait_procs,
  419. want_stop,
  420. want_continue,
  421. }
  422. }
  423. }
  424. impl Entry<'_, '_, '_> {
  425. pub fn get(&mut self) -> Option<WaitObject> {
  426. if let Some(idx) = self
  427. .wait_procs
  428. .iter()
  429. .enumerate()
  430. .filter(|(_, item)| {
  431. if item.stopped().is_some() {
  432. self.want_stop
  433. } else if item.is_continue() {
  434. self.want_continue
  435. } else {
  436. true
  437. }
  438. })
  439. .map(|(idx, _)| idx)
  440. .next()
  441. {
  442. Some(self.wait_procs.remove(idx).unwrap())
  443. } else {
  444. None
  445. }
  446. }
  447. pub fn wait(&mut self) -> KResult<()> {
  448. // SAFETY: We will lock it again after returning from `cv.wait`.
  449. unsafe { self.wait_procs.force_unlock() };
  450. self.cv.wait(&mut self.process_list);
  451. // SAFETY: We will lock it again.
  452. unsafe { self.wait_procs.force_relock() };
  453. if Thread::current().signal_list.has_pending_signal() {
  454. return Err(EINTR);
  455. }
  456. Ok(())
  457. }
  458. }
  459. impl DrainExited<'_> {
  460. pub fn into_iter(&mut self) -> impl Iterator<Item = WaitObject> + '_ {
  461. // We don't propagate stop and continue to the new parent.
  462. self.wait_procs
  463. .drain(..)
  464. .filter(|item| item.stopped().is_none() && !item.is_continue())
  465. }
  466. }
  467. impl NotifyBatch<'_, '_, '_> {
  468. pub fn notify(&mut self, wait: WaitObject) {
  469. self.needs_notify = true;
  470. self.wait_procs.push_back(wait);
  471. }
  472. /// Finish the batch and notify all if we have notified some processes.
  473. pub fn finish(mut self, procs: Proof<'_, ProcessList>) {
  474. if self.needs_notify {
  475. self.cv.notify_all();
  476. self.process.raise(Signal::SIGCHLD, procs);
  477. self.needs_notify = false;
  478. }
  479. }
  480. }
  481. impl Drop for NotifyBatch<'_, '_, '_> {
  482. fn drop(&mut self) {
  483. if self.needs_notify {
  484. panic!("NotifyBatch dropped without calling finish");
  485. }
  486. }
  487. }