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 syscall::SystemError, 20 }; 21 22 use super::kset::KSet; 23 24 pub trait KObject: Any + Send + Sync + Debug + CastFromSync { 25 fn as_any_ref(&self) -> &dyn core::any::Any; 26 27 /// 设置当前kobject对应的sysfs inode(类型为KernFSInode) 28 fn set_inode(&self, inode: Option<Arc<KernFSInode>>); 29 30 /// 获取当前kobject对应的sysfs inode(类型为KernFSInode) 31 fn inode(&self) -> Option<Arc<KernFSInode>>; 32 33 fn parent(&self) -> Option<Weak<dyn KObject>>; 34 35 /// 设置当前kobject的parent kobject(不一定与kset相同) 36 fn set_parent(&self, parent: Option<Weak<dyn KObject>>); 37 38 /// 当前kobject属于哪个kset 39 fn kset(&self) -> Option<Arc<KSet>>; 40 41 /// 设置当前kobject所属的kset 42 fn set_kset(&self, kset: Option<Arc<KSet>>); 43 44 fn kobj_type(&self) -> Option<&'static dyn KObjType>; 45 46 fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>); 47 48 fn name(&self) -> String; 49 50 fn set_name(&self, name: String); 51 52 fn kobj_state(&self) -> RwLockReadGuard<KObjectState>; 53 54 fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>; 55 56 fn set_kobj_state(&self, state: KObjectState); 57 } 58 59 impl dyn KObject { 60 /// 更新kobject的状态 61 pub fn update_kobj_state(&self, insert: Option<KObjectState>, remove: Option<KObjectState>) { 62 let insert = insert.unwrap_or(KObjectState::empty()); 63 let remove = remove.unwrap_or(KObjectState::empty()); 64 let mut state = self.kobj_state_mut(); 65 *state = (*state | insert) & !remove; 66 } 67 } 68 69 impl DowncastArc for dyn KObject { 70 fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any> { 71 self 72 } 73 } 74 75 pub trait KObjType: Debug + Send + Sync { 76 /// 当指定的kobject被释放时,设备驱动模型会调用此方法 77 fn release(&self, _kobj: Arc<dyn KObject>) {} 78 fn sysfs_ops(&self) -> Option<&dyn SysFSOps>; 79 80 fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]>; 81 } 82 83 bitflags! { 84 pub struct KObjectState: u32 { 85 const IN_SYSFS = 1 << 0; 86 const ADD_UEVENT_SENT = 1 << 1; 87 const REMOVE_UEVENT_SENT = 1 << 2; 88 const INITIALIZED = 1 << 3; 89 } 90 91 } 92 93 #[derive(Debug)] 94 pub struct LockedKObjectState(RwLock<KObjectState>); 95 96 impl LockedKObjectState { 97 pub fn new(state: Option<KObjectState>) -> LockedKObjectState { 98 let state = state.unwrap_or(KObjectState::empty()); 99 LockedKObjectState(RwLock::new(state)) 100 } 101 } 102 103 impl Deref for LockedKObjectState { 104 type Target = RwLock<KObjectState>; 105 106 fn deref(&self) -> &Self::Target { 107 &self.0 108 } 109 } 110 111 pub trait KObjectAttribute: Attribute { 112 fn support(&self) -> SysFSOpsSupport; 113 114 fn show(&self, kobj: &dyn KObject, buf: &mut [u8]) -> Result<usize, SystemError>; 115 fn store(&self, kobj: &dyn KObject, buf: &[u8]) -> Result<usize, SystemError>; 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 join_kset.is_some() { 184 let kset = join_kset.unwrap(); 185 kset.join(&kobj); 186 // 如果kobject没有parent,那么就将这个kset作为parent 187 if kobj.parent().is_none() { 188 kobj.set_parent(Some(Arc::downgrade(&(kset as Arc<dyn KObject>)))); 189 } 190 } 191 192 let r = Self::create_dir(kobj.clone()); 193 194 if let Err(e) = r { 195 // https://opengrok.ringotek.cn/xref/linux-6.1.9/lib/kobject.c?r=&mo=10426&fi=394#224 196 if let Some(kset) = kobj.kset() { 197 kset.leave(&kobj); 198 } 199 kobj.set_parent(None); 200 if e == SystemError::EEXIST { 201 kerror!("KObjectManager::add_kobj() failed with error: {e:?}, kobj:{kobj:?}"); 202 } 203 204 return Err(e); 205 } 206 207 kobj.update_kobj_state(Some(KObjectState::IN_SYSFS), None); 208 return Ok(()); 209 } 210 211 fn create_dir(kobj: Arc<dyn KObject>) -> Result<(), SystemError> { 212 // create dir in sysfs 213 sysfs_instance().create_dir(kobj.clone())?; 214 215 // create default attributes in sysfs 216 if let Some(ktype) = kobj.kobj_type() { 217 let groups = ktype.attribute_groups(); 218 if let Some(groups) = groups { 219 let r = sysfs_instance().create_groups(&kobj, groups); 220 if let Err(e) = r { 221 sysfs_instance().remove_dir(&kobj); 222 return Err(e); 223 } 224 } 225 } 226 227 return Ok(()); 228 } 229 230 /// 从sysfs中移除kobject 231 pub fn remove_kobj(kobj: Arc<dyn KObject>) { 232 let ktype = kobj.kobj_type(); 233 if let Some(ktype) = ktype { 234 if let Some(groups) = ktype.attribute_groups() { 235 sysfs_instance().remove_groups(&kobj, groups); 236 } 237 } 238 239 // todo: 发送uevent: KOBJ_REMOVE 240 241 sysfs_instance().remove_dir(&kobj); 242 kobj.update_kobj_state(None, Some(KObjectState::IN_SYSFS)); 243 let kset = kobj.kset(); 244 if let Some(kset) = kset { 245 kset.leave(&kobj); 246 } 247 kobj.set_parent(None); 248 } 249 } 250 251 /// 动态创建的kobject对象的ktype 252 #[derive(Debug)] 253 pub struct DynamicKObjKType; 254 255 impl KObjType for DynamicKObjKType { 256 fn release(&self, kobj: Arc<dyn KObject>) { 257 kdebug!("DynamicKObjKType::release() kobj:{:?}", kobj.name()); 258 } 259 260 fn sysfs_ops(&self) -> Option<&dyn SysFSOps> { 261 Some(&KObjectSysFSOps) 262 } 263 264 fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> { 265 None 266 } 267 } 268