Browse Source

feat: Add sys_unshare (#1260)

* feat(namespace): 实现unshare系统调用及相关功能

- 新增unshare.rs模块实现ksys_unshare
- 修改nsproxy.rs添加clone_inner方法
- 公开create_new_namespaces和create_pid_namespace方法
- 在user_namespace.rs添加current_user_ns方法
- 添加sys_unshare系统调用实现

Signed-off-by: longjin <longjin@DragonOS.org>

* add util-linux package

* 调试unshare

Signed-off-by: longjin <longjin@DragonOS.org>

* fix: 修复futex处理中的用户空间内存访问问题

在`futex.rs`中增加了`safe_read`、`safe_read_u32`和`safe_write_u32`方法,确保在访问用户空间内存时进行安全检查,避免无效地址导致的错误。同时,优化了`handle_futex_death`方法,使用新的安全读取和写入方法,确保在进程死亡时正确处理futex。

Signed-off-by: longjin <longjin@DragonOS.org>

* refactor(futex): 重构RobustListHead结构并移除调试日志

- 将RobustListHead拆分为PosixRobustListHead和RobustListHead
- 为RobustListHead实现Deref和DerefMut trait
- 移除多余的调试日志输出
- 优化robust list处理逻辑

Signed-off-by: longjin <longjin@DragonOS.org>

---------

Signed-off-by: longjin <longjin@DragonOS.org>
LoGin 5 days ago
parent
commit
ba4af7f718

+ 49 - 15
kernel/src/libs/futex/futex.rs

@@ -2,7 +2,10 @@ use alloc::{
     collections::LinkedList,
     collections::LinkedList,
     sync::{Arc, Weak},
     sync::{Arc, Weak},
 };
 };
