Bladeren bron

feat: 支持 sysfs下 block, char, Net, rtc, tty 等类型设备的 uevent 文件读操作 (#973)

* 新增CommonAttrGroup,基本支持sysfs下各种类型设备的uevent属性文件的读测试

* 修改net设备的uevent内容,使之与Linux语义一致

* 删除无用注释
Val213 5 maanden geleden
bovenliggende
commit
38d161ccfe

+ 1 - 1
kernel/src/arch/x86_64/syscall/mod.rs

@@ -133,7 +133,7 @@ pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) {
                 show &= false;
             }
         }
-
+        show = false;
         if show {
             debug!("[SYS] [Pid: {:?}] [Call: {:?}]", pid, to_print);
         }

+ 3 - 4
kernel/src/driver/base/block/block_device.rs

@@ -1,9 +1,8 @@
 /// 引入Module
-use crate::driver::{
+use crate::{driver::{
     base::{
         device::{
-            device_number::{DeviceNumber, Major},
-            Device, DeviceError, IdTable, BLOCKDEVS,
+            device_number::{DeviceNumber, Major}, Device, DeviceError, IdTable, BLOCKDEVS
         },
         map::{
             DeviceStruct, DEV_MAJOR_DYN_END, DEV_MAJOR_DYN_EXT_END, DEV_MAJOR_DYN_EXT_START,
@@ -11,7 +10,7 @@ use crate::driver::{
         },
     },
     block::cache::{cached_block_device::BlockCache, BlockCacheError, BLOCK_SIZE},
-};
+}, filesystem::sysfs::AttributeGroup};
 
 use alloc::{string::String, sync::Arc, vec::Vec};
 use core::{any::Any, fmt::Display, ops::Deref};

+ 20 - 0
kernel/src/driver/base/device/mod.rs

@@ -43,6 +43,7 @@ use super::{
     },
     kset::KSet,
     swnode::software_node_notify,
+    uevent::UeventAttr,
 };
 
 pub mod bus;
@@ -1025,6 +1026,25 @@ impl Eq for DeviceId {}
 
 impl IrqHandlerData for DeviceId {}
 
