mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-21 06:46:31 +00:00
添加mount系统调用 (#561)
* Modify dadk config to switch NovaShell revision * finish primary build of mount(2), usable now * 使用read_from_cstr函数优化代码可读性 , 针对文件系统新增错误EUNSUPFS * small changes * 添加系统调用文档 * cargo fmt * Revert "small changes" This reverts commite1991314ce
. * 修复用户程序参数传入错误 * Revert "small changes" This reverts commite1991314ce
. * 解决合并冲突,最终提交 * 将dadk_config切换为相对路径以修复依赖问题 * Update settings.json * Delete user/apps/test-mount/LICENSE * 换用更好的c字符串读取函数,优化系统调用函数注释,修复错误处理bug,删除无用文件,修改测试程序readme * 修改用户程序readme * 代码格式化,初级版本 * 初级版本,未实现文件系统管理器,未支持设备挂载 * 为文件系统添加name方法,返回文件系统名字字符串,为挂载查询服务 * mount系统调用:添加统一文件系统初始化管理器 * null * 解除冲突 * 删除无用kdebug
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -20,3 +20,4 @@ Cargo.lock
|
|||||||
.cache
|
.cache
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
/logs/
|
/logs/
|
||||||
|
.vscode
|
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -150,6 +150,7 @@
|
|||||||
"rust-analyzer.linkedProjects": [
|
"rust-analyzer.linkedProjects": [
|
||||||
"./kernel/Cargo.toml",
|
"./kernel/Cargo.toml",
|
||||||
"./tools/Cargo.toml",
|
"./tools/Cargo.toml",
|
||||||
|
|
||||||
],
|
],
|
||||||
// "rust-analyzer.cargo.target": "riscv64imac-unknown-none-elf",
|
// "rust-analyzer.cargo.target": "riscv64imac-unknown-none-elf",
|
||||||
"rust-analyzer.cargo.target": "x86_64-unknown-none",
|
"rust-analyzer.cargo.target": "x86_64-unknown-none",
|
||||||
@ -158,5 +159,4 @@
|
|||||||
"check",
|
"check",
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
}
|
}
|
@ -49,6 +49,10 @@ impl FileSystem for DevFS {
|
|||||||
max_name_len: DEVFS_MAX_NAMELEN,
|
max_name_len: DEVFS_MAX_NAMELEN,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"devfs"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DevFS {
|
impl DevFS {
|
||||||
|
@ -140,7 +140,6 @@ impl FATInode {
|
|||||||
// 在磁盘查找
|
// 在磁盘查找
|
||||||
let fat_entry: FATDirEntry =
|
let fat_entry: FATDirEntry =
|
||||||
d.find_entry(name, None, None, self.fs.upgrade().unwrap())?;
|
d.find_entry(name, None, None, self.fs.upgrade().unwrap())?;
|
||||||
// kdebug!("find entry from disk ok, entry={fat_entry:?}");
|
|
||||||
// 创建新的inode
|
// 创建新的inode
|
||||||
let entry_inode: Arc<LockedFATInode> = LockedFATInode::new(
|
let entry_inode: Arc<LockedFATInode> = LockedFATInode::new(
|
||||||
self.fs.upgrade().unwrap(),
|
self.fs.upgrade().unwrap(),
|
||||||
@ -248,6 +247,10 @@ impl FileSystem for FATFileSystem {
|
|||||||
fn as_any_ref(&self) -> &dyn Any {
|
fn as_any_ref(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"fat"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FATFileSystem {
|
impl FATFileSystem {
|
||||||
|
@ -47,6 +47,10 @@ impl FileSystem for KernFS {
|
|||||||
fn root_inode(&self) -> Arc<dyn IndexNode> {
|
fn root_inode(&self) -> Arc<dyn IndexNode> {
|
||||||
return self.root_inode.clone();
|
return self.root_inode.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"kernfs"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KernFS {
|
impl KernFS {
|
||||||
|
@ -281,6 +281,9 @@ impl FileSystem for ProcFS {
|
|||||||
fn as_any_ref(&self) -> &dyn core::any::Any {
|
fn as_any_ref(&self) -> &dyn core::any::Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"procfs"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProcFS {
|
impl ProcFS {
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
use core::intrinsics::unlikely;
|
use core::intrinsics::unlikely;
|
||||||
|
|
||||||
|
use crate::filesystem::vfs::FSMAKER;
|
||||||
|
use crate::{
|
||||||
|
driver::base::device::device_number::DeviceNumber,
|
||||||
|
filesystem::vfs::{core::generate_inode_id, FileType},
|
||||||
|
ipc::pipe::LockedPipeInode,
|
||||||
|
libs::spinlock::{SpinLock, SpinLockGuard},
|
||||||
|
time::TimeSpec,
|
||||||
|
};
|
||||||
use alloc::{
|
use alloc::{
|
||||||
collections::BTreeMap,
|
collections::BTreeMap,
|
||||||
string::String,
|
string::String,
|
||||||
@ -9,17 +17,9 @@ use alloc::{
|
|||||||
};
|
};
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
use crate::{
|
|
||||||
driver::base::device::device_number::DeviceNumber,
|
|
||||||
filesystem::vfs::{core::generate_inode_id, FileType},
|
|
||||||
ipc::pipe::LockedPipeInode,
|
|
||||||
libs::spinlock::{SpinLock, SpinLockGuard},
|
|
||||||
time::TimeSpec,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::vfs::{
|
use super::vfs::{
|
||||||
file::FilePrivateData, syscall::ModeType, FileSystem, FsInfo, IndexNode, InodeId, Metadata,
|
file::FilePrivateData, syscall::ModeType, FileSystem, FileSystemMaker, FsInfo, IndexNode,
|
||||||
SpecialNodeData,
|
InodeId, Metadata, SpecialNodeData,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// RamFS的inode名称的最大长度
|
/// RamFS的inode名称的最大长度
|
||||||
@ -76,6 +76,10 @@ impl FileSystem for RamFS {
|
|||||||
fn as_any_ref(&self) -> &dyn Any {
|
fn as_any_ref(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"ramfs"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RamFS {
|
impl RamFS {
|
||||||
@ -118,8 +122,19 @@ impl RamFS {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn make_ramfs() -> Result<Arc<dyn FileSystem + 'static>, SystemError> {
|
||||||
|
let fs = RamFS::new();
|
||||||
|
return Ok(fs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[distributed_slice(FSMAKER)]
|
||||||
|
static RAMFSMAKER: FileSystemMaker = FileSystemMaker::new(
|
||||||
|
"ramfs",
|
||||||
|
&(RamFS::make_ramfs as fn() -> Result<Arc<dyn FileSystem + 'static>, SystemError>),
|
||||||
|
);
|
||||||
|
|
||||||
impl IndexNode for LockedRamFSInode {
|
impl IndexNode for LockedRamFSInode {
|
||||||
fn truncate(&self, len: usize) -> Result<(), SystemError> {
|
fn truncate(&self, len: usize) -> Result<(), SystemError> {
|
||||||
let mut inode = self.0.lock();
|
let mut inode = self.0.lock();
|
||||||
|
@ -273,3 +273,11 @@ pub fn do_unlink_at(dirfd: i32, path: &str) -> Result<u64, SystemError> {
|
|||||||
|
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @brief mount filesystem
|
||||||
|
pub fn do_mount(fs: Arc<dyn FileSystem>, mount_point: &str) -> Result<usize, SystemError> {
|
||||||
|
ROOT_INODE()
|
||||||
|
.lookup_follow_symlink(&mount_point, VFS_MAX_FOLLOW_SYMLINK_TIMES)?
|
||||||
|
.mount(fs)?;
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
@ -7,7 +7,6 @@ pub mod syscall;
|
|||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use ::core::{any::Any, fmt::Debug, sync::atomic::AtomicUsize};
|
use ::core::{any::Any, fmt::Debug, sync::atomic::AtomicUsize};
|
||||||
|
|
||||||
use alloc::{string::String, sync::Arc, vec::Vec};
|
use alloc::{string::String, sync::Arc, vec::Vec};
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
@ -596,6 +595,8 @@ pub trait FileSystem: Any + Sync + Send + Debug {
|
|||||||
/// @brief 本函数用于实现动态转换。
|
/// @brief 本函数用于实现动态转换。
|
||||||
/// 具体的文件系统在实现本函数时,最简单的方式就是:直接返回self
|
/// 具体的文件系统在实现本函数时,最简单的方式就是:直接返回self
|
||||||
fn as_any_ref(&self) -> &dyn Any;
|
fn as_any_ref(&self) -> &dyn Any;
|
||||||
|
|
||||||
|
fn name(&self) -> &str;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DowncastArc for dyn FileSystem {
|
impl DowncastArc for dyn FileSystem {
|
||||||
@ -643,3 +644,49 @@ impl Metadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub struct FileSystemMaker {
|
||||||
|
function: &'static FileSystemNewFunction,
|
||||||
|
name: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FileSystemMaker {
|
||||||
|
pub const fn new(
|
||||||
|
name: &'static str,
|
||||||
|
function: &'static FileSystemNewFunction,
|
||||||
|
) -> FileSystemMaker {
|
||||||
|
FileSystemMaker { function, name }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn call(&self) -> Result<Arc<dyn FileSystem>, SystemError> {
|
||||||
|
(self.function)()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type FileSystemNewFunction = fn() -> Result<Arc<dyn FileSystem>, SystemError>;
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! define_filesystem_maker_slice {
|
||||||
|
($name:ident) => {
|
||||||
|
#[::linkme::distributed_slice]
|
||||||
|
pub static $name: [FileSystemMaker] = [..];
|
||||||
|
};
|
||||||
|
() => {
|
||||||
|
compile_error!("define_filesystem_maker_slice! requires at least one argument: slice_name");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 调用指定数组中的所有初始化器
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! producefs {
|
||||||
|
($initializer_slice:ident,$filesystem:ident) => {
|
||||||
|
match $initializer_slice.iter().find(|&m| m.name == $filesystem) {
|
||||||
|
Some(maker) => maker.call(),
|
||||||
|
None => {
|
||||||
|
kerror!("mismatch filesystem type : {}", $filesystem);
|
||||||
|
Err(SystemError::EINVAL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
define_filesystem_maker_slice!(FSMAKER);
|
||||||
|
@ -394,4 +394,8 @@ impl FileSystem for MountFS {
|
|||||||
fn as_any_ref(&self) -> &dyn Any {
|
fn as_any_ref(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"mountfs"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
|
use core::ffi::c_void;
|
||||||
use core::mem::size_of;
|
use core::mem::size_of;
|
||||||
|
|
||||||
use alloc::{string::String, sync::Arc, vec::Vec};
|
use alloc::{string::String, sync::Arc, vec::Vec};
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
|
use crate::producefs;
|
||||||
use crate::{
|
use crate::{
|
||||||
driver::base::{block::SeekFrom, device::device_number::DeviceNumber},
|
driver::base::{block::SeekFrom, device::device_number::DeviceNumber},
|
||||||
filesystem::vfs::file::FileDescriptorVec,
|
filesystem::vfs::{core as Vcore, file::FileDescriptorVec},
|
||||||
|
kerror,
|
||||||
libs::rwlock::RwLockWriteGuard,
|
libs::rwlock::RwLockWriteGuard,
|
||||||
mm::{verify_area, VirtAddr},
|
mm::{verify_area, VirtAddr},
|
||||||
process::ProcessManager,
|
process::ProcessManager,
|
||||||
syscall::{
|
syscall::{
|
||||||
user_access::{check_and_clone_cstr, UserBufferWriter},
|
user_access::{self, check_and_clone_cstr, UserBufferWriter},
|
||||||
Syscall,
|
Syscall,
|
||||||
},
|
},
|
||||||
time::TimeSpec,
|
time::TimeSpec,
|
||||||
@ -22,7 +25,7 @@ use super::{
|
|||||||
file::{File, FileMode},
|
file::{File, FileMode},
|
||||||
open::{do_faccessat, do_fchmodat, do_sys_open},
|
open::{do_faccessat, do_fchmodat, do_sys_open},
|
||||||
utils::{rsplit_path, user_path_at},
|
utils::{rsplit_path, user_path_at},
|
||||||
Dirent, FileType, IndexNode, MAX_PATHLEN, ROOT_INODE, VFS_MAX_FOLLOW_SYMLINK_TIMES,
|
Dirent, FileType, IndexNode, FSMAKER, MAX_PATHLEN, ROOT_INODE, VFS_MAX_FOLLOW_SYMLINK_TIMES,
|
||||||
};
|
};
|
||||||
// use crate::kdebug;
|
// use crate::kdebug;
|
||||||
|
|
||||||
@ -1060,6 +1063,41 @@ impl Syscall {
|
|||||||
kwarn!("fchmod not fully implemented");
|
kwarn!("fchmod not fully implemented");
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
/// #挂载文件系统
|
||||||
|
///
|
||||||
|
/// 用于挂载文件系统,目前仅支持ramfs挂载
|
||||||
|
///
|
||||||
|
/// ## 参数:
|
||||||
|
///
|
||||||
|
/// - source 挂载设备(暂时不支持)
|
||||||
|
/// - target 挂载目录
|
||||||
|
/// - filesystemtype 文件系统
|
||||||
|
/// - mountflags 挂载选项(暂未实现)
|
||||||
|
/// - data 带数据挂载
|
||||||
|
///
|
||||||
|
/// ## 返回值
|
||||||
|
/// - Ok(0): 挂载成功
|
||||||
|
/// - Err(SystemError) :挂载过程中出错
|
||||||
|
pub fn mount(
|
||||||
|
_source: *const u8,
|
||||||
|
target: *const u8,
|
||||||
|
filesystemtype: *const u8,
|
||||||
|
_mountflags: usize,
|
||||||
|
_data: *const c_void,
|
||||||
|
) -> Result<usize, SystemError> {
|
||||||
|
let target = user_access::check_and_clone_cstr(target, Some(MAX_PATHLEN))?;
|
||||||
|
|
||||||
|
let filesystemtype = user_access::check_and_clone_cstr(filesystemtype, Some(MAX_PATHLEN))?;
|
||||||
|
|
||||||
|
let filesystemtype = producefs!(FSMAKER, filesystemtype)?;
|
||||||
|
|
||||||
|
return Vcore::do_mount(filesystemtype, (format!("{target}")).as_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 想法:可以在VFS中实现一个文件系统分发器,流程如下:
|
||||||
|
// 1. 接受从上方传来的文件类型字符串
|
||||||
|
// 2. 将传入值与启动时准备好的字符串数组逐个比较(probe)
|
||||||
|
// 3. 直接在函数内调用构造方法并直接返回文件系统对象
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use core::{
|
use core::{
|
||||||
ffi::{c_int, c_void},
|
ffi::{c_int, c_void},
|
||||||
|
ptr::null,
|
||||||
sync::atomic::{AtomicBool, Ordering},
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -942,6 +943,13 @@ impl Syscall {
|
|||||||
|
|
||||||
Err(SystemError::ENOSYS)
|
Err(SystemError::ENOSYS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SYS_MOUNT => {
|
||||||
|
let source = args[0] as *const u8;
|
||||||
|
let target = args[1] as *const u8;
|
||||||
|
let filesystemtype = args[2] as *const u8;
|
||||||
|
return Self::mount(source, target, filesystemtype, 0, null());
|
||||||
|
}
|
||||||
SYS_NEWFSTATAT => {
|
SYS_NEWFSTATAT => {
|
||||||
// todo: 这个系统调用还没有实现
|
// todo: 这个系统调用还没有实现
|
||||||
|
|
||||||
@ -953,6 +961,7 @@ impl Syscall {
|
|||||||
let name = args[0] as *mut PosixOldUtsName;
|
let name = args[0] as *mut PosixOldUtsName;
|
||||||
Self::uname(name)
|
Self::uname(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => panic!("Unsupported syscall ID: {}", syscall_num),
|
_ => panic!("Unsupported syscall ID: {}", syscall_num),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@
|
|||||||
|
|
||||||
#define SYS_ARCH_PRCTL 158
|
#define SYS_ARCH_PRCTL 158
|
||||||
|
|
||||||
|
#define SYS_MOUNT 165
|
||||||
#define SYS_REBOOT 169
|
#define SYS_REBOOT 169
|
||||||
|
|
||||||
#define SYS_GETPPID 110
|
#define SYS_GETPPID 110
|
||||||
|
3
user/apps/test-mount/.gitignore
vendored
Normal file
3
user/apps/test-mount/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/target
|
||||||
|
Cargo.lock
|
||||||
|
/install/
|
11
user/apps/test-mount/Cargo.toml
Normal file
11
user/apps/test-mount/Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
name = "test-mount"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
description = "test the new mount syscall"
|
||||||
|
authors = [ "xiaolin2004 <1553367438@qq.com>" ]
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
libc="0.2"
|
56
user/apps/test-mount/Makefile
Normal file
56
user/apps/test-mount/Makefile
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
TOOLCHAIN="+nightly-2023-08-15-x86_64-unknown-linux-gnu"
|
||||||
|
RUSTFLAGS+=""
|
||||||
|
|
||||||
|
ifdef DADK_CURRENT_BUILD_DIR
|
||||||
|
# 如果是在dadk中编译,那么安装到dadk的安装目录中
|
||||||
|
INSTALL_DIR = $(DADK_CURRENT_BUILD_DIR)
|
||||||
|
else
|
||||||
|
# 如果是在本地编译,那么安装到当前目录下的install目录中
|
||||||
|
INSTALL_DIR = ./install
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(ARCH), x86_64)
|
||||||
|
export RUST_TARGET=x86_64-unknown-linux-musl
|
||||||
|
else ifeq ($(ARCH), riscv64)
|
||||||
|
export RUST_TARGET=riscv64gc-unknown-linux-gnu
|
||||||
|
else
|
||||||
|
# 默认为x86_86,用于本地编译
|
||||||
|
export RUST_TARGET=x86_64-unknown-linux-musl
|
||||||
|
endif
|
||||||
|
|
||||||
|
run:
|
||||||
|
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) run --target $(RUST_TARGET)
|
||||||
|
|
||||||
|
build:
|
||||||
|
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) build --target $(RUST_TARGET)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) clean --target $(RUST_TARGET)
|
||||||
|
|
||||||
|
test:
|
||||||
|
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) test --target $(RUST_TARGET)
|
||||||
|
|
||||||
|
doc:
|
||||||
|
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) doc --target $(RUST_TARGET)
|
||||||
|
|
||||||
|
fmt:
|
||||||
|
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) fmt
|
||||||
|
|
||||||
|
fmt-check:
|
||||||
|
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) fmt --check
|
||||||
|
|
||||||
|
run-release:
|
||||||
|
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) run --target $(RUST_TARGET) --release
|
||||||
|
|
||||||
|
build-release:
|
||||||
|
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) build --target $(RUST_TARGET) --release
|
||||||
|
|
||||||
|
clean-release:
|
||||||
|
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) clean --target $(RUST_TARGET) --release
|
||||||
|
|
||||||
|
test-release:
|
||||||
|
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) test --target $(RUST_TARGET) --release
|
||||||
|
|
||||||
|
.PHONY: install
|
||||||
|
install:
|
||||||
|
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) install --target $(RUST_TARGET) --path . --no-track --root $(INSTALL_DIR) --force
|
3
user/apps/test-mount/README.md
Normal file
3
user/apps/test-mount/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# test-mount
|
||||||
|
|
||||||
|
用于测试mount系统调用的用户程序
|
17
user/apps/test-mount/src/main.rs
Normal file
17
user/apps/test-mount/src/main.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
use core::ffi::{c_char, c_void};
|
||||||
|
use libc::{mount, MS_BIND};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let source = b"\0".as_ptr() as *const c_char;
|
||||||
|
let target = b"/mnt/tmp\0".as_ptr() as *const c_char;
|
||||||
|
let fstype = b"ramfs\0".as_ptr() as *const c_char;
|
||||||
|
let flags = MS_BIND;
|
||||||
|
let data = std::ptr::null() as *const c_void;
|
||||||
|
let result = unsafe { mount(source, target, fstype, flags, data) };
|
||||||
|
|
||||||
|
if result == 0 {
|
||||||
|
println!("Mount successful");
|
||||||
|
} else {
|
||||||
|
println!("Mount failed");
|
||||||
|
}
|
||||||
|
}
|
22
user/dadk/config/test_mount_1_0_0.dadk
Normal file
22
user/dadk/config/test_mount_1_0_0.dadk
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "test-mount",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "to test user mode mount",
|
||||||
|
"task_type": {
|
||||||
|
"BuildFromSource": {
|
||||||
|
"Local": {
|
||||||
|
"path": "apps/test-mount"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"depends": [],
|
||||||
|
"build": {
|
||||||
|
"build_command": "make install"
|
||||||
|
},
|
||||||
|
"install": {
|
||||||
|
"in_dragonos_path": "/"
|
||||||
|
},
|
||||||
|
"clean": {
|
||||||
|
"clean_command": "make clean"
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user