xref: /DragonOS/kernel/src/driver/base/kobject.rs (revision 4dd4856f933be0b4624c7f7ffa9e3d0c8c218873)
1 use core::{any::Any, fmt::Debug, hash::Hash, ops::Deref};
2 
3 use alloc::{
4     string::String,
5     sync::{Arc, Weak},
6 };
7 use driver_base_macros::get_weak_or_clear;
8 use intertrait::CastFromSync;
9 use log::{debug, error};
10 
11 use crate::{
12     filesystem::{
13         kernfs::KernFSInode,
14         sysfs::{sysfs_instance, Attribute, AttributeGroup, SysFSOps, SysFSOpsSupport},
15     },
16     libs::{
17         casting::DowncastArc,
18         rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
19     },
20 };
21 
22 use system_error::SystemError;
23 
24 use super::kset::KSet;
25 
26 pub trait KObject: Any + Send + Sync + Debug + CastFromSync {
27     fn as_any_ref(&self) -> &dyn core::any::Any;
28 
29     /// 设置当前kobject对应的sysfs inode(类型为KernFSInode)
30     fn set_inode(&self, inode: Option<Arc<KernFSInode>>);
31 
32     /// 获取当前kobject对应的sysfs inode(类型为KernFSInode)
33     fn inode(&self) -> Option<Arc<KernFSInode>>;
34 
35     fn parent(&self) -> Option<Weak<dyn KObject>>;
36 
37     /// 设置当前kobject的parent kobject(不一定与kset相同)
38     fn set_parent(&self, parent: Option<Weak<dyn KObject>>);
39 
40     /// 当前kobject属于哪个kset
41     fn kset(&self) -> Option<Arc<KSet>>;
42 
43     /// 设置当前kobject所属的kset
44     fn set_kset(&self, kset: Option<Arc<KSet>>);
45 
46     fn kobj_type(&self) -> Option<&'static dyn KObjType>;
47 
48     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>);
49 
50     fn name(&self) -> String;
51 
52     fn set_name(&self, name: String);
53 
54     fn kobj_state(&self) -> RwLockReadGuard<KObjectState>;
55 
56     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>;
57 
58     fn set_kobj_state(&self, state: KObjectState);
59 }
60 
61 impl dyn KObject {
62     /// 更新kobject的状态
63     pub fn update_kobj_state(&self, insert: Option<KObjectState>, remove: Option<KObjectState>) {
64         let insert = insert.unwrap_or(KObjectState::empty());
65         let remove = remove.unwrap_or(KObjectState::empty());
66         let mut state = self.kobj_state_mut();
67         *state = (*state | insert) & !remove;
68     }
69 }
70 
71 impl DowncastArc for dyn KObject {
72     fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any> {
73         self
74     }
75 }
76 
77 /// kobject的公共数据
78 #[derive(Debug, Default)]
79 pub struct KObjectCommonData {
80     pub kern_inode: Option<Arc<KernFSInode>>,
81     pub parent: Option<Weak<dyn KObject>>,
82     pub kset: Option<Arc<KSet>>,
83     pub kobj_type: Option<&'static dyn KObjType>,
84 }
85 
86 impl KObjectCommonData {
87     pub fn get_parent_or_clear_weak(&mut self) -> Option<Weak<dyn KObject>> {
88         get_weak_or_clear!(self.parent)
89     }
90 }
91 
92 pub trait KObjType: Debug + Send + Sync {
93     /// 当指定的kobject被释放时,设备驱动模型会调用此方法
94     fn release(&self, _kobj: Arc<dyn KObject>) {}
95     fn sysfs_ops(&self) -> Option<&dyn SysFSOps>;
96 
97     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]>;
98 }
99 
100 bitflags! {
101     pub struct KObjectState: u32 {
102         const IN_SYSFS = 1 << 0;
103         const ADD_UEVENT_SENT = 1 << 1;
104         const REMOVE_UEVENT_SENT = 1 << 2;
105         const INITIALIZED = 1 << 3;
106     }
107 
108 }
109 
110 #[derive(Debug)]
111 pub struct LockedKObjectState(RwLock<KObjectState>);
112 
113 impl LockedKObjectState {
114     pub fn new(state: Option<KObjectState>) -> LockedKObjectState {
115         let state = state.unwrap_or(KObjectState::empty());
116         LockedKObjectState(RwLock::new(state))
117     }
118 }
119 
120 impl Deref for LockedKObjectState {
121     type Target = RwLock<KObjectState>;
122 
123     fn deref(&self) -> &Self::Target {
124         &self.0
125     }
126 }
127 
128 impl Default for LockedKObjectState {
129     fn default() -> Self {
130         LockedKObjectState::new(None)
131     }
132 }
133 
134 #[derive(Debug)]
135 pub struct KObjectSysFSOps;
136 
137 impl SysFSOps for KObjectSysFSOps {
138     fn support(&self, attr: &dyn Attribute) -> SysFSOpsSupport {
139         return attr.support();
140     }
141 
142     fn show(
143         &self,
144         kobj: Arc<dyn KObject>,
145         attr: &dyn Attribute,
146         buf: &mut [u8],
147     ) -> Result<usize, SystemError> {
148         let r = attr.show(kobj, buf).map_err(|e| {
149             if e == SystemError::ENOSYS {
150                 SystemError::EIO
151             } else {
152                 e
153             }
154         });
155 
156         return r;
157     }
158 
159     fn store(
160         &self,
161         kobj: Arc<dyn KObject>,
162         attr: &dyn Attribute,
163         buf: &[u8],
164     ) -> Result<usize, SystemError> {
165         let r = attr.store(kobj, buf).map_err(|e| {
166             if e == SystemError::ENOSYS {
167                 SystemError::EIO
168             } else {
169                 e
170             }
171         });
172 
173         return r;
174     }
175 }
176 
177 #[derive(Debug)]
178 pub struct KObjectManager;
179 
180 impl KObjectManager {
181     pub fn init_and_add_kobj(
182         kobj: Arc<dyn KObject>,
183         join_kset: Option<Arc<KSet>>,
184         kobj_type: Option<&'static dyn KObjType>,
185     ) -> Result<(), SystemError> {
186         Self::kobj_init(&kobj, kobj_type);
187         Self::add_kobj(kobj, join_kset)
188     }
189 
190     pub fn kobj_init(kobj: &Arc<dyn KObject>, kobj_type: Option<&'static dyn KObjType>) {
191         kobj.set_kobj_type(kobj_type);
192     }
193 
194     pub fn add_kobj(
195         kobj: Arc<dyn KObject>,
196         join_kset: Option<Arc<KSet>>,
197     ) -> Result<(), SystemError> {
198         if let Some(kset) = join_kset {
199             kset.join(&kobj);
200             // 如果kobject没有parent,那么就将这个kset作为parent
201             if kobj.parent().is_none() {
202                 kobj.set_parent(Some(Arc::downgrade(&(kset as Arc<dyn KObject>))));
203             }
204         }
205 
206         let r = Self::create_dir(kobj.clone());
207 
208         if let Err(e) = r {
209             // https://code.dragonos.org.cn/xref/linux-6.1.9/lib/kobject.c?r=&mo=10426&fi=394#224
210             if let Some(kset) = kobj.kset() {
211                 kset.leave(&kobj);
212             }
213             kobj.set_parent(None);
214             if e == SystemError::EEXIST {
215                 error!("KObjectManager::add_kobj() failed with error: {e:?}, kobj:{kobj:?}");
216             }
217 
218             return Err(e);
219         }
220 
221         kobj.update_kobj_state(Some(KObjectState::IN_SYSFS), None);
222         return Ok(());
223     }
224 
225     fn create_dir(kobj: Arc<dyn KObject>) -> Result<(), SystemError> {
226         // create dir in sysfs
227         sysfs_instance().create_dir(kobj.clone())?;
228 
229         // create default attributes in sysfs
230         if let Some(ktype) = kobj.kobj_type() {
231             let groups = ktype.attribute_groups();
232             if let Some(groups) = groups {
233                 let r = sysfs_instance().create_groups(&kobj, groups);
234                 if let Err(e) = r {
235                     sysfs_instance().remove_dir(&kobj);
236                     return Err(e);
237                 }
238             }
239         }
240 
241         return Ok(());
242     }
243 
244     /// 从sysfs中移除kobject
245     pub fn remove_kobj(kobj: Arc<dyn KObject>) {
246         let ktype = kobj.kobj_type();
247         if let Some(ktype) = ktype {
248             if let Some(groups) = ktype.attribute_groups() {
249                 sysfs_instance().remove_groups(&kobj, groups);
250             }
251         }
252 
253         // todo: 发送uevent: KOBJ_REMOVE
254 
255         sysfs_instance().remove_dir(&kobj);
256         kobj.update_kobj_state(None, Some(KObjectState::IN_SYSFS));
257         let kset = kobj.kset();
258         if let Some(kset) = kset {
259             kset.leave(&kobj);
260         }
261         kobj.set_parent(None);
262     }
263 }
264 
265 /// 动态创建的kobject对象的ktype
266 #[derive(Debug)]
267 pub struct DynamicKObjKType;
268 
269 impl KObjType for DynamicKObjKType {
270     fn release(&self, kobj: Arc<dyn KObject>) {
271         debug!("DynamicKObjKType::release() kobj:{:?}", kobj.name());
272     }
273 
274     fn sysfs_ops(&self) -> Option<&dyn SysFSOps> {
275         Some(&KObjectSysFSOps)
276     }
277 
278     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
279         None
280     }
281 }
282