kobject.rs 7.5 KB

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