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