pid_namespace.rs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. use alloc::sync::Weak;
  2. use alloc::{sync::Arc, vec::Vec};
  3. use hashbrown::HashMap;
  4. use ida::IdAllocator;
  5. use system_error::SystemError;
  6. use crate::libs::spinlock::SpinLock;
  7. use crate::libs::spinlock::SpinLockGuard;
  8. use crate::process::fork::CloneFlags;
  9. use crate::process::pid::Pid;
  10. use crate::process::ProcessControlBlock;
  11. use crate::process::ProcessManager;
  12. use crate::process::RawPid;
  13. use super::nsproxy::NsCommon;
  14. use super::user_namespace::UserNamespace;
  15. use super::{NamespaceOps, NamespaceType};
  16. lazy_static! {
  17. pub static ref INIT_PID_NAMESPACE: Arc<PidNamespace> = PidNamespace::new_root();
  18. }
  19. pub struct PidNamespace {
  20. ns_common: NsCommon,
  21. self_ref: Weak<PidNamespace>,
  22. /// 父namespace的弱引用
  23. parent: Option<Weak<PidNamespace>>,
  24. user_ns: Arc<UserNamespace>,
  25. inner: SpinLock<InnerPidNamespace>,
  26. }
  27. pub struct InnerPidNamespace {
  28. dead: bool,
  29. ida: IdAllocator,
  30. /// PID到进程的映射表
  31. pid_map: HashMap<RawPid, Arc<Pid>>,
  32. /// init进程引用
  33. child_reaper: Option<Weak<ProcessControlBlock>>,
  34. children: Vec<Arc<PidNamespace>>,
  35. }
  36. impl InnerPidNamespace {
  37. pub fn dead(&self) -> bool {
  38. self.dead
  39. }
  40. pub fn child_reaper(&self) -> &Option<Weak<ProcessControlBlock>> {
  41. &self.child_reaper
  42. }
  43. }
  44. impl NamespaceOps for PidNamespace {
  45. fn ns_common(&self) -> &NsCommon {
  46. &self.ns_common
  47. }
  48. }
  49. impl PidNamespace {
  50. /// 最大PID namespace层级
  51. pub const MAX_PID_NS_LEVEL: u32 = 32;
  52. /// 创建root PID namespace
  53. fn new_root() -> Arc<Self> {
  54. Arc::new_cyclic(|self_ref| Self {
  55. self_ref: self_ref.clone(),
  56. ns_common: NsCommon::new(0, NamespaceType::Pid),
  57. parent: None,
  58. user_ns: super::user_namespace::INIT_USER_NAMESPACE.clone(),
  59. inner: SpinLock::new(InnerPidNamespace {
  60. dead: false,
  61. child_reaper: None,
  62. ida: IdAllocator::new(1, usize::MAX).unwrap(),
  63. pid_map: HashMap::new(),
  64. children: Vec::new(),
  65. }),
  66. })
  67. }
  68. /// 获取层级
  69. pub fn level(&self) -> u32 {
  70. self.ns_common.level
  71. }
  72. pub fn alloc_pid_in_ns(&self, pid: Arc<Pid>) -> Result<RawPid, SystemError> {
  73. let mut inner = self.inner();
  74. let raw_pid = inner.do_alloc_pid_in_ns(pid)?;
  75. Ok(raw_pid)
  76. }
  77. pub fn pid_allocated(&self) -> usize {
  78. let inner = self.inner();
  79. inner.do_pid_allocated()
  80. }
  81. pub fn release_pid_in_ns(&self, raw_pid: RawPid) {
  82. let mut inner = self.inner();
  83. inner.do_release_pid_in_ns(raw_pid);
  84. }
  85. pub fn find_pid_in_ns(&self, raw_pid: RawPid) -> Option<Arc<Pid>> {
  86. let inner = self.inner();
  87. inner.pid_map.get(&raw_pid).cloned()
  88. }
  89. /// https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/pid_namespace.c#145
  90. pub(super) fn copy_pid_ns(
  91. &self,
  92. clone_flags: &CloneFlags,
  93. user_ns: Arc<UserNamespace>,
  94. ) -> Result<Arc<Self>, SystemError> {
  95. if !clone_flags.contains(CloneFlags::CLONE_NEWPID) {
  96. return Ok(self.self_ref.upgrade().unwrap());
  97. }
  98. if !Arc::ptr_eq(
  99. &ProcessManager::current_pcb().active_pid_ns(),
  100. &self.self_ref.upgrade().unwrap(),
  101. ) {
  102. return Err(SystemError::EINVAL);
  103. }
  104. return self.create_pid_namespace(user_ns);
  105. }
  106. /// https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/pid_namespace.c#72
  107. pub(super) fn create_pid_namespace(
  108. &self,
  109. user_ns: Arc<UserNamespace>,
  110. ) -> Result<Arc<Self>, SystemError> {
  111. let level = self.level() + 1;
  112. if !self.user_ns.is_ancestor_of(&user_ns) {
  113. return Err(SystemError::EINVAL);
  114. }
  115. if level > Self::MAX_PID_NS_LEVEL {
  116. return Err(SystemError::ENOSPC);
  117. }
  118. // todo: 补充ucount相关
  119. let pidns = Arc::new_cyclic(|self_ref| Self {
  120. self_ref: self_ref.clone(),
  121. ns_common: NsCommon::new(level, NamespaceType::Pid),
  122. parent: Some(self.self_ref.clone()),
  123. user_ns,
  124. inner: SpinLock::new(InnerPidNamespace {
  125. child_reaper: None,
  126. dead: false,
  127. ida: IdAllocator::new(1, usize::MAX).unwrap(),
  128. pid_map: HashMap::new(),
  129. children: Vec::new(),
  130. }),
  131. });
  132. // todo: procfs相关,申请inode号,赋值operations等
  133. self.inner().children.push(pidns.clone());
  134. return Ok(pidns);
  135. }
  136. pub fn inner(&self) -> SpinLockGuard<InnerPidNamespace> {
  137. self.inner.lock()
  138. }
  139. pub fn child_reaper(&self) -> Option<Weak<ProcessControlBlock>> {
  140. self.inner().child_reaper.clone()
  141. }
  142. pub fn set_child_reaper(&self, child_reaper: Weak<ProcessControlBlock>) {
  143. self.inner().child_reaper = Some(child_reaper);
  144. }
  145. pub fn parent(&self) -> Option<Arc<PidNamespace>> {
  146. self.parent.as_ref().and_then(|p| p.upgrade())
  147. }
  148. /// 从父namespace中删除当前PID namespace
  149. pub fn delete_current_pidns_in_parent(&self) {
  150. let current = self.self_ref.upgrade().unwrap();
  151. if let Some(p) = self.parent() {
  152. p.inner().children.retain(|c| !Arc::ptr_eq(c, &current));
  153. }
  154. }
  155. }
  156. impl InnerPidNamespace {
  157. pub fn do_alloc_pid_in_ns(&mut self, pid: Arc<Pid>) -> Result<RawPid, SystemError> {
  158. if self.dead {
  159. return Err(SystemError::ESRCH);
  160. }
  161. let raw_pid = self.ida.alloc().ok_or(SystemError::ENOMEM)?;
  162. let raw_pid = RawPid(raw_pid);
  163. self.pid_map.insert(raw_pid, pid);
  164. Ok(raw_pid)
  165. }
  166. pub fn do_release_pid_in_ns(&mut self, raw_pid: RawPid) {
  167. // log::debug!("do_release_pid_in_ns: raw_pid={}", raw_pid);
  168. self.pid_map.remove(&raw_pid);
  169. self.ida.free(raw_pid.data());
  170. if self.pid_map.is_empty() {
  171. // 如果当前namespace中没有任何PID了,则标记为dead
  172. self.dead = true;
  173. }
  174. }
  175. pub fn do_pid_allocated(&self) -> usize {
  176. self.pid_map.len()
  177. }
  178. }
  179. impl Drop for PidNamespace {
  180. fn drop(&mut self) {
  181. // log::debug!("Dropping PidNamespace at level {}", self.level);
  182. }
  183. }
  184. impl ProcessControlBlock {
  185. pub fn active_pid_ns(&self) -> Arc<PidNamespace> {
  186. self.pid().ns_of_pid()
  187. }
  188. }