xref: /DragonOS/kernel/src/namespaces/ucount.rs (revision f5b2038871d3441e1c7f32439ff422957e7ab828)
1*f5b20388Scodeironman #![allow(dead_code, unused_variables, unused_imports)]
2*f5b20388Scodeironman use alloc::vec::Vec;
3*f5b20388Scodeironman use core::{hash::Hash, sync::atomic::AtomicU32};
4*f5b20388Scodeironman use system_error::SystemError;
5*f5b20388Scodeironman 
6*f5b20388Scodeironman use alloc::sync::Arc;
7*f5b20388Scodeironman use hashbrown::HashMap;
8*f5b20388Scodeironman use log::warn;
9*f5b20388Scodeironman 
10*f5b20388Scodeironman use super::user_namespace::UserNamespace;
11*f5b20388Scodeironman use crate::libs::mutex::Mutex;
12*f5b20388Scodeironman 
13*f5b20388Scodeironman #[derive(Clone, Copy)]
14*f5b20388Scodeironman pub enum Ucount {
15*f5b20388Scodeironman     UserNamespaces = 1,
16*f5b20388Scodeironman     PidNamespaces = 2,
17*f5b20388Scodeironman     UtsNamespaces = 3,
18*f5b20388Scodeironman     IpcNamespaces = 4,
19*f5b20388Scodeironman     NetNamespaces = 5,
20*f5b20388Scodeironman     MntNamespaces = 6,
21*f5b20388Scodeironman     CgroupNamespaces = 7,
22*f5b20388Scodeironman     TimeNamespaces = 8,
23*f5b20388Scodeironman     Counts = 9,
24*f5b20388Scodeironman }
25*f5b20388Scodeironman 
26*f5b20388Scodeironman pub enum UcountRlimit {
27*f5b20388Scodeironman     Nproc = 1,
28*f5b20388Scodeironman     Msgqueue = 2,
29*f5b20388Scodeironman     Sigpending = 3,
30*f5b20388Scodeironman     Memlock = 4,
31*f5b20388Scodeironman     Counts = 5,
32*f5b20388Scodeironman }
33*f5b20388Scodeironman 
34*f5b20388Scodeironman lazy_static! {
35*f5b20388Scodeironman     static ref COUNT_MANAGER: Arc<CountManager> = Arc::new(CountManager::new());
36*f5b20388Scodeironman }
37*f5b20388Scodeironman 
38*f5b20388Scodeironman #[derive(Debug)]
39*f5b20388Scodeironman pub struct UCounts {
40*f5b20388Scodeironman     /// 对应的user_namespace
41*f5b20388Scodeironman     ns: Arc<UserNamespace>,
42*f5b20388Scodeironman     /// 用户标识符
43*f5b20388Scodeironman     uid: usize,
44*f5b20388Scodeironman     count: AtomicU32,
45*f5b20388Scodeironman     ucount: Vec<AtomicU32>, //[AtomicU32; UCOUNT_COUNTS as usize],
46*f5b20388Scodeironman     rlimit: Vec<AtomicU32>, //[AtomicU32; UCOUNT_RLIMIT_COUNTS as usize],
47*f5b20388Scodeironman }
48*f5b20388Scodeironman 
49*f5b20388Scodeironman impl Default for UCounts {
default() -> Self50*f5b20388Scodeironman     fn default() -> Self {
51*f5b20388Scodeironman         Self::new()
52*f5b20388Scodeironman     }
53*f5b20388Scodeironman }
54*f5b20388Scodeironman impl UCounts {
new() -> Self55*f5b20388Scodeironman     pub fn new() -> Self {
56*f5b20388Scodeironman         Self {
57*f5b20388Scodeironman             ns: Arc::new(UserNamespace::new()),
58*f5b20388Scodeironman             uid: 0,
59*f5b20388Scodeironman             count: AtomicU32::new(1),
60*f5b20388Scodeironman             ucount: (0..Ucount::Counts as usize)
61*f5b20388Scodeironman                 .map(|_| AtomicU32::new(0))
62*f5b20388Scodeironman                 .collect(),
63*f5b20388Scodeironman             rlimit: (0..UcountRlimit::Counts as usize)
64*f5b20388Scodeironman                 .map(|_| AtomicU32::new(0))
65*f5b20388Scodeironman                 .collect(),
66*f5b20388Scodeironman         }
67*f5b20388Scodeironman     }
68*f5b20388Scodeironman 
alloc_ucounts(&self, ns: Arc<UserNamespace>, uid: usize) -> Arc<Self>69*f5b20388Scodeironman     fn alloc_ucounts(&self, ns: Arc<UserNamespace>, uid: usize) -> Arc<Self> {
70*f5b20388Scodeironman         let mut counts = COUNT_MANAGER.counts.lock();
71*f5b20388Scodeironman         let key = UKey {
72*f5b20388Scodeironman             user_ns: ns.clone(),
73*f5b20388Scodeironman             uid,
74*f5b20388Scodeironman         };
75*f5b20388Scodeironman         let uc = if let Some(uc) = counts.get(&key) {
76*f5b20388Scodeironman             self.count
77*f5b20388Scodeironman                 .fetch_add(1, core::sync::atomic::Ordering::SeqCst);
78*f5b20388Scodeironman             uc.clone()
79*f5b20388Scodeironman         } else {
80*f5b20388Scodeironman             Arc::new(Self {
81*f5b20388Scodeironman                 ns,
82*f5b20388Scodeironman                 uid,
83*f5b20388Scodeironman                 count: AtomicU32::new(1),
84*f5b20388Scodeironman                 ucount: (0..Ucount::Counts as usize)
85*f5b20388Scodeironman                     .map(|_| AtomicU32::new(0))
86*f5b20388Scodeironman                     .collect(),
87*f5b20388Scodeironman                 rlimit: (0..UcountRlimit::Counts as usize)
88*f5b20388Scodeironman                     .map(|_| AtomicU32::new(0))
89*f5b20388Scodeironman                     .collect(),
90*f5b20388Scodeironman             })
91*f5b20388Scodeironman         };
92*f5b20388Scodeironman         counts.insert(key, uc.clone());
93*f5b20388Scodeironman         uc
94*f5b20388Scodeironman     }
95*f5b20388Scodeironman 
inc_ucounts( &self, user_ns: Arc<UserNamespace>, uid: usize, ucount_type: Ucount, ) -> Option<Arc<UCounts>>96*f5b20388Scodeironman     pub fn inc_ucounts(
97*f5b20388Scodeironman         &self,
98*f5b20388Scodeironman         user_ns: Arc<UserNamespace>,
99*f5b20388Scodeironman         uid: usize,
100*f5b20388Scodeironman         ucount_type: Ucount,
101*f5b20388Scodeironman     ) -> Option<Arc<UCounts>> {
102*f5b20388Scodeironman         let uc_type = ucount_type as usize;
103*f5b20388Scodeironman         let uc = self.alloc_ucounts(user_ns, uid);
104*f5b20388Scodeironman         let mut uc_iter = Some(uc.clone());
105*f5b20388Scodeironman         let mut ucounts_add = vec![];
106*f5b20388Scodeironman         while let Some(iter) = uc_iter {
107*f5b20388Scodeironman             let num = iter.ucount[uc_type].fetch_add(1, core::sync::atomic::Ordering::SeqCst);
108*f5b20388Scodeironman             ucounts_add.push(iter.clone());
109*f5b20388Scodeironman             // 分配失败回滚
110*f5b20388Scodeironman             if num > iter.ns.ucount_max[uc_type] {
111*f5b20388Scodeironman                 for add_iter in &ucounts_add {
112*f5b20388Scodeironman                     add_iter.ucount[uc_type].fetch_sub(1, core::sync::atomic::Ordering::SeqCst);
113*f5b20388Scodeironman                 }
114*f5b20388Scodeironman                 return None;
115*f5b20388Scodeironman             }
116*f5b20388Scodeironman             uc_iter = iter.ns.ucounts.clone();
117*f5b20388Scodeironman         }
118*f5b20388Scodeironman         return Some(uc);
119*f5b20388Scodeironman     }
120*f5b20388Scodeironman 
find_ucounts(user_ns: Arc<UserNamespace>, uid: usize) -> Option<Arc<UCounts>>121*f5b20388Scodeironman     fn find_ucounts(user_ns: Arc<UserNamespace>, uid: usize) -> Option<Arc<UCounts>> {
122*f5b20388Scodeironman         let counts = COUNT_MANAGER.counts.lock();
123*f5b20388Scodeironman         let key = UKey { user_ns, uid };
124*f5b20388Scodeironman         counts.get(&key).cloned()
125*f5b20388Scodeironman     }
126*f5b20388Scodeironman 
get_ucounts(uc: Arc<UCounts>)127*f5b20388Scodeironman     fn get_ucounts(uc: Arc<UCounts>) {
128*f5b20388Scodeironman         let mut counts = COUNT_MANAGER.counts.lock();
129*f5b20388Scodeironman         let ukey = UKey {
130*f5b20388Scodeironman             user_ns: uc.ns.clone(),
131*f5b20388Scodeironman             uid: uc.uid,
132*f5b20388Scodeironman         };
133*f5b20388Scodeironman         counts.insert(ukey, uc);
134*f5b20388Scodeironman     }
135*f5b20388Scodeironman 
dec_ucount(uc: Arc<UCounts>, ucount_type: Ucount)136*f5b20388Scodeironman     pub fn dec_ucount(uc: Arc<UCounts>, ucount_type: Ucount) {
137*f5b20388Scodeironman         let mut uc_iter = Some(uc.clone());
138*f5b20388Scodeironman         let uc_type = ucount_type as usize;
139*f5b20388Scodeironman         while let Some(iter) = uc_iter {
140*f5b20388Scodeironman             let num = iter.ucount[uc_type].fetch_sub(1, core::sync::atomic::Ordering::SeqCst);
141*f5b20388Scodeironman             if num == 0 {
142*f5b20388Scodeironman                 warn!("count has reached zero");
143*f5b20388Scodeironman             }
144*f5b20388Scodeironman             uc_iter = iter.ns.ucounts.clone();
145*f5b20388Scodeironman         }
146*f5b20388Scodeironman         Self::put_ucounts(uc);
147*f5b20388Scodeironman     }
148*f5b20388Scodeironman 
put_ucounts(uc: Arc<UCounts>)149*f5b20388Scodeironman     fn put_ucounts(uc: Arc<UCounts>) {
150*f5b20388Scodeironman         let mut counts = COUNT_MANAGER.counts.lock();
151*f5b20388Scodeironman         let key = UKey {
152*f5b20388Scodeironman             user_ns: uc.ns.clone(),
153*f5b20388Scodeironman             uid: uc.uid,
154*f5b20388Scodeironman         };
155*f5b20388Scodeironman         counts.remove(&key);
156*f5b20388Scodeironman     }
157*f5b20388Scodeironman }
158*f5b20388Scodeironman struct UKey {
159*f5b20388Scodeironman     user_ns: Arc<UserNamespace>,
160*f5b20388Scodeironman     uid: usize,
161*f5b20388Scodeironman }
162*f5b20388Scodeironman 
163*f5b20388Scodeironman impl Hash for UKey {
hash<H: core::hash::Hasher>(&self, state: &mut H)164*f5b20388Scodeironman     fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
165*f5b20388Scodeironman         let user_ns_ptr = Arc::as_ptr(&self.user_ns);
166*f5b20388Scodeironman         user_ns_ptr.hash(state);
167*f5b20388Scodeironman         self.uid.hash(state)
168*f5b20388Scodeironman     }
169*f5b20388Scodeironman }
170*f5b20388Scodeironman impl Eq for UKey {}
171*f5b20388Scodeironman impl PartialEq for UKey {
eq(&self, other: &Self) -> bool172*f5b20388Scodeironman     fn eq(&self, other: &Self) -> bool {
173*f5b20388Scodeironman         Arc::ptr_eq(&self.user_ns, &other.user_ns) && self.uid == other.uid
174*f5b20388Scodeironman     }
175*f5b20388Scodeironman }
176*f5b20388Scodeironman 
177*f5b20388Scodeironman struct CountManager {
178*f5b20388Scodeironman     counts: Mutex<HashMap<UKey, Arc<UCounts>>>,
179*f5b20388Scodeironman }
180*f5b20388Scodeironman 
181*f5b20388Scodeironman impl CountManager {
new() -> Self182*f5b20388Scodeironman     fn new() -> Self {
183*f5b20388Scodeironman         Self {
184*f5b20388Scodeironman             counts: Mutex::new(HashMap::new()),
185*f5b20388Scodeironman         }
186*f5b20388Scodeironman     }
187*f5b20388Scodeironman }
188