+/// sysfs下设备的通用属性组
+#[derive(Debug)]
+pub struct CommonAttrGroup;
+impl AttributeGroup for CommonAttrGroup {
+    fn name(&self) -> Option<&str> {
+        None
+    }
+    fn attrs(&self) -> &[&'static dyn Attribute] {
+        &[&UeventAttr]
+    }
+    fn is_visible(
+        &self,
+        _kobj: alloc::sync::Arc<dyn KObject>,
+        attr: &'static dyn Attribute,
+    ) -> Option<crate::filesystem::vfs::syscall::ModeType> {
+        Some(attr.mode())
+    }
+}
+
 lazy_static! {
     /// class_dir列表,通过parent kobject的name和class_dir的name来索引class_dir实例
     static ref CLASS_DIR_KSET_INSTANCE: RwLock<BTreeMap<String, Arc<ClassDir>>> = RwLock::new(BTreeMap::new());

+ 1 - 1
kernel/src/driver/base/kobject.rs

@@ -22,7 +22,7 @@ use crate::{
 
 use system_error::SystemError;
 
-use super::{kset::KSet, uevent::kobject_uevent};
+use super::{device::CommonAttrGroup, kset::KSet, uevent::kobject_uevent};
 
 pub trait KObject: Any + Send + Sync + Debug + CastFromSync {
     fn as_any_ref(&self) -> &dyn core::any::Any;

+ 6 - 2
kernel/src/driver/base/platform/platform_device.rs

@@ -11,12 +11,12 @@ use crate::{
             bus::{Bus, BusState},
             device_manager,
             driver::Driver,
-            Device, DeviceCommonData, DevicePrivateData, DeviceType, IdTable,
+            CommonAttrGroup, Device, DeviceCommonData, DevicePrivateData, DeviceType, IdTable,
         },
         kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
         kset::KSet,
     },
-    filesystem::kernfs::KernFSInode,
+    filesystem::{kernfs::KernFSInode, sysfs::AttributeGroup},
     libs::{
         rwlock::{RwLockReadGuard, RwLockWriteGuard},
         spinlock::{SpinLock, SpinLockGuard},
@@ -329,4 +329,8 @@ impl Device for PlatformBusDevice {
     fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
         self.inner().device_common.parent = dev_parent;
     }
+
+    fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
+        Some(&[&CommonAttrGroup])
+    }
 }

+ 44 - 28
kernel/src/driver/base/uevent/mod.rs

@@ -19,6 +19,7 @@ use alloc::string::{String, ToString};
 use alloc::sync::Arc;
 use alloc::vec::Vec;
 use intertrait::cast::CastArc;
+use log::warn;
 use system_error::SystemError;
 
 use super::block::block_device::{BlockDevice, BlockDeviceOps};
@@ -128,46 +129,60 @@ impl Attribute for UeventAttr {
 
     /// 用户空间读取 uevent 文件,返回 uevent 信息
     fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
-        let device: Arc<dyn KObject> = _kobj
-            .parent()
-            .and_then(|x| x.upgrade())
-            .ok_or(SystemError::ENODEV)?;
-        let device = kobj2device(device).ok_or(SystemError::EINVAL)?;
+        let device = _kobj.cast::<dyn Device>().map_err(|e: Arc<dyn KObject>| {
+            warn!("device:{:?} is not a device!", e);
+            SystemError::EINVAL
+        })?;
+        log::info!("show uevent");
         let device_type = device.dev_type();
         let mut uevent_content = String::new();
+        log::info!("device_type: {:?}", device_type);
         match device_type {
             DeviceType::Block => {
-                let block_device = device
-                    .cast::<dyn BlockDevice>()
-                    .ok()
-                    .ok_or(SystemError::EINVAL)?;
-                let major = block_device.id_table().device_number().major().data();
-                let minor = block_device.id_table().device_number().minor();
-                let device_name = block_device.id_table().name();
+                let major = device.id_table().device_number().major().data();
+                let minor = device.id_table().device_number().minor();
+                let device_name = device.id_table().name();
                 writeln!(&mut uevent_content, "MAJOR={:?}", major).unwrap();
                 writeln!(&mut uevent_content, "MINOR={:?}", minor).unwrap();
                 writeln!(&mut uevent_content, "DEVNAME={}", device_name).unwrap();
                 writeln!(&mut uevent_content, "DEVTYPE=disk").unwrap();
             }
             DeviceType::Char => {
-                let char_device = device
-                    .cast::<dyn CharDevice>()
-                    .ok()
-                    .ok_or(SystemError::EINVAL)?;
-                let major = char_device.id_table().device_number().major().data();
-                let minor = char_device.id_table().device_number().minor();
-                let device_name = char_device.id_table().name();
+                let major = device.id_table().device_number().major().data();
+                let minor = device.id_table().device_number().minor();
+                let device_name = device.id_table().name();
                 writeln!(&mut uevent_content, "MAJOR={}", major).unwrap();
                 writeln!(&mut uevent_content, "MINOR={}", minor).unwrap();
                 writeln!(&mut uevent_content, "DEVNAME={}", device_name).unwrap();
                 writeln!(&mut uevent_content, "DEVTYPE=char").unwrap();
             }
             DeviceType::Net => {
-                let net_device = device.cast::<dyn Iface>().ok().ok_or(SystemError::EINVAL)?;
-                // let ifindex = net_device.ifindex().expect("Find ifindex error.\n");
-                let device_name = net_device.iface_name();
+                let net_device = device.clone().cast::<dyn Iface>().map_err(|e: Arc<dyn Device>| {
+                    warn!("device:{:?} is not a net device!", e);
+                    SystemError::EINVAL
+                })?;
+                let iface_id = net_device.nic_id();
+                let device_name = device.name();
                 writeln!(&mut uevent_content, "INTERFACE={}", device_name).unwrap();
-                // writeln!(&mut uevent_content, "IFINDEX={}", ifindex).unwrap();
+                writeln!(&mut uevent_content, "IFINDEX={}", iface_id).unwrap();
+            }
+            DeviceType::Bus => {
+                // 处理总线设备类型
+                let device_name = device.name();
+                writeln!(&mut uevent_content, "DEVNAME={}", device_name).unwrap();
+                writeln!(&mut uevent_content, "DEVTYPE=bus").unwrap();
+            }
+            DeviceType::Rtc => {
+                // 处理RTC设备类型
+                let device_name = device.name();
+                writeln!(&mut uevent_content, "DEVNAME={}", device_name).unwrap();
+                writeln!(&mut uevent_content, "DEVTYPE=rtc").unwrap();
+            }
+            DeviceType::Pci => {
+                // 处理PCI设备类型
+                let device_name = device.name();
+                writeln!(&mut uevent_content, "DEVNAME={}", device_name).unwrap();
+                writeln!(&mut uevent_content, "DEVTYPE=pci").unwrap();
             }
             _ => {
                 // 处理其他设备类型
@@ -180,17 +195,15 @@ impl Attribute for UeventAttr {
     }
     /// 捕获来自用户空间对 uevent 文件的写操作,触发uevent事件
     fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
+        log::info!("store uevent");
         return kobject_synth_uevent(_buf, _kobj);
     }
 }
 
-/// 将 kobject 转换为 device
-fn kobj2device(kobj: Arc<dyn KObject>) -> Option<Arc<dyn Device>> {
-    kobj.cast::<dyn Device>().ok()
-}
 
 /// 将设备的基本信息写入 uevent 文件
 fn sysfs_emit_str(buf: &mut [u8], content: &str) -> Result<usize, SystemError> {
+    log::info!("sysfs_emit_str");
     let bytes = content.as_bytes();
     if buf.len() < bytes.len() {
         return Err(SystemError::ENOMEM);
@@ -211,7 +224,10 @@ fn kobject_synth_uevent(buf: &[u8], kobj: Arc<dyn KObject>) -> Result<usize, Sys
     };
 
     if let Err(e) = result {
-        let device = kobj2device(kobj).ok_or(SystemError::EINVAL)?;
+        let device = kobj.cast::<dyn Device>().map_err(|e: Arc<dyn KObject>| {
+            warn!("device:{:?} is not a device!", e);
+            SystemError::EINVAL
+        })?;
         let devname = device.name();
         log::error!("synth uevent: {}: {:?}", devname, e);
         return Err(SystemError::EINVAL);

+ 8 - 4
kernel/src/driver/block/virtio_blk.rs

@@ -24,7 +24,7 @@ use crate::{
             device::{
                 bus::Bus,
                 driver::{Driver, DriverCommonData},
-                Device, DeviceCommonData, DeviceId, DeviceType, IdTable,
+                CommonAttrGroup, Device, DeviceCommonData, DeviceId, DeviceType, IdTable,
             },
             kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
             kset::KSet,
@@ -38,7 +38,7 @@ use crate::{
         },
     },
     exception::{irqdesc::IrqReturn, IrqNumber},
-    filesystem::{kernfs::KernFSInode, mbr::MbrDiskPartionTable},
+    filesystem::{kernfs::KernFSInode, mbr::MbrDiskPartionTable, sysfs::AttributeGroup},
     init::initcall::INITCALL_POSTCORE,
     libs::{
         rwlock::{RwLockReadGuard, RwLockWriteGuard},
@@ -342,7 +342,7 @@ impl VirtIODevice for VirtIOBlkDevice {
 
 impl Device for VirtIOBlkDevice {
     fn dev_type(&self) -> DeviceType {
-        DeviceType::Net
+        DeviceType::Block
     }
 
     fn id_table(&self) -> IdTable {
@@ -407,6 +407,10 @@ impl Device for VirtIOBlkDevice {
     fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
         self.inner().device_common.parent = parent;
     }
+
+    fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
+        Some(&[&CommonAttrGroup])
+    }
 }
 
 impl KObject for VirtIOBlkDevice {
@@ -472,7 +476,7 @@ fn virtio_blk_driver_init() -> Result<(), SystemError> {
     let driver = VirtIOBlkDriver::new();
     virtio_driver_manager()
         .register(driver.clone() as Arc<dyn VirtIODriver>)
-        .expect("Add virtio net driver failed");
+        .expect("Add virtio block driver failed");
     unsafe {
         VIRTIO_BLK_DRIVER = Some(driver);
     }

+ 2 - 2
kernel/src/driver/net/class.rs

@@ -1,7 +1,7 @@
 use crate::{
     driver::base::{
         class::{class_manager, Class},
-        device::sys_dev_char_kset,
+        device::{sys_dev_char_kset, CommonAttrGroup},
         kobject::KObject,
         subsys::SubSysPrivate,
     },
@@ -78,6 +78,6 @@ impl Class for NetClass {
     }
 
     fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
-        return &[&NetAttrGroup];
+        return &[&NetAttrGroup, &CommonAttrGroup];
     }
 }

+ 6 - 2
kernel/src/driver/net/virtio_net.rs

@@ -25,7 +25,7 @@ use crate::{
             device::{
                 bus::Bus,
                 driver::{Driver, DriverCommonData},
-                Device, DeviceCommonData, DeviceId, DeviceType, IdTable,
+                CommonAttrGroup, Device, DeviceCommonData, DeviceId, DeviceType, IdTable,
             },
             kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
             kset::KSet,
@@ -41,7 +41,7 @@ use crate::{
         },
     },
     exception::{irqdesc::IrqReturn, IrqNumber},
-    filesystem::kernfs::KernFSInode,
+    filesystem::{kernfs::KernFSInode, sysfs::AttributeGroup},
     init::initcall::INITCALL_POSTCORE,
     libs::{
         rwlock::{RwLockReadGuard, RwLockWriteGuard},
@@ -249,6 +249,10 @@ impl Device for VirtIONetDevice {
     fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
         self.inner().device_common.parent = parent;
     }
+
+    fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
+        Some(&[&CommonAttrGroup])
+    }
 }
 
 impl VirtIODevice for VirtIONetDevice {

+ 5 - 2
kernel/src/driver/pci/raw_device.rs

@@ -8,7 +8,10 @@ use alloc::{
 use crate::{
     driver::base::{
         class::Class,
-        device::{bus::Bus, driver::Driver, Device, DeviceCommonData, DeviceType, IdTable},
+        device::{
+            bus::Bus, driver::Driver, CommonAttrGroup, Device, DeviceCommonData, DeviceType,
+            IdTable,
+        },
         kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
         kset::KSet,
     },
@@ -84,7 +87,7 @@ impl PciDevice for PciGeneralDevice {
 
 impl Device for PciGeneralDevice {
     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
-        Some(&[&BasicPciReadOnlyAttrs])
+        Some(&[&BasicPciReadOnlyAttrs, &CommonAttrGroup])
     }
 
     fn bus(&self) -> Option<Weak<dyn Bus>> {

+ 5 - 2
kernel/src/driver/pci/test/pt_device.rs

@@ -10,7 +10,10 @@ use crate::{
     driver::{
         base::{
             class::Class,
-            device::{bus::Bus, driver::Driver, Device, DeviceCommonData, DeviceType, IdTable},
+            device::{
+                bus::Bus, driver::Driver, CommonAttrGroup, Device, DeviceCommonData, DeviceType,
+                IdTable,
+            },
             kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
             kset::KSet,
         },
@@ -74,7 +77,7 @@ impl PciDevice for TestDevice {
 
 impl Device for TestDevice {
     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
-        Some(&[&HelloAttr])
+        Some(&[&HelloAttr, &CommonAttrGroup])
     }
 
     fn bus(&self) -> Option<Weak<dyn Bus>> {

+ 5 - 1
kernel/src/driver/rtc/class.rs

@@ -9,10 +9,11 @@ use unified_init::macros::unified_init;
 use crate::{
     driver::base::{
         class::{class_manager, Class},
-        device::{device_manager, sys_dev_char_kset},
+        device::{device_manager, sys_dev_char_kset, CommonAttrGroup},
         kobject::KObject,
         subsys::SubSysPrivate,
     },
+    filesystem::sysfs::AttributeGroup,
     init::initcall::INITCALL_SUBSYS,
     time::{timekeeping::do_settimeofday64, PosixTimeSpec},
 };
@@ -78,6 +79,9 @@ impl Class for RtcClass {
     fn subsystem(&self) -> &SubSysPrivate {
         return &self.subsystem;
     }
+    fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
+        return &[&CommonAttrGroup];
+    }
 }
 
 /// 注册rtc通用设备

+ 3 - 2
kernel/src/driver/rtc/sysfs.rs

@@ -9,7 +9,8 @@ use crate::{
     driver::base::{
         class::Class,
         device::{
-            bus::Bus, device_manager, driver::Driver, Device, DeviceCommonData, DeviceType, IdTable,
+            bus::Bus, device_manager, driver::Driver, CommonAttrGroup, Device, DeviceCommonData,
+            DeviceType, IdTable,
         },
         kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
         kset::KSet,
@@ -172,7 +173,7 @@ impl Device for RtcGeneralDevice {
         true
     }
     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
-        Some(&[&RtcAttrGroup])
+        Some(&[&RtcAttrGroup, &CommonAttrGroup])
     }
 
     fn dev_parent(&self) -> Option<Weak<dyn Device>> {

+ 6 - 1
kernel/src/driver/tty/sysfs.rs

@@ -8,10 +8,11 @@ use unified_init::macros::unified_init;
 use crate::{
     driver::base::{
         class::{class_manager, Class},
-        device::sys_dev_char_kset,
+        device::{sys_dev_char_kset, CommonAttrGroup},
         kobject::KObject,
         subsys::SubSysPrivate,
     },
+    filesystem::sysfs::AttributeGroup,
     init::initcall::INITCALL_SUBSYS,
 };
 
@@ -61,6 +62,10 @@ impl Class for TtyClass {
     fn subsystem(&self) -> &SubSysPrivate {
         return &self.subsystem;
     }
+
+    fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
+        return &[&CommonAttrGroup];
+    }
 }
 
 /// 初始化帧缓冲区子系统

+ 3 - 3
kernel/src/driver/video/fbdev/base/fbcon/mod.rs

@@ -11,8 +11,8 @@ use crate::{
         base::{
             class::Class,
             device::{
-                bus::Bus, device_manager, driver::Driver, Device, DeviceCommonData, DeviceType,
-                IdTable,
+                bus::Bus, device_manager, driver::Driver, CommonAttrGroup, Device,
+                DeviceCommonData, DeviceType, IdTable,
             },
             kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
             kset::KSet,
@@ -235,7 +235,7 @@ impl Device for FbConsoleDevice {
     }
 
     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
-        return Some(&[&AnonymousAttributeGroup]);
+        return Some(&[&AnonymousAttributeGroup, &CommonAttrGroup]);
     }
 
     fn dev_parent(&self) -> Option<Weak<dyn Device>> {

+ 6 - 2
kernel/src/driver/video/fbdev/base/fbmem.rs

@@ -18,7 +18,7 @@ use crate::{
             device_manager,
             device_number::{DeviceNumber, Major},
             driver::Driver,
-            sys_dev_char_kset, Device, DeviceCommonData, DeviceType, IdTable,
+            sys_dev_char_kset, CommonAttrGroup, Device, DeviceCommonData, DeviceType, IdTable,
         },
         kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
         kset::KSet,
@@ -112,6 +112,10 @@ impl Class for GraphicsClass {
     fn subsystem(&self) -> &SubSysPrivate {
         return &self.subsystem;
     }
+
+    fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
+        return &[&CommonAttrGroup];
+    }
 }
 
 /// 帧缓冲区管理器
@@ -373,7 +377,7 @@ impl Device for FbDevice {
     }
 
     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
-        Some(&[&FbDeviceAttrGroup])
+        Some(&[&FbDeviceAttrGroup, &CommonAttrGroup])
     }
 
     fn dev_parent(&self) -> Option<Weak<dyn Device>> {

+ 2 - 1
kernel/src/exception/sysfs.rs

@@ -5,6 +5,7 @@ use unified_init::macros::unified_init;
 
 use crate::{
     driver::base::{
+        device::CommonAttrGroup,
         kobject::{KObjType, KObject, KObjectManager, KObjectSysFSOps},
         kset::KSet,
     },
@@ -45,7 +46,7 @@ impl KObjType for IrqKObjType {
     }
 
     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
-        Some(&[&IrqAttrGroup])
+        Some(&[&IrqAttrGroup, &CommonAttrGroup])
     }
 
     fn release(&self, _kobj: Arc<dyn KObject>) {