mod.rs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. use crate::driver::base::uevent::kobject_uevent::kobject_uevent_env;
  2. use core::fmt::Write;
  3. /*
  4. Struct
  5. kset_uevent_ops
  6. Function
  7. get_ktype
  8. kobject_name
  9. kset_get
  10. kset_put
  11. to_kset
  12. */
  13. use crate::driver::base::kobject::KObject;
  14. use crate::driver::net::Iface;
  15. use crate::filesystem::sysfs::{Attribute, SysFSOpsSupport, SYSFS_ATTR_MODE_RW};
  16. use alloc::string::{String, ToString};
  17. use alloc::sync::Arc;
  18. use alloc::vec::Vec;
  19. use intertrait::cast::CastArc;
  20. use log::warn;
  21. use system_error::SystemError;
  22. use super::block::block_device::{BlockDevice, BlockDeviceOps};
  23. use super::char::CharDevice;
  24. use super::device::{Device, DeviceType};
  25. pub mod kobject_uevent;
  26. // https://code.dragonos.org.cn/xref/linux-6.1.9/lib/kobject_uevent.c?fi=kobject_uevent#457
  27. #[derive(Debug)]
  28. pub enum KobjectAction {
  29. KOBJADD,
  30. KOBJREMOVE, // Kobject(或上层数据结构)的添加/移除事件
  31. KOBJCHANGE, // Kobject(或上层数据结构)的状态或者内容发生改变; 如果设备驱动需要上报的事件不再上面事件的范围内,或者是自定义的事件,可以使用该event,并携带相应的参数。
  32. KOBJMOVE, // Kobject(或上层数据结构)更改名称或者更改Parent(意味着在sysfs中更改了目录结构)
  33. KOBJONLINE,
  34. KOBJOFFLINE, // Kobject(或上层数据结构)的上线/下线事件,其实是是否使能
  35. KOBJBIND,
  36. KOBJUNBIND,
  37. }
  38. /// 解析一个字符串,以确定它代表的是哪个 kobject_action,并提取出随后的参数(如果有的话)
  39. fn kobject_action_type(buf: &[u8]) -> Result<(KobjectAction, Vec<String>), SystemError> {
  40. let mut action = KobjectAction::KOBJCHANGE;
  41. let mut action_args: Vec<String> = Vec::new();
  42. let mut count = buf.len();
  43. if count != 0 && (buf[count - 1] == b'\n' || buf[count - 1] == b'\0') {
  44. count -= 1;
  45. }
  46. if count == 0 {
  47. return Err(SystemError::EINVAL);
  48. }
  49. let arg_start = buf.iter().position(|&c| c == b' ').unwrap_or(count);
  50. let count_first = arg_start;
  51. let args_start = arg_start + 1;
  52. // 匹配KobjectAction
  53. match &buf[..count_first] {
  54. b"add" => action = KobjectAction::KOBJADD,
  55. b"remove" => action = KobjectAction::KOBJREMOVE,
  56. b"change" => action = KobjectAction::KOBJCHANGE,
  57. b"move" => action = KobjectAction::KOBJMOVE,
  58. b"online" => action = KobjectAction::KOBJONLINE,
  59. b"offline" => action = KobjectAction::KOBJOFFLINE,
  60. b"bind" => action = KobjectAction::KOBJBIND,
  61. b"unbind" => action = KobjectAction::KOBJUNBIND,
  62. _ => return Err(SystemError::EINVAL),
  63. }
  64. // 如果有参数,提取参数
  65. if count - args_start > 0 {
  66. action_args = buf[args_start..]
  67. .split(|&c| c == b' ')
  68. .map(|s| String::from_utf8_lossy(s).to_string())
  69. .collect::<Vec<_>>();
  70. }
  71. Ok((action, action_args))
  72. }
  73. pub const UEVENT_NUM_ENVP: usize = 64;
  74. pub const UEVENT_BUFFER_SIZE: usize = 2048;
  75. pub const UEVENT_HELPER_PATH_LEN: usize = 256;
  76. /// 表示处理内核对象 uevents 的环境
  77. /// - envp,指针数组,用于保存每个环境变量的地址,最多可支持的环境变量数量为UEVENT_NUM_ENVP。
  78. /// - envp_idx,用于访问环境变量指针数组的index。
  79. /// - buf,保存环境变量的buffer,最大为UEVENT_BUFFER_SIZE。
  80. /// - buflen,访问buf的变量。
  81. // https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/kobject.h#31
  82. #[derive(Debug)]
  83. pub struct KobjUeventEnv {
  84. argv: Vec<String>,
  85. envp: Vec<String>,
  86. envp_idx: usize,
  87. buf: Vec<u8>,
  88. buflen: usize,
  89. }
  90. // kset_uevent_ops是为kset量身订做的一个数据结构,里面包含filter和uevent两个回调函数,用处如下:
  91. /*
  92. filter,当任何Kobject需要上报uevent时,它所属的kset可以通过该接口过滤,阻止不希望上报的event,从而达到从整体上管理的目的。
  93. name,该接口可以返回kset的名称。如果一个kset没有合法的名称,则其下的所有Kobject将不允许上报uvent
  94. uevent,当任何Kobject需要上报uevent时,它所属的kset可以通过该接口统一为这些event添加环境变量。因为很多时候上报uevent时的环境变量都是相同的,因此可以由kset统一处理,就不需要让每个Kobject独自添加了。
  95. */
  96. /// 设备文件夹下的`uevent`文件的属性
  97. #[derive(Debug, Clone, Copy)]
  98. pub struct UeventAttr;
  99. impl Attribute for UeventAttr {
  100. fn name(&self) -> &str {
  101. "uevent"
  102. }
  103. fn mode(&self) -> crate::filesystem::vfs::syscall::ModeType {
  104. SYSFS_ATTR_MODE_RW
  105. }
  106. fn support(&self) -> crate::filesystem::sysfs::SysFSOpsSupport {
  107. SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE
  108. }
  109. /// 用户空间读取 uevent 文件,返回 uevent 信息
  110. fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
  111. let device = _kobj.cast::<dyn Device>().map_err(|e: Arc<dyn KObject>| {
  112. warn!("device:{:?} is not a device!", e);
  113. SystemError::EINVAL
  114. })?;
  115. log::info!("show uevent");
  116. let device_type = device.dev_type();
  117. let mut uevent_content = String::new();
  118. log::info!("device_type: {:?}", device_type);
  119. match device_type {
  120. DeviceType::Block => {
  121. let major = device.id_table().device_number().major().data();
  122. let minor = device.id_table().device_number().minor();
  123. let device_name = device.id_table().name();
  124. writeln!(&mut uevent_content, "MAJOR={:?}", major).unwrap();
  125. writeln!(&mut uevent_content, "MINOR={:?}", minor).unwrap();
  126. writeln!(&mut uevent_content, "DEVNAME={}", device_name).unwrap();
  127. writeln!(&mut uevent_content, "DEVTYPE=disk").unwrap();
  128. }
  129. DeviceType::Char => {
  130. let major = device.id_table().device_number().major().data();
  131. let minor = device.id_table().device_number().minor();
  132. let device_name = device.id_table().name();
  133. writeln!(&mut uevent_content, "MAJOR={}", major).unwrap();
  134. writeln!(&mut uevent_content, "MINOR={}", minor).unwrap();
  135. writeln!(&mut uevent_content, "DEVNAME={}", device_name).unwrap();
  136. writeln!(&mut uevent_content, "DEVTYPE=char").unwrap();
  137. }
  138. DeviceType::Net => {
  139. let net_device =
  140. device
  141. .clone()
  142. .cast::<dyn Iface>()
  143. .map_err(|e: Arc<dyn Device>| {
  144. warn!("device:{:?} is not a net device!", e);
  145. SystemError::EINVAL
  146. })?;
  147. let iface_id = net_device.nic_id();
  148. let device_name = device.name();
  149. writeln!(&mut uevent_content, "INTERFACE={}", device_name).unwrap();
  150. writeln!(&mut uevent_content, "IFINDEX={}", iface_id).unwrap();
  151. }
  152. DeviceType::Bus => {
  153. // 处理总线设备类型
  154. let device_name = device.name();
  155. writeln!(&mut uevent_content, "DEVNAME={}", device_name).unwrap();
  156. writeln!(&mut uevent_content, "DEVTYPE=bus").unwrap();
  157. }
  158. DeviceType::Rtc => {
  159. // 处理RTC设备类型
  160. let device_name = device.name();
  161. writeln!(&mut uevent_content, "DEVNAME={}", device_name).unwrap();
  162. writeln!(&mut uevent_content, "DEVTYPE=rtc").unwrap();
  163. }
  164. DeviceType::Pci => {
  165. // 处理PCI设备类型
  166. let device_name = device.name();
  167. writeln!(&mut uevent_content, "DEVNAME={}", device_name).unwrap();
  168. writeln!(&mut uevent_content, "DEVTYPE=pci").unwrap();
  169. }
  170. _ => {
  171. // 处理其他设备类型
  172. let device_name = device.name();
  173. writeln!(&mut uevent_content, "DEVNAME={}", device_name).unwrap();
  174. writeln!(&mut uevent_content, "DEVTYPE={:?}", device_type).unwrap();
  175. }
  176. }
  177. sysfs_emit_str(_buf, &uevent_content)
  178. }
  179. /// 捕获来自用户空间对 uevent 文件的写操作,触发uevent事件
  180. fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
  181. log::info!("store uevent");
  182. return kobject_synth_uevent(_buf, _kobj);
  183. }
  184. }
  185. /// 将设备的基本信息写入 uevent 文件
  186. fn sysfs_emit_str(buf: &mut [u8], content: &str) -> Result<usize, SystemError> {
  187. log::info!("sysfs_emit_str");
  188. let bytes = content.as_bytes();
  189. if buf.len() < bytes.len() {
  190. return Err(SystemError::ENOMEM);
  191. }
  192. buf[..bytes.len()].copy_from_slice(bytes);
  193. Ok(bytes.len())
  194. }
  195. /// 解析用户空间写入的 uevent 信息,触发 uevent 事件
  196. fn kobject_synth_uevent(buf: &[u8], kobj: Arc<dyn KObject>) -> Result<usize, SystemError> {
  197. let no_uuid_envp = vec!["SYNTH_UUID=0".to_string()];
  198. let (action, action_args) = kobject_action_type(buf)?;
  199. let result = if action_args.is_empty() {
  200. kobject_uevent_env(kobj.clone(), action, no_uuid_envp)
  201. } else {
  202. kobject_uevent_env(kobj.clone(), action, action_args)
  203. };
  204. if let Err(e) = result {
  205. let device = kobj.cast::<dyn Device>().map_err(|e: Arc<dyn KObject>| {
  206. warn!("device:{:?} is not a device!", e);
  207. SystemError::EINVAL
  208. })?;
  209. let devname = device.name();
  210. log::error!("synth uevent: {}: {:?}", devname, e);
  211. return Err(SystemError::EINVAL);
  212. }
  213. Ok(buf.len())
  214. }