-use core::hash::{Hash, Hasher};
+use core::{
+    hash::{Hash, Hasher},
+    ops::{Deref, DerefMut},
+};
 use core::{
 use core::{
     intrinsics::{likely, unlikely},
     intrinsics::{likely, unlikely},
     mem,
     mem,
@@ -646,17 +649,39 @@ impl Futex {
 const ROBUST_LIST_LIMIT: isize = 2048;
 const ROBUST_LIST_LIMIT: isize = 2048;
 
 
 #[derive(Debug, Copy, Clone)]
 #[derive(Debug, Copy, Clone)]
-pub struct RobustList {
+#[repr(C)]
+struct PosixRobustList {
     next: VirtAddr,
     next: VirtAddr,
 }
 }
 
 
 #[derive(Debug, Copy, Clone)]
 #[derive(Debug, Copy, Clone)]
-pub struct RobustListHead {
-    list: RobustList,
+#[repr(C)]
+pub struct PosixRobustListHead {
+    list: PosixRobustList,
     futex_offset: isize,
     futex_offset: isize,
     list_op_pending: VirtAddr,
     list_op_pending: VirtAddr,
 }
 }
 
 
+#[derive(Debug, Copy, Clone)]
+pub struct RobustListHead {
+    pub posix: PosixRobustListHead,
+    pub uaddr: VirtAddr,
+}
+
+impl Deref for RobustListHead {
+    type Target = PosixRobustListHead;
+
+    fn deref(&self) -> &Self::Target {
+        &self.posix
+    }
+}
+
+impl DerefMut for RobustListHead {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.posix
+    }
+}
+
 impl RobustListHead {
 impl RobustListHead {
     /// # 获得futex的用户空间地址
     /// # 获得futex的用户空间地址
     pub fn futex_uaddr(&self, entry: VirtAddr) -> VirtAddr {
     pub fn futex_uaddr(&self, entry: VirtAddr) -> VirtAddr {
@@ -677,18 +702,21 @@ impl RobustListHead {
     /// - head_uaddr:robust list head用户空间地址
     /// - head_uaddr:robust list head用户空间地址
     /// - len:robust list head的长度    
     /// - len:robust list head的长度    
     pub fn set_robust_list(head_uaddr: VirtAddr, len: usize) -> Result<usize, SystemError> {
     pub fn set_robust_list(head_uaddr: VirtAddr, len: usize) -> Result<usize, SystemError> {
-        let robust_list_head_len = mem::size_of::<RobustListHead>();
+        let robust_list_head_len = mem::size_of::<PosixRobustListHead>();
         if unlikely(len != robust_list_head_len) {
         if unlikely(len != robust_list_head_len) {
             return Err(SystemError::EINVAL);
             return Err(SystemError::EINVAL);
         }
         }
 
 
         let user_buffer_reader = UserBufferReader::new(
         let user_buffer_reader = UserBufferReader::new(
-            head_uaddr.as_ptr::<RobustListHead>(),
-            mem::size_of::<RobustListHead>(),
+            head_uaddr.as_ptr::<PosixRobustListHead>(),
+            mem::size_of::<PosixRobustListHead>(),
             true,
             true,
         )?;
         )?;
-        let robust_list_head = *user_buffer_reader.read_one_from_user::<RobustListHead>(0)?;
-
+        let robust_list_head = *user_buffer_reader.read_one_from_user::<PosixRobustListHead>(0)?;
+        let robust_list_head = RobustListHead {
+            posix: robust_list_head,
+            uaddr: head_uaddr,
+        };
         // 向内核注册robust list
         // 向内核注册robust list
         ProcessManager::current_pcb().set_robust_list(Some(robust_list_head));
         ProcessManager::current_pcb().set_robust_list(Some(robust_list_head));
 
 
@@ -726,11 +754,11 @@ impl RobustListHead {
             core::mem::size_of::<usize>(),
             core::mem::size_of::<usize>(),
             true,
             true,
         )?;
         )?;
-        user_writer.copy_one_to_user(&mem::size_of::<RobustListHead>(), 0)?;
+        user_writer.copy_one_to_user(&mem::size_of::<PosixRobustListHead>(), 0)?;
         // 将head拷贝到用户空间head
         // 将head拷贝到用户空间head
         let mut user_writer = UserBufferWriter::new(
         let mut user_writer = UserBufferWriter::new(
-            head_uaddr.as_ptr::<RobustListHead>(),
-            mem::size_of::<RobustListHead>(),
+            head_uaddr.as_ptr::<PosixRobustListHead>(),
+            mem::size_of::<PosixRobustListHead>(),
             true,
             true,
         )?;
         )?;
         user_writer.copy_one_to_user(&robust_list_head, 0)?;
         user_writer.copy_one_to_user(&robust_list_head, 0)?;
@@ -750,6 +778,7 @@ impl RobustListHead {
                 return;
                 return;
             }
             }
         };
         };
+
         // 遍历当前进程/线程的robust list
         // 遍历当前进程/线程的robust list
         for futex_uaddr in head.futexes() {
         for futex_uaddr in head.futexes() {
             let ret = Self::handle_futex_death(futex_uaddr, pcb.raw_pid().into() as u32);
             let ret = Self::handle_futex_death(futex_uaddr, pcb.raw_pid().into() as u32);
@@ -879,7 +908,7 @@ impl Iterator for FutexIterator<'_> {
             return None;
             return None;
         }
         }
 
 
-        while self.entry.data() != &self.robust_list_head.list as *const RobustList as usize {
+        while self.entry.data() != self.robust_list_head.uaddr.data() {
             if self.count == ROBUST_LIST_LIMIT {
             if self.count == ROBUST_LIST_LIMIT {
                 break;
                 break;
             }
             }
@@ -895,8 +924,13 @@ impl Iterator for FutexIterator<'_> {
             };
             };
 
 
             // 安全地读取下一个entry
             // 安全地读取下一个entry
-            let next_entry = RobustListHead::safe_read::<RobustList>(self.entry)
-                .and_then(|reader| reader.read_one_from_user::<RobustList>(0).ok().cloned())?;
+            let next_entry =
+                RobustListHead::safe_read::<PosixRobustList>(self.entry).and_then(|reader| {
+                    reader
+                        .read_one_from_user::<PosixRobustList>(0)
+                        .ok()
+                        .cloned()
+                })?;
 
 
             self.entry = next_entry.next;
             self.entry = next_entry.next;
 
 

+ 7 - 4
kernel/src/libs/futex/syscall.rs

@@ -1,15 +1,13 @@
 use system_error::SystemError;
 use system_error::SystemError;
 
 
 use crate::{
 use crate::{
+    libs::futex::futex::RobustListHead,
     mm::{verify_area, VirtAddr},
     mm::{verify_area, VirtAddr},
     syscall::Syscall,
     syscall::Syscall,
     time::PosixTimeSpec,
     time::PosixTimeSpec,
 };
 };
 
 
-use super::{
-    constant::*,
-    futex::{Futex, RobustListHead},
-};
+use super::{constant::*, futex::Futex};
 
 
 impl Syscall {
 impl Syscall {
     pub fn do_futex(
     pub fn do_futex(
@@ -117,6 +115,11 @@ impl Syscall {
         verify_area(head_uaddr, core::mem::size_of::<u32>())?;
         verify_area(head_uaddr, core::mem::size_of::<u32>())?;
 
 
         let ret = RobustListHead::set_robust_list(head_uaddr, len);
         let ret = RobustListHead::set_robust_list(head_uaddr, len);
+        // log::debug!(
+        //     "set_robust_list: pid: {} head_uaddr={:?}",
+        //     crate::process::ProcessManager::current_pid(),
+        //     head_uaddr
+        // );
         return ret;
         return ret;
     }
     }
 
 

+ 0 - 1
kernel/src/process/fork.rs

@@ -339,7 +339,6 @@ impl ProcessManager {
         clone_args: KernelCloneArgs,
         clone_args: KernelCloneArgs,
         current_trapframe: &TrapFrame,
         current_trapframe: &TrapFrame,
     ) -> Result<(), SystemError> {
     ) -> Result<(), SystemError> {
-        // log::debug!("fork: clone_flags: {:?}", clone_args.flags);
         let clone_flags = clone_args.flags;
         let clone_flags = clone_args.flags;
         // 不允许与不同namespace的进程共享根目录
         // 不允许与不同namespace的进程共享根目录
 
 

+ 1 - 4
kernel/src/process/mod.rs

@@ -452,9 +452,6 @@ impl ProcessManager {
 
 
             // 进行进程退出后的工作
             // 进行进程退出后的工作
             let thread = pcb.thread.write_irqsave();
             let thread = pcb.thread.write_irqsave();
-            if let Some(addr) = thread.set_child_tid {
-                unsafe { clear_user(addr, core::mem::size_of::<i32>()).expect("clear tid failed") };
-            }
 
 
             if let Some(addr) = thread.clear_child_tid {
             if let Some(addr) = thread.clear_child_tid {
                 if Arc::strong_count(&pcb.basic().user_vm().expect("User VM Not found")) > 1 {
                 if Arc::strong_count(&pcb.basic().user_vm().expect("User VM Not found")) > 1 {
@@ -467,9 +464,9 @@ impl ProcessManager {
                 }
                 }
                 unsafe { clear_user(addr, core::mem::size_of::<i32>()).expect("clear tid failed") };
                 unsafe { clear_user(addr, core::mem::size_of::<i32>()).expect("clear tid failed") };
             }
             }
+            compiler_fence(Ordering::SeqCst);
 
 
             RobustListHead::exit_robust_list(pcb.clone());
             RobustListHead::exit_robust_list(pcb.clone());
-
             // 如果是vfork出来的进程,则需要处理completion
             // 如果是vfork出来的进程,则需要处理completion
             if thread.vfork_done.is_some() {
             if thread.vfork_done.is_some() {
                 thread.vfork_done.as_ref().unwrap().complete_all();
                 thread.vfork_done.as_ref().unwrap().complete_all();

+ 1 - 0
kernel/src/process/namespace/mod.rs

@@ -1,6 +1,7 @@
 pub mod mnt;
 pub mod mnt;
 pub mod nsproxy;
 pub mod nsproxy;
 pub mod pid_namespace;
 pub mod pid_namespace;
+pub mod unshare;
 pub mod user_namespace;
 pub mod user_namespace;
 
 
 use nsproxy::NsCommon;
 use nsproxy::NsCommon;

+ 11 - 3
kernel/src/process/namespace/nsproxy.rs

@@ -23,8 +23,9 @@ pub struct NsProxy {
     pub pid_ns_for_children: Arc<PidNamespace>,
     pub pid_ns_for_children: Arc<PidNamespace>,
     /// mount namespace(挂载命名空间)
     /// mount namespace(挂载命名空间)
     pub mnt_ns: Arc<MntNamespace>,
     pub mnt_ns: Arc<MntNamespace>,
+    // 注意,user_ns 存储在cred,不存储在nsproxy
+
     // 其他namespace(为未来扩展预留)
     // 其他namespace(为未来扩展预留)
-    // pub user_ns: Option<Arc<UserNamespace>>,
     // pub net_ns: Option<Arc<NetNamespace>>,
     // pub net_ns: Option<Arc<NetNamespace>>,
     // pub ipc_ns: Option<Arc<IpcNamespace>>,
     // pub ipc_ns: Option<Arc<IpcNamespace>>,
     // pub uts_ns: Option<Arc<UtsNamespace>>,
     // pub uts_ns: Option<Arc<UtsNamespace>>,
@@ -58,6 +59,13 @@ impl NsProxy {
     pub fn mnt_namespace(&self) -> &Arc<MntNamespace> {
     pub fn mnt_namespace(&self) -> &Arc<MntNamespace> {
         &self.mnt_ns
         &self.mnt_ns
     }
     }
+
+    pub fn clone_inner(&self) -> Self {
+        Self {
+            pid_ns_for_children: self.pid_ns_for_children.clone(),
+            mnt_ns: self.mnt_ns.clone(),
+        }
+    }
 }
 }
 
 
 impl ProcessManager {
 impl ProcessManager {
@@ -123,7 +131,7 @@ impl ProcessManager {
 /// 返回新创建的nsproxy。调用者需要负责正确的加锁并将其附加到进程上。
 /// 返回新创建的nsproxy。调用者需要负责正确的加锁并将其附加到进程上。
 ///
 ///
 /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/nsproxy.c?r=&mo=3770&fi=151#67
 /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/nsproxy.c?r=&mo=3770&fi=151#67
-fn create_new_namespaces(
+pub(super) fn create_new_namespaces(
     clone_flags: &CloneFlags,
     clone_flags: &CloneFlags,
     pcb: &Arc<ProcessControlBlock>,
     pcb: &Arc<ProcessControlBlock>,
     user_ns: Arc<UserNamespace>,
     user_ns: Arc<UserNamespace>,
@@ -133,7 +141,7 @@ fn create_new_namespaces(
         .pid_ns_for_children
         .pid_ns_for_children
         .copy_pid_ns(clone_flags, user_ns.clone())?;
         .copy_pid_ns(clone_flags, user_ns.clone())?;
 
 
-    let mnt_ns = nsproxy.mnt_ns.copy_mnt_ns(clone_flags, user_ns)?;
+    let mnt_ns = nsproxy.mnt_ns.copy_mnt_ns(clone_flags, user_ns.clone())?;
     let result = NsProxy {
     let result = NsProxy {
         pid_ns_for_children,
         pid_ns_for_children,
         mnt_ns,
         mnt_ns,

+ 4 - 1
kernel/src/process/namespace/pid_namespace.rs

@@ -124,7 +124,10 @@ impl PidNamespace {
     }
     }
 
 
     /// https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/pid_namespace.c#72
     /// https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/pid_namespace.c#72
-    fn create_pid_namespace(&self, user_ns: Arc<UserNamespace>) -> Result<Arc<Self>, SystemError> {
+    pub(super) fn create_pid_namespace(
+        &self,
+        user_ns: Arc<UserNamespace>,
+    ) -> Result<Arc<Self>, SystemError> {
         let level = self.level() + 1;
         let level = self.level() + 1;
         if !self.user_ns.is_ancestor_of(&user_ns) {
         if !self.user_ns.is_ancestor_of(&user_ns) {
             return Err(SystemError::EINVAL);
             return Err(SystemError::EINVAL);

+ 110 - 0
kernel/src/process/namespace/unshare.rs

@@ -0,0 +1,110 @@
+use alloc::sync::Arc;
+
+use system_error::SystemError;
+
+use crate::process::{
+    fork::CloneFlags,
+    namespace::nsproxy::{switch_task_namespaces, NsProxy},
+    ProcessManager,
+};
+
+/// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/fork.c#3385
+pub fn ksys_unshare(flags: CloneFlags) -> Result<(), SystemError> {
+    // 检查 unshare 标志位
+    check_unshare_flags(flags)?;
+
+    let new_nsproxy = unshare_nsproxy_namespaces(flags)?;
+
+    if let Some(new_nsproxy) = new_nsproxy {
+        // 更新当前进程的 Namespace 代理
+        let current_pcb = ProcessManager::current_pcb();
+        switch_task_namespaces(&current_pcb, new_nsproxy)?;
+    }
+    // TODO: 处理其他命名空间的 unshare 操作
+    // CLONE_NEWNS, CLONE_FS, CLONE_FILES, CLONE_SIGHAND, CLONE_VM, CLONE_THREAD, CLONE_SYSVSEM,
+    // CLONE_NEWUTS, CLONE_NEWIPC, CLONE_NEWUSER, CLONE_NEWNET, CLONE_NEWCGROUP, CLONE_NEWTIME
+
+    Ok(())
+}
+
+#[inline(never)]
+fn unshare_nsproxy_namespaces(
+    unshare_flags: CloneFlags,
+) -> Result<Option<Arc<NsProxy>>, SystemError> {
+    const ALL_VALID_FLAGS: CloneFlags = CloneFlags::from_bits_truncate(
+        CloneFlags::CLONE_NEWNS.bits()
+            | CloneFlags::CLONE_NEWUTS.bits()
+            | CloneFlags::CLONE_NEWIPC.bits()
+            | CloneFlags::CLONE_NEWNET.bits()
+            | CloneFlags::CLONE_NEWPID.bits()
+            | CloneFlags::CLONE_NEWCGROUP.bits()
+            | CloneFlags::CLONE_NEWTIME.bits(),
+    );
+    if !unshare_flags.intersects(ALL_VALID_FLAGS) {
+        return Ok(None);
+    }
+
+    // 获取当前进程的 PCB
+    let current_pcb = ProcessManager::current_pcb();
+    let user_ns = ProcessManager::current_user_ns();
+
+    let nsproxy = super::nsproxy::create_new_namespaces(&unshare_flags, &current_pcb, user_ns)?;
+    return Ok(Some(nsproxy));
+}
+
+#[inline(never)]
+fn check_unshare_flags(flags: CloneFlags) -> Result<(), SystemError> {
+    // 检查无效的标志位
+    const ALL_VALID_FLAGS: CloneFlags = CloneFlags::from_bits_truncate(
+        CloneFlags::CLONE_NEWNS.bits()
+            | CloneFlags::CLONE_NEWCGROUP.bits()
+            | CloneFlags::CLONE_NEWUTS.bits()
+            | CloneFlags::CLONE_NEWIPC.bits()
+            | CloneFlags::CLONE_NEWUSER.bits()
+            | CloneFlags::CLONE_NEWPID.bits()
+            | CloneFlags::CLONE_NEWNET.bits()
+            | CloneFlags::CLONE_NEWTIME.bits()
+            | CloneFlags::CLONE_FS.bits()
+            | CloneFlags::CLONE_FILES.bits()
+            | CloneFlags::CLONE_SIGHAND.bits()
+            | CloneFlags::CLONE_VM.bits()
+            | CloneFlags::CLONE_THREAD.bits()
+            | CloneFlags::CLONE_SYSVSEM.bits(),
+    );
+
+    if flags.intersects(!ALL_VALID_FLAGS) {
+        return Err(SystemError::EINVAL);
+    }
+
+    let current_pcb = ProcessManager::current_pcb();
+
+    // 如果请求 unshare CLONE_THREAD, CLONE_SIGHAND 或 CLONE_VM,
+    // 必须确保线程组为空(即只有一个线程)
+    if flags.intersects(CloneFlags::CLONE_THREAD | CloneFlags::CLONE_SIGHAND | CloneFlags::CLONE_VM)
+        && !current_pcb.threads_read_irqsave().thread_group_empty()
+    {
+        return Err(SystemError::EINVAL);
+    }
+
+    // 如果请求 unshare CLONE_SIGHAND 或 CLONE_VM,
+    // 必须确保信号处理结构的引用计数为1
+    if flags.intersects(CloneFlags::CLONE_SIGHAND | CloneFlags::CLONE_VM) {
+        let sighand_count = current_pcb
+            .sig_struct_irqsave()
+            .cnt
+            .load(core::sync::atomic::Ordering::SeqCst);
+        if sighand_count > 1 {
+            return Err(SystemError::EINVAL);
+        }
+    }
+
+    // TODO: 如果请求 unshare CLONE_VM,
+    // 必须确保当前进程是单线程进程
+    // if flags.contains(CloneFlags::CLONE_VM) {
+    //     if !current_pcb.thread_group_empty() {
+    //         return Err(SystemError::EINVAL);
+    //     }
+    // }
+
+    Ok(())
+}

+ 12 - 0
kernel/src/process/namespace/user_namespace.rs

@@ -3,6 +3,7 @@ use core::cmp::Ordering;
 use core::fmt::Debug;
 use core::fmt::Debug;
 
 
 use crate::libs::spinlock::SpinLock;
 use crate::libs::spinlock::SpinLock;
+use crate::process::ProcessManager;
 
 
 use super::nsproxy::NsCommon;
 use super::nsproxy::NsCommon;
 use super::{NamespaceOps, NamespaceType};
 use super::{NamespaceOps, NamespaceType};
@@ -86,3 +87,14 @@ impl Debug for UserNamespace {
         f.debug_struct("UserNamespace").finish()
         f.debug_struct("UserNamespace").finish()
     }
     }
 }
 }
+
+impl ProcessManager {
+    /// 获取当前进程的 user_ns
+    pub fn current_user_ns() -> Arc<UserNamespace> {
+        if Self::initialized() {
+            ProcessManager::current_pcb().cred().user_ns.clone()
+        } else {
+            INIT_USER_NAMESPACE.clone()
+        }
+    }
+}

+ 1 - 0
kernel/src/process/syscall/mod.rs

@@ -25,6 +25,7 @@ mod sys_setresuid;
 mod sys_setsid;
 mod sys_setsid;
 mod sys_setuid;
 mod sys_setuid;
 mod sys_uname;
 mod sys_uname;
+mod sys_unshare;
 mod sys_wait4;
 mod sys_wait4;
 
 
 #[cfg(target_arch = "x86_64")]
 #[cfg(target_arch = "x86_64")]

+ 44 - 0
kernel/src/process/syscall/sys_unshare.rs

@@ -0,0 +1,44 @@
+use crate::arch::interrupt::TrapFrame;
+use crate::arch::syscall::nr::SYS_UNSHARE;
+use crate::process::fork::CloneFlags;
+use crate::process::namespace::unshare::ksys_unshare;
+use crate::syscall::table::{FormattedSyscallParam, Syscall};
+use alloc::vec::Vec;
+use system_error::SystemError;
+
+pub struct SysUnshare;
+
+impl SysUnshare {
+    fn flags(args: &[usize]) -> CloneFlags {
+        CloneFlags::from_bits_truncate(args[0] as u64)
+    }
+}
+
+impl Syscall for SysUnshare {
+    fn num_args(&self) -> usize {
+        1
+    }
+
+    /// # 函数的功能
+    /// unshare系统调用允许进程将其部分执行上下文与其他进程解耦
+    ///
+    /// ## 参数
+    /// - flags: 指定要解耦的资源类型
+    ///
+    /// ## 返回值
+    /// - 成功时返回0
+    /// - 失败时返回错误码
+    fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
+        let flags = Self::flags(args);
+        ksys_unshare(flags).map(|_| 0)
+    }
+
+    fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
+        vec![FormattedSyscallParam::new(
+            "flags",
+            format!("{:#x}", Self::flags(args).bits()),
+        )]
+    }
+}
+
+syscall_table_macros::declare_syscall!(SYS_UNSHARE, SysUnshare);

+ 43 - 0
user/dadk/config/util-linux_bin_ubuntu2404.toml

@@ -0,0 +1,43 @@
+# 用户程序名称
+name = "util-linux_bin_ubuntu2404"
+# 版本号
+version = "2.39.3"
+# 用户程序描述信息
+description = "util-linux for Ubuntu 24.04"
+# (可选)默认: false 是否只构建一次,如果为true,DADK会在构建成功后,将构建结果缓存起来,下次构建时,直接使用缓存的构建结果
+build-once = false
+#  (可选) 默认: false 是否只安装一次,如果为true,DADK会在安装成功后,不再重复安装
+install-once = false
+# 目标架构
+# 可选值:"x86_64", "aarch64", "riscv64", "loongarch64"
+target-arch = ["x86_64"]
+# 任务源
+[task-source]
+# 构建类型
+# 可选值:"build-from-source", "install-from-prebuilt"
+type = "install-from-prebuilt"
+# 构建来源
+# "build_from_source" 可选值:"git", "local", "archive"
+# "install_from_prebuilt" 可选值:"local", "archive"
+source = "archive"
+# 路径或URL
+source-path = "https://mirrors.dragonos.org.cn/pub/third_party/gnu/util-linux/util-linux-ubuntu2404-202508150101-eddba90e197f93c788bc61b2a1b78021.tar.xz"
+archive-rootdir = "sysroot/"
+
+[build]
+
+# 安装相关信息
+[install]
+# (可选)安装到DragonOS的路径
+in-dragonos-path = "/"
+# 清除相关信息
+[clean]
+# (可选)清除命令
+clean-command = ""
+# 依赖项
+[[depends]]
+name = "glibc_bin_ubuntu2404"
+version = "2.39"
+
+# (可选)环境变量
+# 注意:如果没有环境变量,忽略此项,不允许只留一个[[envs]]