kobject.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  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. const UEVENT_SUPPRESS = 1 << 4;
  82. }
  83. }
  84. #[derive(Debug)]
  85. pub struct LockedKObjectState(RwLock<KObjectState>);
  86. impl LockedKObjectState {
  87. pub fn new(state: Option<KObjectState>) -> LockedKObjectState {
  88. let state = state.unwrap_or(KObjectState::empty());
  89. LockedKObjectState(RwLock::new(state))
  90. }
  91. }
  92. impl Deref for LockedKObjectState {
  93. type Target = RwLock<KObjectState>;
  94. fn deref(&self) -> &Self::Target {
  95. &self.0
  96. }
  97. }
  98. impl Default for LockedKObjectState {
  99. fn default() -> Self {
  100. LockedKObjectState::new(None)
  101. }
  102. }
  103. #[derive(Debug)]
  104. pub struct KObjectSysFSOps;
  105. impl SysFSOps for KObjectSysFSOps {
  106. fn support(&self, attr: &dyn Attribute) -> SysFSOpsSupport {
  107. return attr.support();
  108. }
  109. fn show(
  110. &self,
  111. kobj: Arc<dyn KObject>,
  112. attr: &dyn Attribute,
  113. buf: &mut [u8],
  114. ) -> Result<usize, SystemError> {
  115. let r = attr.show(kobj, buf).map_err(|e| {
  116. if e == SystemError::ENOSYS {
  117. SystemError::EIO
  118. } else {
  119. e
  120. }
  121. });
  122. return r;
  123. }
  124. fn store(
  125. &self,
  126. kobj: Arc<dyn KObject>,
  127. attr: &dyn Attribute,
  128. buf: &[u8],
  129. ) -> Result<usize, SystemError> {
  130. let r = attr.store(kobj, buf).map_err(|e| {
  131. if e == SystemError::ENOSYS {
  132. SystemError::EIO
  133. } else {
  134. e
  135. }
  136. });
  137. return r;
  138. }
  139. }
  140. #[derive(Debug)]
  141. pub struct KObjectManager;
  142. impl KObjectManager {
  143. pub fn init_and_add_kobj(
  144. kobj: Arc<dyn KObject>,
  145. join_kset: Option<Arc<KSet>>,
  146. kobj_type: Option<&'static dyn KObjType>,
  147. ) -> Result<(), SystemError> {
  148. Self::kobj_init(&kobj, kobj_type);
  149. Self::add_kobj(kobj, join_kset)
  150. }
  151. pub fn kobj_init(kobj: &Arc<dyn KObject>, kobj_type: Option<&'static dyn KObjType>) {
  152. kobj.set_kobj_type(kobj_type);
  153. }
  154. pub fn add_kobj(
  155. kobj: Arc<dyn KObject>,
  156. join_kset: Option<Arc<KSet>>,
  157. ) -> Result<(), SystemError> {
  158. if let Some(kset) = join_kset {
  159. kset.join(&kobj);
  160. // 如果kobject没有parent,那么就将这个kset作为parent
  161. if kobj.parent().is_none() {
  162. kobj.set_parent(Some(Arc::downgrade(&(kset as Arc<dyn KObject>))));
  163. }
  164. }
  165. let r = Self::create_dir(kobj.clone());
  166. if let Err(e) = r {
  167. // https://code.dragonos.org.cn/xref/linux-6.1.9/lib/kobject.c?r=&mo=10426&fi=394#224
  168. if let Some(kset) = kobj.kset() {
  169. kset.leave(&kobj);
  170. }
  171. kobj.set_parent(None);
  172. if e == SystemError::EEXIST {
  173. error!("KObjectManager::add_kobj() failed with error: {e:?}, kobj:{kobj:?}");
  174. }
  175. return Err(e);
  176. }
  177. kobj.update_kobj_state(Some(KObjectState::IN_SYSFS), None);
  178. return Ok(());
  179. }
  180. fn create_dir(kobj: Arc<dyn KObject>) -> Result<(), SystemError> {
  181. // create dir in sysfs
  182. sysfs_instance().create_dir(kobj.clone())?;
  183. // create default attributes in sysfs
  184. if let Some(ktype) = kobj.kobj_type() {
  185. let groups = ktype.attribute_groups();
  186. if let Some(groups) = groups {
  187. let r = sysfs_instance().create_groups(&kobj, groups);
  188. if let Err(e) = r {
  189. sysfs_instance().remove_dir(&kobj);
  190. return Err(e);
  191. }
  192. }
  193. }
  194. return Ok(());
  195. }
  196. /// 从sysfs中移除kobject
  197. pub fn remove_kobj(kobj: Arc<dyn KObject>) {
  198. let ktype = kobj.kobj_type();
  199. if let Some(ktype) = ktype {
  200. if let Some(groups) = ktype.attribute_groups() {
  201. sysfs_instance().remove_groups(&kobj, groups);
  202. }
  203. }
  204. // todo: 发送uevent: KOBJ_REMOVE
  205. // kobject_uevent();
  206. sysfs_instance().remove_dir(&kobj);
  207. kobj.update_kobj_state(None, Some(KObjectState::IN_SYSFS));
  208. let kset = kobj.kset();
  209. if let Some(kset) = kset {
  210. kset.leave(&kobj);
  211. }
  212. kobj.set_parent(None);
  213. }
  214. fn get_kobj_path_length(kobj: &Arc<dyn KObject>) -> usize {
  215. log::info!("get_kobj_path_length() kobj:{:?}", kobj.name());
  216. let mut parent = kobj.parent().unwrap().upgrade().unwrap();
  217. /* walk up the ancestors until we hit the one pointing to the
  218. * root.
  219. * Add 1 to strlen for leading '/' of each level.
  220. */
  221. let mut length = 0; // 确保 length 被正确初始化
  222. let mut iteration_count = 0; // 用于记录迭代次数
  223. const MAX_ITERATIONS: usize = 10; // 最大迭代次数
  224. loop {
  225. log::info!(
  226. "Iteration {}: parent.name():{:?}",
  227. iteration_count,
  228. parent.name()
  229. );
  230. length += parent.name().len() + 1;
  231. if let Some(weak_parent) = parent.parent() {
  232. if let Some(upgraded_parent) = weak_parent.upgrade() {
  233. parent = upgraded_parent;
  234. } else {
  235. log::error!("Failed to upgrade weak reference to parent");
  236. break;
  237. }
  238. } else {
  239. log::error!("Parent has no parent");
  240. break;
  241. }
  242. iteration_count += 1;
  243. if iteration_count >= MAX_ITERATIONS {
  244. log::error!("Reached maximum iteration count, breaking to avoid infinite loop");
  245. break;
  246. }
  247. }
  248. return length;
  249. }
  250. /*
  251. static void fill_kobj_path(struct kobject *kobj, char *path, int length)
  252. {
  253. struct kobject *parent;
  254. --length;
  255. for (parent = kobj; parent; parent = parent->parent) {
  256. int cur = strlen(kobject_name(parent));
  257. /* back up enough to print this name with '/' */
  258. length -= cur;
  259. memcpy(path + length, kobject_name(parent), cur);
  260. *(path + --length) = '/';
  261. }
  262. pr_debug("kobject: '%s' (%p): %s: path = '%s'\n", kobject_name(kobj),
  263. kobj, __func__, path);
  264. }
  265. */
  266. fn fill_kobj_path(kobj: &Arc<dyn KObject>, path: &mut [u8], length: usize) {
  267. let mut parent = kobj.parent().unwrap().upgrade().unwrap();
  268. let mut length = length;
  269. length -= 1;
  270. loop {
  271. log::info!("fill_kobj_path parent.name():{:?}", parent.name());
  272. let cur = parent.name().len();
  273. if length < cur + 1 {
  274. // 如果剩余长度不足以容纳当前名称和分隔符,则退出
  275. break;
  276. }
  277. length -= cur;
  278. let parent_name = parent.name();
  279. let name = parent_name.as_bytes();
  280. path[length..(cur + length)].copy_from_slice(&name[..cur]);
  281. length -= 1;
  282. path[length] = b'/';
  283. if let Some(weak_parent) = parent.parent() {
  284. if let Some(upgraded_parent) = weak_parent.upgrade() {
  285. parent = upgraded_parent;
  286. } else {
  287. break;
  288. }
  289. } else {
  290. break;
  291. }
  292. }
  293. }
  294. // TODO: 实现kobject_get_path
  295. // https://code.dragonos.org.cn/xref/linux-6.1.9/lib/kobject.c#139
  296. pub fn kobject_get_path(kobj: &Arc<dyn KObject>) -> String {
  297. log::debug!("kobject_get_path() kobj:{:?}", kobj.name());
  298. let length = Self::get_kobj_path_length(kobj);
  299. let path: &mut [u8] = &mut vec![0; length];
  300. Self::fill_kobj_path(kobj, path, length);
  301. let path_string = String::from_utf8(path.to_vec()).unwrap();
  302. return path_string;
  303. }
  304. }
  305. /// 动态创建的kobject对象的ktype
  306. #[derive(Debug)]
  307. pub struct DynamicKObjKType;
  308. impl KObjType for DynamicKObjKType {
  309. fn release(&self, kobj: Arc<dyn KObject>) {
  310. debug!("DynamicKObjKType::release() kobj:{:?}", kobj.name());
  311. }
  312. fn sysfs_ops(&self) -> Option<&dyn SysFSOps> {
  313. Some(&KObjectSysFSOps)
  314. }
  315. fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
  316. None
  317. }
  318. }