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 pub trait KObjectAttribute: Attribute { 113 fn support(&self) -> SysFSOpsSupport; 114 115 fn show(&self, kobj: &dyn KObject, buf: &mut [u8]) -> Result<usize, SystemError>; 116 fn store(&self, kobj: &dyn KObject, buf: &[u8]) -> Result<usize, SystemError>; 117 } 118 119 #[derive(Debug)] 120 pub struct KObjectSysFSOps; 121 122 impl SysFSOps for KObjectSysFSOps { 123 fn support(&self, attr: &dyn Attribute) -> SysFSOpsSupport { 124 return attr.support(); 125 } 126 127 fn show( 128 &self, 129 kobj: Arc<dyn KObject>, 130 attr: &dyn Attribute, 131 buf: &mut [u8], 132 ) -> Result<usize, SystemError> { 133 let r = attr.show(kobj, buf).map_err(|e| { 134 if e == SystemError::EOPNOTSUPP_OR_ENOTSUP { 135 SystemError::EIO 136 } else { 137 e 138 } 139 }); 140 141 return r; 142 } 143 144 fn store( 145 &self, 146 kobj: Arc<dyn KObject>, 147 attr: &dyn Attribute, 148 buf: &[u8], 149 ) -> Result<usize, SystemError> { 150 let r = attr.store(kobj, buf).map_err(|e| { 151 if e == SystemError::EOPNOTSUPP_OR_ENOTSUP { 152 SystemError::EIO 153 } else { 154 e 155 } 156 }); 157 158 return r; 159 } 160 } 161 162 #[derive(Debug)] 163 pub struct KObjectManager; 164 165 impl KObjectManager { 166 #[allow(dead_code)] 167 pub fn init_and_add_kobj( 168 kobj: Arc<dyn KObject>, 169 join_kset: Option<Arc<KSet>>, 170 ) -> Result<(), SystemError> { 171 Self::kobj_init(&kobj); 172 Self::add_kobj(kobj, join_kset) 173 } 174 175 #[allow(dead_code)] 176 pub fn kobj_init(kobj: &Arc<dyn KObject>) { 177 kobj.set_kobj_type(Some(&DynamicKObjKType)); 178 } 179 180 pub fn add_kobj( 181 kobj: Arc<dyn KObject>, 182 join_kset: Option<Arc<KSet>>, 183 ) -> Result<(), SystemError> { 184 if join_kset.is_some() { 185 let kset = join_kset.unwrap(); 186 kset.join(&kobj); 187 // 如果kobject没有parent,那么就将这个kset作为parent 188 if kobj.parent().is_none() { 189 kobj.set_parent(Some(Arc::downgrade(&(kset as Arc<dyn KObject>)))); 190 } 191 } 192 193 let r = Self::create_dir(kobj.clone()); 194 195 if let Err(e) = r { 196 // https://opengrok.ringotek.cn/xref/linux-6.1.9/lib/kobject.c?r=&mo=10426&fi=394#224 197 if let Some(kset) = kobj.kset() { 198 kset.leave(&kobj); 199 } 200 kobj.set_parent(None); 201 if e == SystemError::EEXIST { 202 kerror!("KObjectManager::add_kobj() failed with error: {e:?}, kobj:{kobj:?}"); 203 } 204 205 return Err(e); 206 } 207 208 kobj.update_kobj_state(Some(KObjectState::IN_SYSFS), None); 209 return Ok(()); 210 } 211 212 fn create_dir(kobj: Arc<dyn KObject>) -> Result<(), SystemError> { 213 // create dir in sysfs 214 sysfs_instance().create_dir(kobj.clone())?; 215 216 // create default attributes in sysfs 217 if let Some(ktype) = kobj.kobj_type() { 218 let groups = ktype.attribute_groups(); 219 if let Some(groups) = groups { 220 let r = sysfs_instance().create_groups(&kobj, groups); 221 if let Err(e) = r { 222 sysfs_instance().remove_dir(&kobj); 223 return Err(e); 224 } 225 } 226 } 227 228 return Ok(()); 229 } 230 231 /// 从sysfs中移除kobject 232 pub fn remove_kobj(kobj: Arc<dyn KObject>) { 233 let ktype = kobj.kobj_type(); 234 if let Some(ktype) = ktype { 235 if let Some(groups) = ktype.attribute_groups() { 236 sysfs_instance().remove_groups(&kobj, groups); 237 } 238 } 239 240 // todo: 发送uevent: KOBJ_REMOVE 241 242 sysfs_instance().remove_dir(&kobj); 243 kobj.update_kobj_state(None, Some(KObjectState::IN_SYSFS)); 244 let kset = kobj.kset(); 245 if let Some(kset) = kset { 246 kset.leave(&kobj); 247 } 248 kobj.set_parent(None); 249 } 250 } 251 252 /// 动态创建的kobject对象的ktype 253 #[derive(Debug)] 254 pub struct DynamicKObjKType; 255 256 impl KObjType for DynamicKObjKType { 257 fn release(&self, kobj: Arc<dyn KObject>) { 258 kdebug!("DynamicKObjKType::release() kobj:{:?}", kobj.name()); 259 } 260 261 fn sysfs_ops(&self) -> Option<&dyn SysFSOps> { 262 Some(&KObjectSysFSOps) 263 } 264 265 fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> { 266 None 267 } 268 } 269