Browse Source

清理积弊,不必要的动态分发和智能指针

val213 5 months ago
parent
commit
d7be7deebc

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

@@ -1,8 +1,9 @@
 /// 引入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,
@@ -10,7 +11,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};

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

@@ -1,7 +1,6 @@
 use core::{any::Any, fmt::Debug, hash::Hash, ops::Deref};
 
 use alloc::{
-    boxed::Box,
     string::String,
     sync::{Arc, Weak},
 };
@@ -22,7 +21,7 @@ use crate::{
 
 use system_error::SystemError;
 
-use super::{device::CommonAttrGroup, kset::KSet, uevent::kobject_uevent};
+use super::kset::KSet;
 
 pub trait KObject: Any + Send + Sync + Debug + CastFromSync {
     fn as_any_ref(&self) -> &dyn core::any::Any;
@@ -263,7 +262,6 @@ impl KObjectManager {
 
     fn get_kobj_path_length(kobj: &Arc<dyn KObject>) -> usize {
         log::info!("get_kobj_path_length() kobj:{:?}", kobj.name());
-        let mut length = 1;
         let mut parent = kobj.parent().unwrap().upgrade().unwrap();
         /* walk up the ancestors until we hit the one pointing to the
          * root.

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

@@ -259,6 +259,6 @@ impl KSetUeventOps for KSetUeventOpsDefault {
     }
 
     fn uevent(&self, env: &KobjUeventEnv) -> i32 {
-        0
+        todo!()
     }
 }

+ 8 - 86
kernel/src/driver/base/uevent/kobject_uevent.rs

@@ -83,15 +83,6 @@ fn uevent_net_exit() {
     UEVENT_SOCK_LIST.lock().clear();
 }
 
-// /* This lock protects uevent_seqnum and uevent_sock_list */
-// static DEFINE_MUTEX(uevent_sock_mutex);
-
-/*
-
-
-
-*/
-
 /// kobject_uevent,和kobject_uevent_env功能一样,只是没有指定任何的环境变量
 pub fn kobject_uevent(kobj: Arc<dyn KObject>, action: KobjectAction) -> Result<(), SystemError> {
     // kobject_uevent和kobject_uevent_env功能一样,只是没有指定任何的环境变量
@@ -101,7 +92,7 @@ pub fn kobject_uevent(kobj: Arc<dyn KObject>, action: KobjectAction) -> Result<(
     }
 }
 
-///  kobject_uevent_env,以envp为环境变量,上报一个指定action的uevent。环境变量的作用是为执行用户空间程序指定运行环境。
+///  kobject_uevent_env,以 envp 为环境变量,上报一个指定 action  uevent。环境变量的作用是为执行用户空间程序指定运行环境。
 pub fn kobject_uevent_env(
     kobj: Arc<dyn KObject>,
     action: KobjectAction,
@@ -271,43 +262,7 @@ pub fn kobject_uevent_env(
         return Ok(retval);
     }
     retval = kobject_uevent_net_broadcast(kobj, &env, &action_string, &devpath);
-    //mutex_unlock(&uevent_sock_mutex);
-
-    #[cfg(feature = "UEVENT_HELPER")]
-    fn handle_uevent_helper() {
-        // TODO
-        // 在特性 `UEVENT_HELPER` 开启的情况下,这里的代码会执行
-        // 指定处理uevent的用户空间程序,通常是热插拔程序mdev、udevd等
-        // 	/* call uevent_helper, usually only enabled during early boot */
-        // 	if (uevent_helper[0] && !kobj_usermode_filter(kobj)) {
-        // 		struct subprocess_info *info;
-
-        // 		retval = add_uevent_var(env, "HOME=/");
-        // 		if (retval)
-        // 			goto exit;
-        // 		retval = add_uevent_var(env,
-        // 					"PATH=/sbin:/bin:/usr/sbin:/usr/bin");
-        // 		if (retval)
-        // 			goto exit;
-        // 		retval = init_uevent_argv(env, subsystem);
-        // 		if (retval)
-        // 			goto exit;
-
-        // 		retval = -ENOMEM;
-        // 		info = call_usermodehelper_setup(env->argv[0], env->argv,
-        // 						 env->envp, GFP_KERNEL,
-        // 						 NULL, cleanup_uevent_env, env);
-        // 		if (info) {
-        // 			retval = call_usermodehelper_exec(info, UMH_NO_WAIT);
-        // 			env = NULL;	/* freed by cleanup_uevent_env */
-        // 		}
-        // 	}
-    }
-    #[cfg(not(feature = "UEVENT_HELPER"))]
-    fn handle_uevent_helper() {
-        // 在特性 `UEVENT_HELPER` 关闭的情况下,这里的代码会执行
-    }
-    handle_uevent_helper();
+    // todo: 设置了 UEVENT_HELP 编译条件之后,使用 handle_uevent_helper() 对指定的 uevent 进行处理,通常是热插拔程序 mdev、udev 等
     drop(devpath);
     drop(env);
     log::info!("kobject_uevent_env: retval: {}", retval);
@@ -383,53 +338,20 @@ pub fn kobject_uevent_net_broadcast(
     action_string: &str,
     devpath: &str,
 ) -> i32 {
-    // let net:Net = None;
-    // let mut ops = kobj_ns_ops(kobj);
-
-    // if (!ops && kobj.kset().is_some()) {
-    // 	let ksobj:KObject = &kobj.kset().kobj();
-
-    // 	if (ksobj.parent() != NULL){
-    //         ops = kobj_ns_ops(ksobj.parent());
-    //     }
-
-    // }
-    // TODO: net结构体?
-    // https://code.dragonos.org.cn/xref/linux-6.1.9/include/net/net_namespace.h#60
-    /* kobjects currently only carry network namespace tags and they
-     * are the only tag relevant here since we want to decide which
-     * network namespaces to broadcast the uevent into.
-     */
-    // if (ops && ops.netlink_ns() && kobj.ktype().namespace())
-    // 	if (ops.type() == KOBJ_NS_TYPE_NET)
-    // 		net = kobj.ktype().namespace(kobj);
+    // TODO: net namespace
     // 如果有网络命名空间,则广播标记的uevent;如果没有,则广播未标记的uevent
-    // if !net.is_none() {
-    //     ret = uevent_net_broadcast_tagged(net.unwrap(), env, action_string, devpath);
-    // } else {
     let ret = uevent_net_broadcast_untagged(env, action_string, devpath);
-    // }
     log::info!("kobject_uevent_net_broadcast finish. ret: {}", ret);
     ret
 }
 
-pub fn uevent_net_broadcast_tagged(
-    sk: &dyn NetlinkSocket,
-    env: &KobjUeventEnv,
-    action_string: &str,
-    devpath: &str,
-) -> i32 {
-    let ret = 0;
-    ret
-}
-
 /// 分配一个用于 uevent 消息的 skb(socket buffer)。
 pub fn alloc_uevent_skb<'a>(
     env: &'a KobjUeventEnv,
     action_string: &'a str,
     devpath: &'a str,
 ) -> Arc<RwLock<SkBuff>> {
-    let skb = Arc::new(RwLock::new(SkBuff::new()));
+    let skb = Arc::new(RwLock::new(SkBuff::new(None)));
     skb
 }
 // https://code.dragonos.org.cn/xref/linux-6.1.9/lib/kobject_uevent.c#309
@@ -445,7 +367,7 @@ pub fn uevent_net_broadcast_untagged(
         devpath
     );
     let mut retval = 0;
-    let mut skb = Arc::new(RwLock::new(SkBuff::new()));
+    let mut skb = Arc::new(RwLock::new(SkBuff::new(None)));
 
     // 锁定 UEVENT_SOCK_LIST 并遍历
     let ue_sk_list = UEVENT_SOCK_LIST.lock();
@@ -456,16 +378,16 @@ pub fn uevent_net_broadcast_untagged(
             continue;
         }
         // 如果 skb 为空,则分配一个新的 skb
-        if skb.read().is_empty() {
+        if skb.read().inner.is_empty() {
             log::info!("uevent_net_broadcast_untagged: alloc_uevent_skb failed");
             retval = SystemError::ENOMEM.to_posix_errno();
             skb = alloc_uevent_skb(env, action_string, devpath);
-            if skb.read().is_empty() {
+            if skb.read().inner.is_empty() {
                 continue;
             }
         }
         log::info!("next is netlink_broadcast");
-        let netlink_socket: Arc<dyn NetlinkSocket> = Arc::new(ue_sk.inner.clone());
+        let netlink_socket = Arc::new(ue_sk.inner.clone());
         retval = match netlink_broadcast(&netlink_socket, Arc::clone(&skb), 0, 1, 1) {
             Ok(_) => 0,
             Err(err) => err.to_posix_errno(),

+ 8 - 5
kernel/src/driver/base/uevent/mod.rs

@@ -157,10 +157,14 @@ impl Attribute for UeventAttr {
                 writeln!(&mut uevent_content, "DEVTYPE=char").unwrap();
             }
             DeviceType::Net => {
-                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 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();
@@ -200,7 +204,6 @@ impl Attribute for UeventAttr {
     }
 }
 
-
 /// 将设备的基本信息写入 uevent 文件
 fn sysfs_emit_str(buf: &mut [u8], content: &str) -> Result<usize, SystemError> {
     log::info!("sysfs_emit_str");

+ 97 - 198
kernel/src/net/socket/netlink/af_netlink.rs

@@ -19,7 +19,7 @@ use hashbrown::HashMap;
 use intertrait::CastFromSync;
 use netlink::{
     sk_data_ready, NetlinkKernelCfg, NETLINK_ADD_MEMBERSHIP, NETLINK_DROP_MEMBERSHIP,
-    NETLINK_PKTINFO,
+    NETLINK_KOBJECT_UEVENT, NETLINK_PKTINFO,
 };
 use num::Zero;
 use system_error::SystemError;
@@ -57,7 +57,7 @@ pub struct HListHead {
 }
 #[derive(Debug)]
 pub struct HListNode {
-    data: Arc<Mutex<Box<dyn NetlinkSocket>>>,
+    data: Arc<Mutex<NetlinkSock>>,
     next: Option<Arc<HListNode>>,
 }
 impl HListHead {
@@ -73,7 +73,7 @@ struct HListHeadIter<'a> {
 }
 
 impl<'a> Iterator for HListHeadIter<'a> {
-    type Item = &'a Arc<Mutex<Box<dyn NetlinkSocket>>>;
+    type Item = &'a Arc<Mutex<NetlinkSock>>;
 
     fn next(&mut self) -> Option<Self::Item> {
         match self.current {
@@ -88,7 +88,7 @@ impl<'a> Iterator for HListHeadIter<'a> {
 type NetlinkSockComparator = Arc<dyn Fn(&NetlinkSock) -> bool + Send + Sync>;
 /// 每一个netlink协议族都有一个NetlinkTable,用于保存该协议族的所有netlink套接字
 pub struct NetlinkTable {
-    hash: HashMap<u32, Arc<Mutex<Box<dyn NetlinkSocket>>>>,
+    hash: HashMap<u32, Arc<Mutex<NetlinkSock>>>,
     listeners: Option<Listeners>,
     registered: u32,
     flags: u32,
@@ -102,9 +102,7 @@ impl NetlinkTable {
     fn new() -> NetlinkTable {
         NetlinkTable {
             hash: HashMap::new(),
-            listeners: Some(Listeners {
-                masks: Vec::with_capacity(32),
-            }),
+            listeners: Some(Listeners { masks: vec![0; 32] }),
             registered: 0,
             flags: 0,
             groups: 32,
@@ -114,15 +112,6 @@ impl NetlinkTable {
             compare: None,
         }
     }
-    fn listeners(&self) -> Listeners {
-        Listeners::new()
-    }
-    fn flags(&self) -> u32 {
-        0
-    }
-    fn groups(&self) -> u32 {
-        0
-    }
     pub fn set_registered(&mut self, registered: u32) {
         self.registered = registered;
     }
@@ -178,27 +167,8 @@ fn netlink_proto_init() -> Result<(), SystemError> {
 
 pub struct NetlinkFamulyOps {
     family: AddressFamily,
-    // owner: Module,
 }
 
-// impl NetProtoFamily for NetlinkFamulyOps {
-//     // https://code.dragonos.org.cn/s?refs=netlink_create&project=linux-6.1.9
-//     /// netlink_create() 用户空间创建一个netlink套接字
-//     fn create(socket: &mut dyn Socket, protocol: i32, _kern: bool) -> Result<(), Error> {
-//         // 假设我们有一个类型来跟踪协议最大值
-//         const MAX_LINKS: i32 = 1024;
-//         // if socket.type_ != SocketType::Raw && socket.type_ != SocketType::Dgram {
-//         //     return Err(Error::SocketTypeNotSupported);
-//         // }
-//         if !(0..MAX_LINKS).contains(&protocol) {
-//             // todo: 这里不符合规范,后续待修改为 SystemError
-//             return Err(Error::ProtocolNotSupported);
-//         }
-//         // 安全的数组索引封装
-//         let protocol = protocol as usize;
-//         Ok(())
-//     }
-// }
 
 lazy_static! {
     static ref NETLINK_FAMILY_OPS: NetlinkFamulyOps = NetlinkFamulyOps {
@@ -221,76 +191,61 @@ pub fn netlink_add_usersock_entry(nl_table: &mut RwLockWriteGuard<Vec<NetlinkTab
         "netlink_add_usersock_entry: nl_table[index].groups: {}",
         nl_table[index].groups
     );
-    // rcu_assign_pointer(nl_table[index].listeners, listeners);
-    // nl_table[index].module = THIS_MODULE;
+
     nl_table[index].registered = 1;
     nl_table[index].flags = NL_CFG_F_NONROOT_SEND;
 }
 // https://code.dragonos.org.cn/xref/linux-6.1.9/net/netlink/af_netlink.c#572
 /// 内核套接字插入 nl_table
-pub fn netlink_insert(
-    sk: Arc<Mutex<Box<dyn NetlinkSocket>>>,
-    portid: u32,
-) -> Result<(), SystemError> {
+pub fn netlink_insert(nlk: Arc<Mutex<NetlinkSock>>, portid: u32) -> Result<(), SystemError> {
     let mut nl_table: RwLockWriteGuard<Vec<NetlinkTable>> = NL_TABLE.write();
 
-    let index = sk.lock().sk_protocol();
-
-    let nlk = Arc::new(RwLock::new(
-        sk.lock()
-            .deref()
-            .as_any()
-            .downcast_ref::<NetlinkSock>()
-            .ok_or(SystemError::EINVAL)?
-            .clone(),
-    ));
-    {
-        let nlk_guard = nlk.read();
-        // 检查端口是否匹配
-        if nlk_guard.portid != portid {
-            log::debug!("netlink_insert: portid mismatch\n");
-            return Err(SystemError::EOVERFLOW);
-        }
+    let mut nlk_guard = nlk.lock();
+    let index = nlk_guard.sk_protocol();
+    // 检查端口是否匹配
+    if nlk_guard.portid != portid {
+        log::debug!(
+            "netlink_insert: portid mismatch. nlk_guard.portid: {}, portid: {}",
+            nlk_guard.portid,
+            portid
+        );
+        return Err(SystemError::EINVAL);
     }
 
-    {
-        let mut nlk_guard = nlk.write();
-        // 绑定端口
-        nlk_guard.portid = portid;
-        // 设置套接字已绑定
-        nlk_guard.bound = portid != 0;
-        // 将套接字插入哈希表
-        nl_table[index].hash.insert(portid, Arc::clone(&sk));
-        log::debug!("netlink_insert: inserted socket\n");
-    }
+    // 设置套接字已绑定
+    nlk_guard.bound = portid != 0;
+    // 将套接字插入哈希表
+    nl_table[index].hash.insert(portid, Arc::clone(&nlk));
+    log::debug!("netlink_insert: inserted socket\n");
 
     Ok(())
 }
-
+// https://code.dragonos.org.cn/xref/linux-6.1.9/net/netlink/af_netlink.c#990
+/// netlink 套接字绑定多播组
 fn netlink_bind(
     sock: Arc<Mutex<Box<dyn NetlinkSocket>>>,
     addr: &SockAddrNl,
 ) -> Result<(), SystemError> {
     log::info!("netlink_bind here!");
-    let sk: Arc<Mutex<Box<dyn NetlinkSocket>>> = Arc::clone(&sock);
     // todo: net namespace支持
-    // let net = sock_net(sk);
     log::info!("netlink_bind: nl_family: {:?}", addr.nl_family);
-    // let nlk: Arc<Mutex<NetlinkSock>> = sock
-    //     .clone()
-    //     .arc_any()
-    //     .downcast()
-    //     .map_err(|_| SystemError::EINVAL)?;
-
-    let nlk = Arc::new(Mutex::new(
-        sock.lock()
+
+    let nlk = {
+        let sock_guard = sock.lock();
+        let netlink_sock = sock_guard
             .deref()
             .as_any()
             .downcast_ref::<NetlinkSock>()
             .ok_or(SystemError::EINVAL)?
-            .clone(),
-    ));
+            .clone();
+        Arc::new(Mutex::new(netlink_sock))
+    };
+
     let nladdr = addr;
+    let mut nlk_guard = nlk.lock();
+    nlk_guard.portid = addr.nl_pid;
+
+    log::info!("netlink_bind: nlk.portid: {}", nlk_guard.portid);
     let mut groups: u32;
     log::info!("netlink_bind: nl_family: {:?}", nladdr.nl_family);
     if nladdr.nl_family != AddressFamily::Netlink {
@@ -299,80 +254,49 @@ fn netlink_bind(
     }
     groups = nladdr.nl_groups;
     log::info!("netlink_bind: groups: {}", groups);
-    let mut nlk = nlk.lock();
-    // Only superuser is allowed to listen multicasts
+    // todo: 只有 root 用户才能绑定多播组
     if groups != 0 {
         let group_count = addr.nl_groups.count_ones(); // 计算多播组数量
-        nlk.ngroups = group_count;
-        // if !netlink_allowed(sock, NL_CFG_F_NONROOT_RECV) {
-        //     return Err(-EPERM);
-        // }
-        let _ = netlink_realloc_groups(&mut nlk);
+        nlk_guard.ngroups = group_count;
+        netlink_realloc_groups(&mut nlk_guard).expect("netlink_realloc_groups failed");
     }
 
-    // BITS_PER_LONG = __WORDSIZE = 64
-    if nlk.ngroups < 64 {
-        groups &= (1 << nlk.ngroups) - 1;
+    if nlk_guard.ngroups < 32 {
+        groups &= (1 << nlk_guard.ngroups) - 1;
     }
 
-    let bound = nlk.bound;
+    let bound = nlk_guard.bound;
     log::info!("netlink_bind: bound: {}", bound);
     if bound {
-        // Ensure nlk.portid is up-to-date.
-        if nladdr.nl_pid != nlk.portid {
+        if nladdr.nl_pid != nlk_guard.portid {
             return Err(SystemError::EINVAL);
         }
     }
 
-    if groups != 0 {
-        for group in 0..(mem::size_of::<u32>() * 8) as u32 {
-            if group != groups {
-                continue;
-            }
-            // 尝试绑定到第 group + 1 个组播组。如果绑定成功(错误码err为0),则继续绑定下一个组播组。
-            // err = nlk.bind().unwrap()(group + 1);
-            // if err == 0 {
-            //     continue;
-            // }
-            // netlink_undo_bind(group, groups, sk);
-            // return Err(SystemError::EINVAL);
-        }
-    }
-
-    // No need for barriers here as we return to user-space without
-    // using any of the bound attributes.
     if !bound {
         if nladdr.nl_pid != 0 {
             log::info!("netlink_bind: insert");
-            let _ = netlink_insert(sk, nladdr.nl_pid);
+            netlink_insert(nlk.clone(), nladdr.nl_pid).expect("netlink_insert failed");
         } else {
             log::info!("netlink_bind: autobind");
-            netlink_autobind(sock, &mut nlk.portid);
+            netlink_autobind(nlk.clone(), &mut nlk_guard.portid);
         };
-        // if err != 0 {
-        // BITS_PER_TYPE<TYPE> = SIZEOF TYPE * BITS PER BYTES
-        // todo
-        // netlink_undo_bind(mem::size_of::<u32>() * 8, groups, sk);
-        // netlink_unlock_table();
-        //     return Err(SystemError::EINVAL);
-        // }
     }
-    // todo
-    // netlink_update_subscriptions(sk, nlk.subscriptions + hweight32(groups) - hweight32(nlk.groups.unwrap()[0]));
-    log::info!("netlink_bind: nlk.groups: {:?}", nlk.groups);
-    nlk.groups[0] = groups;
-    log::info!("netlink_bind: nlk.groups: {:?}", nlk.groups);
-    netlink_update_listeners(nlk);
+
+    log::info!("netlink_bind: nlk.groups: {:?}", nlk_guard.groups);
+    nlk_guard.groups[0] = groups;
+    log::info!("netlink_bind: nlk.groups: {:?}", nlk_guard.groups);
+    netlink_update_listeners(&mut nlk_guard);
 
     Ok(())
 }
 
-/// 自动为netlink套接字选择一个端口号,并在netlink table 中插入这个端口。如果端口已经被使用,它会尝试使用不同的端口号直到找到一个可用的端口。如果有多个线程同时尝试绑定,则认为是正常情况,并成功返回.
-fn netlink_autobind(sk: Arc<Mutex<Box<dyn NetlinkSocket>>>, portid: &mut u32) {
+/// 自动为netlink套接字选择一个端口号,并在 netlink table 中插入这个端口。如果端口已经被使用,它会尝试使用不同的端口号直到找到一个可用的端口。如果有多个线程同时尝试绑定,则认为是正常情况,并成功返回.
+fn netlink_autobind(nlk: Arc<Mutex<NetlinkSock>>, portid: &mut u32) {
     let mut rover: u32 = 0;
     loop {
         // 假设 netlink_lookup 是一个函数,返回一个 Option<Arc<Mutex<Box<dyn NetlinkSocket>>>> 类型
-        let ret = netlink_lookup(sk.lock().sk_protocol(), *portid);
+        let ret = netlink_lookup(nlk.lock().sk_protocol(), *portid);
 
         // 如果查询成功
         if ret.is_some() {
@@ -392,12 +316,13 @@ fn netlink_autobind(sk: Arc<Mutex<Box<dyn NetlinkSocket>>>, portid: &mut u32) {
             break;
         }
     }
-    let _ = netlink_insert(sk, *portid);
+
+    netlink_insert(nlk, *portid).expect("netlink_insert failed");
 }
 // TODO: net namespace支持
 // https://code.dragonos.org.cn/xref/linux-6.1.9/net/netlink/af_netlink.c#532
 /// 在 netlink_table 中查找 netlink 套接字
-fn netlink_lookup(protocol: usize, portid: u32) -> Option<Arc<Mutex<Box<dyn NetlinkSocket>>>> {
+fn netlink_lookup(protocol: usize, portid: u32) -> Option<Arc<Mutex<NetlinkSock>>> {
     // todo: net 支持
     let nl_table = NL_TABLE.read();
     let index = protocol;
@@ -417,7 +342,7 @@ pub trait NetlinkSocket: Socket + Any {
     fn sk_rcvbuf(&self) -> usize;
     fn enqueue_skb(&mut self, skb: Arc<RwLock<SkBuff>>);
     fn is_kernel(&self) -> bool;
-    fn equals(&self, other: Arc<Mutex<Box<dyn NetlinkSocket>>>) -> bool;
+    fn equals(&self, other: Arc<Mutex<NetlinkSock>>) -> bool;
     fn portid(&self) -> u32;
     fn ngroups(&self) -> u64;
     fn groups(&self) -> Vec<u64>;
@@ -444,7 +369,6 @@ impl NetlinkSockMetadata {
 #[cast_to([sync] Socket)]
 #[cast_to([sync] NetlinkSocket)]
 pub struct NetlinkSock {
-    // sk: Option<Weak<dyn NetlinkSocket>>,
     portid: u32,
     node: Arc<HListHead>,
     dst_portid: u32,
@@ -453,7 +377,7 @@ pub struct NetlinkSock {
     subscriptions: u32,
     ngroups: u32,
     groups: Vec<u32>,
-    pub protocol: usize,
+    protocol: usize,
     bound: bool,
     state: NetlinkState,
     max_recvmsg_len: usize,
@@ -577,7 +501,7 @@ impl NetlinkSocket for NetlinkSock {
         return self.state;
     }
     fn sk_protocol(&self) -> usize {
-        return self.protocol;
+        return self.protocol as usize;
     }
     fn sk_rmem_alloc(&self) -> usize {
         0
@@ -591,7 +515,7 @@ impl NetlinkSocket for NetlinkSock {
     fn is_kernel(&self) -> bool {
         self.flags & NetlinkFlags::NETLINK_F_KERNEL_SOCKET.bits() != 0
     }
-    fn equals(&self, other: Arc<Mutex<Box<dyn NetlinkSocket>>>) -> bool {
+    fn equals(&self, other: Arc<Mutex<NetlinkSock>>) -> bool {
         let binding = other.lock();
         let nlk = binding
             .deref()
@@ -636,12 +560,11 @@ impl NetlinkSock {
     pub const DEFAULT_RX_BUF_SIZE: usize = 512 * 1024;
     /// 默认的发送缓冲区的大小 transmiss
     pub const DEFAULT_TX_BUF_SIZE: usize = 512 * 1024;
-    pub fn new() -> NetlinkSock {
+    pub fn new(_protocol: Option<usize>) -> NetlinkSock {
         let vec_of_vec_u8: Vec<Vec<u8>> = Vec::new();
         let mutex_protected = Mutex::new(vec_of_vec_u8);
         let data: Arc<Mutex<Vec<Vec<u8>>>> = Arc::new(mutex_protected);
         NetlinkSock {
-            // sk: None,
             portid: 0,
             node: Arc::new(HListHead { first: None }),
             dst_portid: 0,
@@ -652,7 +575,7 @@ impl NetlinkSock {
             groups: vec![0; 32],
             bound: false,
             state: NetlinkState::NetlinkUnconnected,
-            protocol: 1,
+            protocol: _protocol.unwrap_or(0),
             max_recvmsg_len: 0,
             dump_done_errno: 0,
             cb_running: false,
@@ -763,6 +686,10 @@ impl NetlinkSock {
         log::debug!("netlink_recv: copied: {}, endpoint: {:?}", copied, endpoint);
         Ok((copied, endpoint))
     }
+
+    pub fn set_protocol(&mut self, protocol: usize) {
+        self.protocol = protocol;
+    }
 }
 
 #[derive(Clone)]
@@ -784,6 +711,8 @@ fn initialize_netlink_table() -> RwLock<Vec<NetlinkTable>> {
     for _ in 0..MAX_LINKS {
         tables.push(NetlinkTable::new());
     }
+    // uevent 协议注册
+    tables[NETLINK_KOBJECT_UEVENT].set_registered(1);
     log::info!("initialize_netlink_table,len:{}", tables.len());
     RwLock::new(tables)
 }
@@ -833,7 +762,7 @@ pub fn netlink_has_listeners(sk: &NetlinkSock, group: u32) -> i32 {
     res
 }
 struct NetlinkBroadcastData<'a> {
-    exclude_sk: &'a Arc<dyn NetlinkSocket>,
+    exclude_sk: &'a Arc<NetlinkSock>,
     // net: &'a Net,
     portid: u32,
     group: u64,
@@ -858,7 +787,7 @@ impl<'a> NetlinkBroadcastData<'a> {
 /// ## 备注:
 /// 传入的 netlink 套接字跟组播消息属于同一种 netlink 协议类型,并且这个套接字开启了组播阅订,除了这些,其他信息(比如阅订了具体哪些组播)都是不确定的
 fn do_one_broadcast(
-    sk: Arc<Mutex<Box<dyn NetlinkSocket>>>,
+    sk: Arc<Mutex<NetlinkSock>>,
     info: &mut Box<NetlinkBroadcastData>,
 ) -> Result<(), SystemError> {
     log::info!("do_one_broadcast");
@@ -880,18 +809,7 @@ fn do_one_broadcast(
     {
         return Err(SystemError::EINVAL);
     }
-    // TODO: 需要net namespace支持
-    // if !net_eq(sock_net(sk), info.net) {
-    //     if !(nlk.flags & NetlinkFlags::LISTEN_ALL_NSID.bits()) {
-    //         return;
-    //     }
-    //     if !peernet_has_id(sock_net(sk), info.net) {
-    //         return;
-    //     }
-    //     if !file_ns_capable(sk.sk_socket.file, info.net.user_ns, CAP_NET_BROADCAST) {
-    //         return;
-    //     }
-    // }
+    // TODO: net namespace
 
     // 如果 netlink 组播消息的管理块携带了 failure 标志, 则对该 netlink 套接字设置缓冲区溢出状态
     if info.failure != 0 {
@@ -899,7 +817,7 @@ fn do_one_broadcast(
         return Err(SystemError::EINVAL);
     }
     // 设置 skb2,其内容来自 skb
-    if info.skb_2.read().is_empty() {
+    if info.skb_2.read().inner.is_empty() {
         if skb_shared(&info.skb) {
             info.copy_skb_to_skb_2();
         } else {
@@ -908,7 +826,7 @@ fn do_one_broadcast(
         }
     }
     // 到这里如果 skb2 还是 NULL,意味着上一步中 clone 失败
-    if info.skb_2.read().is_empty() {
+    if info.skb_2.read().inner.is_empty() {
         netlink_overrun(&sk);
         info.failure = 1;
         if sk.lock().flags().is_some() & !NetlinkFlags::BROADCAST_SEND_ERROR.bits().is_zero() {
@@ -953,18 +871,15 @@ fn do_one_broadcast(
 ///  [2]. kernel     --组播--> 用户进程
 ///
 pub fn netlink_broadcast(
-    ssk: &Arc<dyn NetlinkSocket>,
+    ssk: &Arc<NetlinkSock>,
     skb: Arc<RwLock<SkBuff>>,
     portid: u32,
     group: u64,
     allocation: u32,
 ) -> Result<(), SystemError> {
     log::info!("netlink_broadcast");
-    // TODO: 需要net namespace支持
-    // let net = sock_net(ssk);
     let mut info = Box::new(NetlinkBroadcastData {
         exclude_sk: ssk,
-        // net,
         portid,
         group,
         failure: 0,
@@ -973,7 +888,7 @@ pub fn netlink_broadcast(
         delivered: 0,
         allocation,
         skb,
-        skb_2: Arc::new(RwLock::new(SkBuff::new())),
+        skb_2: Arc::new(RwLock::new(SkBuff::new(None))),
     });
 
     // While we sleep in clone, do not allow to change socket list
@@ -1000,7 +915,7 @@ pub fn netlink_broadcast(
 }
 
 /// 对网络套接字(sk)和网络数据包(skb)进行过滤
-fn sk_filter(sk: &Arc<Mutex<Box<dyn NetlinkSocket>>>, skb: &Arc<RwLock<SkBuff>>) -> bool {
+fn sk_filter(sk: &Arc<Mutex<NetlinkSock>>, skb: &Arc<RwLock<SkBuff>>) -> bool {
     // TODO: Implementation of the function
     false
 }
@@ -1021,10 +936,7 @@ fn sk_filter(sk: &Arc<Mutex<Box<dyn NetlinkSocket>>>, skb: &Arc<RwLock<SkBuff>>)
 /// ## 备注:
 /// - 到这里,已经确定了传入的 netlink 套接字跟组播消息匹配正确;
 /// - netlink 组播消息不支持阻塞
-fn netlink_broadcast_deliver(
-    sk: Arc<Mutex<Box<dyn NetlinkSocket>>>,
-    skb: &Arc<RwLock<SkBuff>>,
-) -> i32 {
+fn netlink_broadcast_deliver(sk: Arc<Mutex<NetlinkSock>>, skb: &Arc<RwLock<SkBuff>>) -> i32 {
     log::info!("netlink_broadcast_deliver");
     let nlk: Arc<RwLock<NetlinkSock>> = Arc::clone(&sk)
         .arc_any()
@@ -1048,27 +960,15 @@ fn netlink_broadcast_deliver(
     }
     -1
 }
-// https://code.dragonos.org.cn/xref/linux-6.1.9/net/netlink/af_netlink.c?fi=netlink_has_listeners#387
 /// 设置一个网络缓冲区skb的所有者为指定的源套接字sk
-fn netlink_skb_set_owner_r(skb: &Arc<RwLock<SkBuff>>, sk: Arc<Mutex<Box<dyn NetlinkSocket>>>) {
-    // WARN_ON(skb->sk != NULL);
+fn netlink_skb_set_owner_r(skb: &Arc<RwLock<SkBuff>>, sk: Arc<Mutex<NetlinkSock>>) {
     let mut skb_write = skb.write();
     skb_write.sk = sk;
-    // skb->destructor = netlink_skb_destructor;
-    // atomic_add(skb->truesize, &sk->sk_rmem_alloc);
-    // sk_mem_charge(sk, skb->truesize);
-}
-pub struct NetlinkSocketWrapper {
-    sk: Arc<dyn NetlinkSocket>,
-}
-impl NetlinkSocketWrapper {
-    pub fn new(sk: Arc<dyn NetlinkSocket>) -> NetlinkSocketWrapper {
-        NetlinkSocketWrapper { sk }
-    }
 }
+
 // https://code.dragonos.org.cn/xref/linux-6.1.9/net/netlink/af_netlink.c?fi=netlink_has_listeners#1268
 /// 将一个网络缓冲区 skb 中的数据发送到指定的 目标进程套接字 sk
-fn netlink_sendskb(sk: Arc<Mutex<Box<dyn NetlinkSocket>>>, skb: &Arc<RwLock<SkBuff>>) -> u32 {
+fn netlink_sendskb(sk: Arc<Mutex<NetlinkSock>>, skb: &Arc<RwLock<SkBuff>>) -> u32 {
     let len = skb.read().len;
     {
         // 将 skb 放入该 netlink 套接字接收队列末尾
@@ -1090,14 +990,12 @@ fn netlink_sendskb(sk: Arc<Mutex<Box<dyn NetlinkSocket>>>, skb: &Arc<RwLock<SkBu
 /// - portid: 目的单播地址
 /// - nonblock    - 1:非阻塞调用,2:阻塞调用
 fn netlink_unicast(
-    ssk: Arc<Mutex<Box<dyn NetlinkSocket>>>,
+    ssk: Arc<Mutex<NetlinkSock>>,
     skb: Arc<RwLock<SkBuff>>,
     portid: u32,
     nonblock: bool,
 ) -> Result<u32, SystemError> {
     let mut err: i32;
-    // todo:重新调整skb的大小
-    // skb = netlink_trim(skb, gfp_any());
     // 计算发送超时时间(如果是非阻塞调用,则返回 0)
     let timeo: i64 = ssk.lock().sock_sndtimeo(nonblock);
     loop {
@@ -1139,8 +1037,8 @@ fn netlink_unicast(
 /// ## 备注:
 /// - skb的所有者在本函数中发生了变化
 fn netlink_unicast_kernel(
-    sk: Arc<Mutex<Box<dyn NetlinkSocket>>>,
-    ssk: Arc<Mutex<Box<dyn NetlinkSocket>>>,
+    sk: Arc<Mutex<NetlinkSock>>,
+    ssk: Arc<Mutex<NetlinkSock>>,
     skb: Arc<RwLock<SkBuff>>,
 ) -> u32 {
     let mut ret: u32;
@@ -1177,17 +1075,17 @@ fn netlink_unicast_kernel(
 /// - 0:表示继续执行,skb可以被附加到套接字上。
 /// - 1:表示需要重新查找,可能因为等待超时或接收缓冲区不足。
 fn netlink_attachskb(
-    sk: Arc<Mutex<Box<dyn NetlinkSocket>>>,
+    sk: Arc<Mutex<NetlinkSock>>,
     skb: Arc<RwLock<SkBuff>>,
     mut timeo: i64,
-    ssk: Arc<Mutex<Box<dyn NetlinkSocket>>>,
+    ssk: Arc<Mutex<NetlinkSock>>,
 ) -> Result<u64, SystemError> {
     let nlk: Arc<RwLock<NetlinkSock>> = Arc::clone(&sk)
         .arc_any()
         .downcast()
         .map_err(|_| SystemError::EINVAL)?;
     let nlk_guard = nlk.read();
-    let ssk_option: Option<Arc<Mutex<Box<dyn NetlinkSocket>>>> = Some(ssk.clone());
+    let ssk_option = Some(ssk.clone());
 
     /*
         如果目的netlink套接字上已经接收尚未处理的数据大小超过了接收缓冲区大小,
@@ -1242,11 +1140,10 @@ fn netlink_attachskb(
 }
 
 fn netlink_getsockbyportid(
-    ssk: Arc<Mutex<Box<dyn NetlinkSocket>>>,
+    ssk: Arc<Mutex<NetlinkSock>>,
     portid: u32,
-) -> Result<Arc<Mutex<Box<dyn NetlinkSocket>>>, SystemError> {
-    let sock: Arc<Mutex<Box<dyn NetlinkSocket>>> =
-        netlink_lookup(ssk.lock().sk_protocol(), portid).unwrap();
+) -> Result<Arc<Mutex<NetlinkSock>>, SystemError> {
+    let sock = netlink_lookup(ssk.lock().sk_protocol(), portid).unwrap();
     if Some(sock.clone()).is_none() {
         return Err(SystemError::ECONNREFUSED);
     }
@@ -1316,6 +1213,7 @@ fn netlink_setsockopt(
             }
         }
         NETLINK_PKTINFO => {
+            todo!();
             //     if val != 0 {
             //     nlk.flags |= NetlinkFlags::RECV_PKTINFO.bits();
             //     } else {
@@ -1329,7 +1227,7 @@ fn netlink_setsockopt(
     Ok(())
 }
 
-fn netlink_update_listeners(nlk: MutexGuard<NetlinkSock>) {
+fn netlink_update_listeners(nlk: &mut MutexGuard<NetlinkSock>) {
     log::info!("netlink_update_listeners");
     let mut nl_table = NL_TABLE.write();
     let netlink_table = &mut nl_table[nlk.protocol];
@@ -1341,8 +1239,6 @@ fn netlink_update_listeners(nlk: MutexGuard<NetlinkSock>) {
     for group in &nlk.groups {
         let mask = 1 << (group % 64);
         let idx = group / 64;
-
-        listeners.masks[idx as usize] |= mask;
         log::info!(
             "group:{},mask:{},idx:{},masks:{:?}",
             group,
@@ -1350,6 +1246,7 @@ fn netlink_update_listeners(nlk: MutexGuard<NetlinkSock>) {
             idx,
             listeners.masks
         );
+        listeners.masks[idx as usize] |= mask;
     }
 }
 
@@ -1357,6 +1254,7 @@ fn netlink_update_listeners(nlk: MutexGuard<NetlinkSock>) {
 fn netlink_realloc_groups(nlk: &mut MutexGuard<NetlinkSock>) -> Result<(), SystemError> {
     let nl_table = NL_TABLE.write();
     let groups = nl_table[nlk.protocol].groups;
+    log::info!("nlk.protocol:{},groups:{:?}", nlk.protocol, groups);
     if nl_table[nlk.protocol].registered == 0 {
         // 没有注册任何组
         log::warn!("netlink_realloc_groups: not registered");
@@ -1368,11 +1266,12 @@ fn netlink_realloc_groups(nlk: &mut MutexGuard<NetlinkSock>) -> Result<(), Syste
         return Ok(());
     }
     log::info!("nlk.ngroups:{},groups:{}", nlk.ngroups, groups);
-    let mut new_groups = vec![0u32; groups as usize];
-    log::info!("nlk.groups:{:?}", nlk.groups);
+    let mut new_groups = vec![0u32; 32];
+    log::info!("nlk.groups:{:?},len = {}", nlk.groups, nlk.groups.len());
+    log::info!("new_groups:{:?},len = {}", new_groups, new_groups.len());
     // 当 nlk.ngroups 大于 0 时复制数据
     if nlk.ngroups > 0 {
-        new_groups[..nlk.ngroups as usize].copy_from_slice(&nlk.groups);
+        new_groups.copy_from_slice(&nlk.groups);
     }
     nlk.groups = new_groups;
     nlk.ngroups = groups;

+ 9 - 10
kernel/src/net/socket/netlink/mod.rs

@@ -261,14 +261,13 @@ impl VecExt for Vec<u8> {
     }
 }
 
-// todo: net namespace
+/// 创建一个新的内核netlink套接字
 pub fn netlink_kernel_create(
     unit: usize,
     cfg: Option<NetlinkKernelCfg>,
 ) -> Result<NetlinkSock, SystemError> {
-    // THIS_MODULE
-    let mut nlk: NetlinkSock = NetlinkSock::new();
-    let sk: Arc<Mutex<Box<dyn NetlinkSocket>>> = Arc::new(Mutex::new(Box::new(nlk.clone())));
+    let mut nlk: NetlinkSock = NetlinkSock::new(Some(unit));
+    let sk: Arc<Mutex<NetlinkSock>> = Arc::new(Mutex::new(nlk.clone()));
     let groups: u32;
     if unit >= MAX_LINKS {
         return Err(SystemError::EINVAL);
@@ -314,9 +313,9 @@ pub fn netlink_kernel_create(
 }
 
 fn __netlink_create(nlk: &mut NetlinkSock, unit: usize, kern: usize) -> Result<i32, SystemError> {
-    // 其他的初始化配置参数
+    // 初始化配置参数
     nlk.flags = kern as u32;
-    nlk.protocol = unit;
+    nlk.set_protocol(unit);
     return Ok(0);
 }
 
@@ -330,14 +329,14 @@ pub struct Netlink;
 impl family::Family for Netlink {
     /// 用户空间创建一个新的套接字的入口
     fn socket(stype: Type, _protocol: u32) -> Result<Arc<Inode>, SystemError> {
-        let socket = create_netlink_socket(_protocol)?;
+        let socket = create_netlink_socket(_protocol as usize)?;
         Ok(Inode::new(socket))
     }
 }
 /// 用户空间创建一个新的Netlink套接字
-fn create_netlink_socket(_protocol: u32) -> Result<Arc<dyn Socket>, SystemError> {
-    match _protocol as usize {
-        NETLINK_KOBJECT_UEVENT => Ok(Arc::new(af_netlink::NetlinkSock::new())),
+fn create_netlink_socket(_protocol: usize) -> Result<Arc<dyn Socket>, SystemError> {
+    match _protocol {
+        NETLINK_KOBJECT_UEVENT => Ok(Arc::new(af_netlink::NetlinkSock::new(Some(_protocol)))),
         _ => Err(SystemError::EPROTONOSUPPORT),
     }
 }

+ 12 - 77
kernel/src/net/socket/netlink/skbuff.rs

@@ -1,97 +1,32 @@
 use super::af_netlink::{NetlinkSock, NetlinkSocket};
 use crate::libs::{mutex::Mutex, rwlock::RwLock};
-use alloc::{boxed::Box, sync::Arc};
-// 曾用方案:在 smoltcp::PacketBuffer 的基础上封装了一层,用于处理 netlink 协议中网络数据包(skb)的相关操作
-// 暂时弃用,目前尝试使用更简单的方式处理 skb
+use alloc::{boxed::Box, sync::Arc, vec::Vec};
+use uefi_raw::protocol;
+const SKB_SIZE: usize = 4096; // 定义 SKB 的大小
 #[derive(Debug, Clone)]
 pub struct SkBuff {
-    pub sk: Arc<Mutex<Box<dyn NetlinkSocket>>>,
+    pub sk: Arc<Mutex<NetlinkSock>>,
     pub len: u32,
-    pub pkt_type: u32,
-    pub mark: u32,
-    pub queue_mapping: u32,
-    pub protocol: u32,
-    pub vlan_present: u32,
-    pub vlan_tci: u32,
-    pub vlan_proto: u32,
-    pub priority: u32,
-    pub ingress_ifindex: u32,
-    pub ifindex: u32,
-    pub tc_index: u32,
-    pub cb: [u32; 5],
-    pub hash: u32,
-    pub tc_classid: u32,
-    pub data: u32,
-    pub data_end: u32,
-    pub napi_id: u32,
-    pub family: u32,
-    pub remote_ip4: u32,
-    pub local_ip4: u32,
-    pub remote_ip6: [u32; 4],
-    pub local_ip6: [u32; 4],
-    pub remote_port: u32,
-    pub local_port: u32,
-    pub data_meta: u32,
-    pub tstamp: u64,
-    pub wire_len: u32,
-    pub gso_segs: u32,
-    pub gso_size: u32,
-    pub tstamp_type: u8,
-    pub _bitfield_align_1: [u8; 0],
-    pub hwtstamp: u64,
+    pub inner: Vec<u8>,
 }
 impl SkBuff {
-    pub fn new() -> Self {
+    pub fn new(protocol: Option<usize>) -> Self {
         SkBuff {
-            sk: Arc::new(Mutex::new(Box::new(NetlinkSock::new()))),
+            sk: Arc::new(Mutex::new(NetlinkSock::new(protocol))),
             len: 0,
-            pkt_type: 0,
-            mark: 0,
-            queue_mapping: 0,
-            protocol: 0,
-            vlan_present: 0,
-            vlan_tci: 0,
-            vlan_proto: 0,
-            priority: 0,
-            ingress_ifindex: 0,
-            ifindex: 0,
-            tc_index: 0,
-            cb: [0; 5],
-            hash: 0,
-            tc_classid: 0,
-            data: 0,
-            data_end: 0,
-            napi_id: 0,
-            family: 0,
-            remote_ip4: 0,
-            local_ip4: 0,
-            remote_ip6: [0; 4],
-            local_ip6: [0; 4],
-            remote_port: 0,
-            local_port: 0,
-            data_meta: 0,
-            tstamp: 0,
-            wire_len: 0,
-            gso_segs: 0,
-            gso_size: 0,
-            tstamp_type: 0,
-            _bitfield_align_1: [0; 0],
-            hwtstamp: 0,
+            inner: vec![0u8; SKB_SIZE],
         }
     }
-    pub fn is_empty(&self) -> bool {
-        self.len == 0
-    }
 }
 
 // 处理网络套接字的过度运行情况
-pub fn netlink_overrun(sk: &Arc<Mutex<Box<dyn NetlinkSocket>>>) {
-    // Implementation of the function
+pub fn netlink_overrun(sk: &Arc<Mutex<NetlinkSock>>) {
+    todo!()
 }
 
 // 用于检查网络数据包(skb)是否被共享
 pub fn skb_shared(skb: &RwLock<SkBuff>) -> bool {
-    // Implementation of the function
+    // todo!()
     false
 }
 
@@ -99,7 +34,7 @@ pub fn skb_shared(skb: &RwLock<SkBuff>) -> bool {
 /// 孤儿化网络数据包意味着数据包不再与任何套接字关联,
 /// 通常是因为发送数据包时指定了 MSG_DONTWAIT 标志,这告诉内核不要等待必要的资源(如内存),而是尽可能快地发送数据包。
 pub fn skb_orphan(skb: &Arc<RwLock<SkBuff>>) {
-    // TODO: Implementation of the function
+    // todo!()
 }
 
 fn skb_recv_datagram() {}

+ 0 - 1
kernel/src/net/syscall_util.rs

@@ -187,7 +187,6 @@ impl SockAddr {
                     return Err(SystemError::EINVAL);
                 }
                 AddressFamily::Netlink => {
-                    // TODO: support netlink socket
                     let addr: SockAddrNl = addr.addr_nl;
                     return Ok(Endpoint::Netlink(NetlinkEndpoint::new(addr)));
                 }

+ 3 - 13
user/apps/test-uevent/README.md

@@ -1,14 +1,4 @@
-# DragonOS Rust-Application Template
+# test_uevent
+这是一个测试 uevent 机制的应用,用于测试uevent的功能。
 
-您可以使用此模板来创建DragonOS应用程序。
-
-## 使用方法
-
-1. 使用DragonOS的tools目录下的`bootstrap.sh`脚本初始化环境
-2. 在终端输入`cargo install cargo-generate`
-3. 在终端输入`cargo generate --git https://github.com/DragonOS-Community/Rust-App-Template`即可创建项目
-如果您的网络较慢,请使用镜像站`cargo generate --git https://git.mirrors.dragonos.org/DragonOS-Community/Rust-App-Template`
-4. 使用`cargo run`来运行项目
-5. 在DragonOS的`user/dadk/config`目录下,使用`dadk new`命令,创建编译配置,安装到DragonOS的`/`目录下。 
-(在dadk的编译命令选项处,请使用Makefile里面的`make install`配置进行编译、安装)
-6. 编译DragonOS即可安装
+执行此测试,将会执行以下操作:

+ 3 - 3
user/apps/test-uevent/src/main.rs

@@ -1,4 +1,4 @@
-use libc::{sockaddr, sockaddr_storage, recvfrom, bind, sendto, socket, AF_NETLINK, SOCK_DGRAM, SOCK_CLOEXEC, getpid, c_void};
+use libc::{sockaddr,  recvfrom, bind, sendto, socket, AF_NETLINK, SOCK_DGRAM, getpid, c_void};
 use nix::libc;
 use std::os::unix::io::RawFd;
 use std::{ mem, io};
@@ -14,7 +14,7 @@ struct Nlmsghdr {
 
 fn create_netlink_socket() -> io::Result<RawFd> {
     let sockfd = unsafe {
-        socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, libc::NETLINK_KOBJECT_UEVENT)
+        socket(AF_NETLINK, SOCK_DGRAM, libc::NETLINK_KOBJECT_UEVENT)
     };
 
     if sockfd < 0 {
@@ -30,7 +30,7 @@ fn bind_netlink_socket(sock: RawFd) -> io::Result<()> {
     let mut addr: libc::sockaddr_nl = unsafe { mem::zeroed() };
     addr.nl_family = AF_NETLINK as u16;
     addr.nl_pid = pid as u32;
-    addr.nl_groups = 0;
+    addr.nl_groups = 1;
 
     let ret = unsafe {
         bind(sock, &addr as *const _ as *const sockaddr, mem::size_of::<libc::sockaddr_nl>() as u32)