mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-20 18:26:32 +00:00
feat:Add tracepoint prototype (#1088)
* feat:Add tracepoint prototype Signed-off-by: Godones <chenlinfeng25@outlook.com>
This commit is contained in:
155
kernel/Cargo.lock
generated
155
kernel/Cargo.lock
generated
@ -212,7 +212,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe05a1a3c09033e9e87f7ba13af35cf2508148d3a97fb6b16475df84207993fa"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows",
|
||||
"windows 0.58.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1498,14 +1498,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "static-keys"
|
||||
version = "0.6.1"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ae6eb9d5e3c88a62145a3f2edd2e45c296bad8ef3e31b06d654acff70272744"
|
||||
checksum = "aa784228d57f9f47a0f5837289ba92296239c2273f146d97b35bbd8538806777"
|
||||
dependencies = [
|
||||
"clear-cache",
|
||||
"libc",
|
||||
"mach2",
|
||||
"windows",
|
||||
"windows 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1972,23 +1972,46 @@ version = "0.58.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-core 0.58.0",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f919aee0a93304be7f62e8e5027811bbba96bcb1de84d6618be56e43f8a32a1"
|
||||
dependencies = [
|
||||
"windows-core 0.59.0",
|
||||
"windows-targets 0.53.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.58.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-result",
|
||||
"windows-strings",
|
||||
"windows-implement 0.58.0",
|
||||
"windows-interface 0.58.0",
|
||||
"windows-result 0.2.0",
|
||||
"windows-strings 0.1.0",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "810ce18ed2112484b0d4e15d022e5f598113e220c53e373fb31e67e21670c1ce"
|
||||
dependencies = [
|
||||
"windows-implement 0.59.0",
|
||||
"windows-interface 0.59.1",
|
||||
"windows-result 0.3.2",
|
||||
"windows-strings 0.3.1",
|
||||
"windows-targets 0.53.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.58.0"
|
||||
@ -2000,6 +2023,17 @@ dependencies = [
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.58.0"
|
||||
@ -2011,6 +2045,23 @@ dependencies = [
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.59.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.2.0"
|
||||
@ -2020,16 +2071,34 @@ dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
|
||||
dependencies = [
|
||||
"windows-result",
|
||||
"windows-result 0.2.0",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
@ -2072,13 +2141,29 @@ dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.6",
|
||||
"windows_aarch64_msvc 0.52.6",
|
||||
"windows_i686_gnu 0.52.6",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_gnullvm 0.52.6",
|
||||
"windows_i686_msvc 0.52.6",
|
||||
"windows_x86_64_gnu 0.52.6",
|
||||
"windows_x86_64_gnullvm 0.52.6",
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.53.0",
|
||||
"windows_aarch64_msvc 0.53.0",
|
||||
"windows_i686_gnu 0.53.0",
|
||||
"windows_i686_gnullvm 0.53.0",
|
||||
"windows_i686_msvc 0.53.0",
|
||||
"windows_x86_64_gnu 0.53.0",
|
||||
"windows_x86_64_gnullvm 0.53.0",
|
||||
"windows_x86_64_msvc 0.53.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
@ -2091,6 +2176,12 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
@ -2103,6 +2194,12 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
@ -2115,12 +2212,24 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
@ -2133,6 +2242,12 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
@ -2145,6 +2260,12 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
@ -2157,6 +2278,12 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
@ -2169,6 +2296,12 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.4"
|
||||
|
@ -75,7 +75,7 @@ lru = "0.12.3"
|
||||
rbpf = { path = "crates/rbpf" }
|
||||
printf-compat = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/printf-compat", rev = "5f5c9cc363", default-features = false }
|
||||
|
||||
static-keys = "=0.6.1"
|
||||
static-keys = { version = "=0.7" }
|
||||
|
||||
defer = "0.2.1"
|
||||
cfg-if = { version = "1.0.0" }
|
||||
|
@ -66,6 +66,16 @@ SECTIONS
|
||||
}
|
||||
|
||||
. = ALIGN(32768);
|
||||
|
||||
trace_point_start_pa = .;
|
||||
.tracepoint (trace_point_start_pa): AT(trace_point_start_pa - KERNEL_VMA)
|
||||
{
|
||||
_tracepoint = .;
|
||||
*(.tracepoint)
|
||||
*(.tracepoint.*)
|
||||
_etracepoint = .;
|
||||
}
|
||||
. = ALIGN(32768);
|
||||
|
||||
init_proc_union_start_pa = .;
|
||||
.data.init_proc_union (init_proc_union_start_pa):
|
||||
|
@ -68,6 +68,16 @@ SECTIONS
|
||||
|
||||
. = ALIGN(32768);
|
||||
|
||||
trace_point_start_pa = .;
|
||||
.tracepoint (trace_point_start_pa): AT(trace_point_start_pa - KERNEL_VMA)
|
||||
{
|
||||
_tracepoint = .;
|
||||
*(.tracepoint)
|
||||
*(.tracepoint.*)
|
||||
_etracepoint = .;
|
||||
}
|
||||
. = ALIGN(32768);
|
||||
|
||||
init_proc_union_start_pa = .;
|
||||
.data.init_proc_union (init_proc_union_start_pa): AT(init_proc_union_start_pa - KERNEL_VMA)
|
||||
{ *(.data.init_proc_union) }
|
||||
|
@ -67,6 +67,16 @@ SECTIONS
|
||||
|
||||
. = ALIGN(32768);
|
||||
|
||||
trace_point_start_pa = .;
|
||||
.tracepoint (trace_point_start_pa): AT(trace_point_start_pa - KERNEL_VMA)
|
||||
{
|
||||
_tracepoint = .;
|
||||
*(.tracepoint)
|
||||
*(.tracepoint.*)
|
||||
_etracepoint = .;
|
||||
}
|
||||
. = ALIGN(32768);
|
||||
|
||||
init_proc_union_start_pa = .;
|
||||
.data.init_proc_union (init_proc_union_start_pa): AT(init_proc_union_start_pa - KERNEL_VMA)
|
||||
{ *(.data.init_proc_union) }
|
||||
|
3
kernel/src/debug/.gitignore
vendored
3
kernel/src/debug/.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
gen_kallsyms
|
||||
kallsyms.S
|
||||
kallsyms.S
|
||||
kallsyms
|
||||
|
@ -2,4 +2,6 @@ pub mod jump_label;
|
||||
pub mod klog;
|
||||
pub mod kprobe;
|
||||
pub mod panic;
|
||||
pub mod sysfs;
|
||||
pub mod traceback;
|
||||
pub mod tracing;
|
||||
|
28
kernel/src/debug/sysfs/mod.rs
Normal file
28
kernel/src/debug/sysfs/mod.rs
Normal file
@ -0,0 +1,28 @@
|
||||
use crate::driver::base::kset::KSet;
|
||||
use crate::init::initcall::INITCALL_POSTCORE;
|
||||
use crate::misc::ksysfs::sys_kernel_kset;
|
||||
use alloc::string::ToString;
|
||||
use alloc::sync::Arc;
|
||||
use system_error::SystemError;
|
||||
use unified_init::macros::unified_init;
|
||||
|
||||
/// `/sys/kernel/debug`的kset
|
||||
static mut SYS_KERNEL_DEBUG_KSET_INSTANCE: Option<Arc<KSet>> = None;
|
||||
|
||||
/// 初始化debug模块在sysfs中的目录
|
||||
#[unified_init(INITCALL_POSTCORE)]
|
||||
fn debugfs_init() -> Result<(), SystemError> {
|
||||
let debug_kset = KSet::new("debug".to_string());
|
||||
debug_kset
|
||||
.register(Some(sys_kernel_kset()))
|
||||
.expect("register debug kset failed");
|
||||
unsafe {
|
||||
SYS_KERNEL_DEBUG_KSET_INSTANCE = Some(debug_kset);
|
||||
}
|
||||
super::tracing::init_debugfs_tracing()?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
pub fn debugfs_kset() -> Arc<KSet> {
|
||||
unsafe { SYS_KERNEL_DEBUG_KSET_INSTANCE.clone().unwrap() }
|
||||
}
|
239
kernel/src/debug/tracing/events.rs
Normal file
239
kernel/src/debug/tracing/events.rs
Normal file
@ -0,0 +1,239 @@
|
||||
use crate::debug::tracing::tracepoint::{CommonTracePointMeta, TracePoint};
|
||||
use crate::debug::tracing::TracingDirCallBack;
|
||||
use crate::filesystem::kernfs::callback::{KernCallbackData, KernFSCallback, KernInodePrivateData};
|
||||
use crate::filesystem::kernfs::KernFSInode;
|
||||
use crate::filesystem::vfs::syscall::ModeType;
|
||||
use crate::filesystem::vfs::PollStatus;
|
||||
use crate::libs::spinlock::SpinLock;
|
||||
use alloc::boxed::Box;
|
||||
use alloc::collections::BTreeMap;
|
||||
use alloc::string::{String, ToString};
|
||||
use alloc::sync::Arc;
|
||||
use system_error::SystemError;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TracingEventsManager {
|
||||
root: Arc<KernFSInode>,
|
||||
subsystems: SpinLock<BTreeMap<String, Arc<EventsSubsystem>>>,
|
||||
}
|
||||
|
||||
impl TracingEventsManager {
|
||||
pub fn new(root: Arc<KernFSInode>) -> Self {
|
||||
Self {
|
||||
root,
|
||||
subsystems: SpinLock::new(BTreeMap::new()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a subsystem by name
|
||||
///
|
||||
/// If the subsystem already exists, return the existing subsystem.
|
||||
pub fn create_subsystem(
|
||||
&self,
|
||||
subsystem_name: &str,
|
||||
) -> Result<Arc<EventsSubsystem>, SystemError> {
|
||||
if self.subsystems.lock().contains_key(subsystem_name) {
|
||||
return Ok(self.get_subsystem(subsystem_name).unwrap());
|
||||
}
|
||||
let dir = self.root.add_dir(
|
||||
subsystem_name.to_string(),
|
||||
ModeType::from_bits_truncate(0o755),
|
||||
None,
|
||||
Some(&TracingDirCallBack),
|
||||
)?;
|
||||
let subsystem = Arc::new(EventsSubsystem::new(dir));
|
||||
self.subsystems
|
||||
.lock()
|
||||
.insert(subsystem_name.to_string(), subsystem.clone());
|
||||
Ok(subsystem)
|
||||
}
|
||||
|
||||
/// Get the subsystem by name
|
||||
pub fn get_subsystem(&self, subsystem_name: &str) -> Option<Arc<EventsSubsystem>> {
|
||||
self.subsystems.lock().get(subsystem_name).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EventsSubsystem {
|
||||
root: Arc<KernFSInode>,
|
||||
events: SpinLock<BTreeMap<String, Arc<EventInfo>>>,
|
||||
}
|
||||
|
||||
impl EventsSubsystem {
|
||||
pub fn new(root: Arc<KernFSInode>) -> Self {
|
||||
Self {
|
||||
root,
|
||||
events: SpinLock::new(BTreeMap::new()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Insert a new event into the subsystem
|
||||
pub fn insert_event(
|
||||
&self,
|
||||
event_name: &str,
|
||||
event_info: Arc<EventInfo>,
|
||||
) -> Result<(), SystemError> {
|
||||
self.events
|
||||
.lock()
|
||||
.insert(event_name.to_string(), event_info);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get the event by name
|
||||
#[allow(unused)]
|
||||
pub fn get_event(&self, event_name: &str) -> Option<Arc<EventInfo>> {
|
||||
self.events.lock().get(event_name).cloned()
|
||||
}
|
||||
|
||||
/// Get the root inode of the subsystem
|
||||
pub fn root(&self) -> Arc<KernFSInode> {
|
||||
self.root.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EventInfo {
|
||||
#[allow(unused)]
|
||||
enable: Arc<KernFSInode>,
|
||||
// filter: Arc<KernFSInode>,
|
||||
// trigger: Arc<KernFSInode>,
|
||||
}
|
||||
|
||||
impl EventInfo {
|
||||
pub fn new(tracepoint: &'static TracePoint, subsystem: Arc<KernFSInode>) -> Arc<Self> {
|
||||
let trace_dir = subsystem
|
||||
.add_dir(
|
||||
tracepoint.name().to_string(),
|
||||
ModeType::from_bits_truncate(0o755),
|
||||
None,
|
||||
Some(&TracingDirCallBack),
|
||||
)
|
||||
.expect("add tracepoint dir failed");
|
||||
let enable_inode = trace_dir
|
||||
.add_file(
|
||||
"enable".to_string(),
|
||||
ModeType::from_bits_truncate(0o644),
|
||||
None,
|
||||
Some(KernInodePrivateData::DebugFS(tracepoint)),
|
||||
Some(&EnableCallBack),
|
||||
)
|
||||
.expect("add enable file failed");
|
||||
|
||||
Arc::new(Self {
|
||||
enable: enable_inode,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for EventInfo {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct EnableCallBack;
|
||||
|
||||
impl KernFSCallback for EnableCallBack {
|
||||
fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read(
|
||||
&self,
|
||||
data: KernCallbackData,
|
||||
buf: &mut [u8],
|
||||
offset: usize,
|
||||
) -> Result<usize, SystemError> {
|
||||
if offset > 0 {
|
||||
return Ok(0);
|
||||
}
|
||||
let pri_data = data.private_data();
|
||||
match pri_data {
|
||||
Some(pri_data) => {
|
||||
let tracepoint = pri_data.debugfs_tracepoint().ok_or(SystemError::EINVAL)?;
|
||||
let buf_value = if tracepoint.is_enabled() { b"1" } else { b"0" };
|
||||
let len = buf.len().min(buf_value.len());
|
||||
buf[..len].copy_from_slice(&buf_value[..len]);
|
||||
Ok(len)
|
||||
}
|
||||
None => {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn write(
|
||||
&self,
|
||||
data: KernCallbackData,
|
||||
buf: &[u8],
|
||||
_offset: usize,
|
||||
) -> Result<usize, SystemError> {
|
||||
let pri_data = data.private_data();
|
||||
match pri_data {
|
||||
Some(pri_data) => {
|
||||
let tracepoint = pri_data.debugfs_tracepoint().ok_or(SystemError::EINVAL)?;
|
||||
let value = core::str::from_utf8(buf)
|
||||
.map_err(|_| SystemError::EINVAL)?
|
||||
.trim();
|
||||
match value {
|
||||
"0" => {
|
||||
tracepoint.disable();
|
||||
}
|
||||
"1" => {
|
||||
tracepoint.enable();
|
||||
}
|
||||
_ => {
|
||||
log::info!("EnableCallBack invalid value: {}", value);
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
}
|
||||
Ok(buf.len())
|
||||
}
|
||||
None => {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
|
||||
Err(SystemError::ENOSYS)
|
||||
}
|
||||
}
|
||||
|
||||
static mut TRACING_EVENTS_MANAGER: Option<TracingEventsManager> = None;
|
||||
|
||||
/// Initialize the tracing events
|
||||
pub fn init_events(events_root: Arc<KernFSInode>) -> Result<(), SystemError> {
|
||||
let events_manager = TracingEventsManager::new(events_root);
|
||||
let tracepoint_data_start = _tracepoint as usize as *const CommonTracePointMeta;
|
||||
let tracepoint_data_end = _etracepoint as usize as *const CommonTracePointMeta;
|
||||
let tracepoint_data_len = (tracepoint_data_end as usize - tracepoint_data_start as usize)
|
||||
/ size_of::<CommonTracePointMeta>();
|
||||
let tracepoint_data =
|
||||
unsafe { core::slice::from_raw_parts(tracepoint_data_start, tracepoint_data_len) };
|
||||
for tracepoint_meta in tracepoint_data {
|
||||
let tracepoint = tracepoint_meta.trace_point;
|
||||
tracepoint.register(tracepoint_meta.print_func, Box::new(()));
|
||||
log::info!(
|
||||
"tracepoint name: {}, module path: {}",
|
||||
tracepoint.name(),
|
||||
tracepoint.module_path()
|
||||
);
|
||||
// kernel::{subsystem}::
|
||||
let mut subsys_name = tracepoint.module_path().split("::");
|
||||
let subsys_name = subsys_name.nth(1).ok_or(SystemError::EINVAL)?;
|
||||
let subsys = events_manager.create_subsystem(subsys_name)?;
|
||||
let event_info = EventInfo::new(tracepoint, subsys.root());
|
||||
subsys.insert_event(tracepoint.name(), event_info)?;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
TRACING_EVENTS_MANAGER = Some(events_manager);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
extern "C" {
|
||||
fn _tracepoint();
|
||||
fn _etracepoint();
|
||||
}
|
97
kernel/src/debug/tracing/mod.rs
Normal file
97
kernel/src/debug/tracing/mod.rs
Normal file
@ -0,0 +1,97 @@
|
||||
mod events;
|
||||
pub mod trace_pipe;
|
||||
pub mod tracepoint;
|
||||
|
||||
use crate::debug::sysfs::debugfs_kset;
|
||||
use crate::debug::tracing::trace_pipe::TRACE_PIPE_MAX_RECORD;
|
||||
use crate::driver::base::kobject::KObject;
|
||||
use crate::filesystem::kernfs::callback::{KernCallbackData, KernFSCallback, KernInodePrivateData};
|
||||
use crate::filesystem::kernfs::KernFSInode;
|
||||
use crate::filesystem::vfs::syscall::ModeType;
|
||||
use crate::filesystem::vfs::PollStatus;
|
||||
use alloc::string::ToString;
|
||||
use alloc::sync::Arc;
|
||||
use system_error::SystemError;
|
||||
use tracepoint::TracePoint;
|
||||
|
||||
static mut TRACING_ROOT_INODE: Option<Arc<KernFSInode>> = None;
|
||||
|
||||
#[allow(unused)]
|
||||
fn tracing_root_inode() -> Arc<KernFSInode> {
|
||||
unsafe { TRACING_ROOT_INODE.clone().unwrap() }
|
||||
}
|
||||
|
||||
/// Initialize the debugfs tracing directory
|
||||
pub fn init_debugfs_tracing() -> Result<(), SystemError> {
|
||||
let debugfs = debugfs_kset();
|
||||
let root_dir = debugfs.inode().ok_or(SystemError::ENOENT)?;
|
||||
let tracing_root = root_dir.add_dir(
|
||||
"tracing".to_string(),
|
||||
ModeType::from_bits_truncate(0o555),
|
||||
None,
|
||||
Some(&TracingDirCallBack),
|
||||
)?;
|
||||
let events_root = tracing_root.add_dir(
|
||||
"events".to_string(),
|
||||
ModeType::from_bits_truncate(0o755),
|
||||
None,
|
||||
Some(&TracingDirCallBack),
|
||||
)?;
|
||||
|
||||
tracing_root.add_file(
|
||||
"trace_pipe".to_string(),
|
||||
ModeType::from_bits_truncate(0o444),
|
||||
Some(TRACE_PIPE_MAX_RECORD),
|
||||
None,
|
||||
Some(&trace_pipe::TracePipeCallBack),
|
||||
)?;
|
||||
|
||||
trace_pipe::init_trace_pipe();
|
||||
|
||||
events::init_events(events_root)?;
|
||||
|
||||
unsafe {
|
||||
TRACING_ROOT_INODE = Some(tracing_root);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TracingDirCallBack;
|
||||
|
||||
impl KernFSCallback for TracingDirCallBack {
|
||||
fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read(
|
||||
&self,
|
||||
_data: KernCallbackData,
|
||||
_buf: &mut [u8],
|
||||
_offset: usize,
|
||||
) -> Result<usize, SystemError> {
|
||||
Err(SystemError::EISDIR)
|
||||
}
|
||||
|
||||
fn write(
|
||||
&self,
|
||||
_data: KernCallbackData,
|
||||
_buf: &[u8],
|
||||
_offset: usize,
|
||||
) -> Result<usize, SystemError> {
|
||||
Err(SystemError::EISDIR)
|
||||
}
|
||||
|
||||
fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
|
||||
Err(SystemError::EISDIR)
|
||||
}
|
||||
}
|
||||
|
||||
impl KernInodePrivateData {
|
||||
pub fn debugfs_tracepoint(&self) -> Option<&'static TracePoint> {
|
||||
return match self {
|
||||
KernInodePrivateData::DebugFS(tracepoint) => Some(tracepoint),
|
||||
_ => None,
|
||||
};
|
||||
}
|
||||
}
|
123
kernel/src/debug/tracing/trace_pipe.rs
Normal file
123
kernel/src/debug/tracing/trace_pipe.rs
Normal file
@ -0,0 +1,123 @@
|
||||
use crate::filesystem::kernfs::callback::{KernCallbackData, KernFSCallback};
|
||||
use crate::filesystem::vfs::PollStatus;
|
||||
use crate::libs::spinlock::SpinLock;
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
use core::fmt::Debug;
|
||||
use system_error::SystemError;
|
||||
|
||||
static mut TRACE_PIPE: Option<TracePipe> = None;
|
||||
|
||||
pub const TRACE_PIPE_MAX_RECORD: usize = 4096;
|
||||
|
||||
pub fn init_trace_pipe() {
|
||||
unsafe {
|
||||
TRACE_PIPE = Some(TracePipe::new(TRACE_PIPE_MAX_RECORD));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trace_pipe() -> &'static TracePipe {
|
||||
unsafe { TRACE_PIPE.as_ref().unwrap() }
|
||||
}
|
||||
|
||||
/// Push a record to trace pipe
|
||||
pub fn trace_pipe_push_record(record: String) {
|
||||
trace_pipe().push_record(record);
|
||||
}
|
||||
|
||||
pub struct TracePipe {
|
||||
buf: SpinLock<TracePipeBuf>,
|
||||
}
|
||||
|
||||
struct TracePipeBuf {
|
||||
size: usize,
|
||||
max_record: usize,
|
||||
buf: Vec<String>,
|
||||
}
|
||||
|
||||
impl TracePipeBuf {
|
||||
pub const fn new(max_record: usize) -> Self {
|
||||
Self {
|
||||
max_record,
|
||||
size: 0,
|
||||
buf: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push_str(&mut self, record: String) {
|
||||
let record_size = record.len();
|
||||
if self.size + record_size > self.max_record {
|
||||
let mut i = 0;
|
||||
while i < record_size {
|
||||
let t = self.buf.pop().unwrap();
|
||||
self.size -= t.len();
|
||||
i += t.len();
|
||||
}
|
||||
}
|
||||
self.buf.push(record);
|
||||
self.size += record_size;
|
||||
}
|
||||
|
||||
pub fn read_at(&self, buf: &mut [u8], offset: usize) -> Result<usize, SystemError> {
|
||||
if offset == self.size {
|
||||
return Ok(0);
|
||||
}
|
||||
if buf.len() < self.size {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
let mut count = 0;
|
||||
for line in self.buf.iter() {
|
||||
let line = line.as_bytes();
|
||||
buf[count..count + line.len()].copy_from_slice(line);
|
||||
count += line.len();
|
||||
}
|
||||
Ok(count)
|
||||
}
|
||||
}
|
||||
|
||||
impl TracePipe {
|
||||
pub const fn new(max_record: usize) -> Self {
|
||||
Self {
|
||||
buf: SpinLock::new(TracePipeBuf::new(max_record)),
|
||||
}
|
||||
}
|
||||
pub fn push_record(&self, record: String) {
|
||||
self.buf.lock().push_str(record);
|
||||
}
|
||||
|
||||
pub fn read_at(&self, buf: &mut [u8], offset: usize) -> Result<usize, SystemError> {
|
||||
self.buf.lock().read_at(buf, offset)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TracePipeCallBack;
|
||||
|
||||
impl KernFSCallback for TracePipeCallBack {
|
||||
fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read(
|
||||
&self,
|
||||
_data: KernCallbackData,
|
||||
buf: &mut [u8],
|
||||
offset: usize,
|
||||
) -> Result<usize, SystemError> {
|
||||
let trace_pipe = trace_pipe();
|
||||
trace_pipe.read_at(buf, offset)
|
||||
}
|
||||
|
||||
fn write(
|
||||
&self,
|
||||
_data: KernCallbackData,
|
||||
_buf: &[u8],
|
||||
_offset: usize,
|
||||
) -> Result<usize, SystemError> {
|
||||
Err(SystemError::EPERM)
|
||||
}
|
||||
|
||||
fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
|
||||
Ok(PollStatus::READ)
|
||||
}
|
||||
}
|
187
kernel/src/debug/tracing/tracepoint.rs
Normal file
187
kernel/src/debug/tracing/tracepoint.rs
Normal file
@ -0,0 +1,187 @@
|
||||
use crate::libs::spinlock::{SpinLock, SpinLockGuard};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::collections::BTreeMap;
|
||||
use core::any::Any;
|
||||
use core::fmt::Debug;
|
||||
use static_keys::StaticFalseKey;
|
||||
|
||||
pub struct TracePoint {
|
||||
name: &'static str,
|
||||
module_path: &'static str,
|
||||
key: &'static StaticFalseKey,
|
||||
register: Option<fn()>,
|
||||
unregister: Option<fn()>,
|
||||
callback: SpinLock<BTreeMap<usize, TracePointFunc>>,
|
||||
}
|
||||
|
||||
impl Debug for TracePoint {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("TracePoint")
|
||||
.field("name", &self.name)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(C)]
|
||||
pub struct CommonTracePointMeta {
|
||||
pub trace_point: &'static TracePoint,
|
||||
pub print_func: fn(),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TracePointFunc {
|
||||
pub func: fn(),
|
||||
pub data: Box<dyn Any + Send + Sync>,
|
||||
}
|
||||
|
||||
impl TracePoint {
|
||||
pub const fn new(
|
||||
key: &'static StaticFalseKey,
|
||||
name: &'static str,
|
||||
module_path: &'static str,
|
||||
register: Option<fn()>,
|
||||
unregister: Option<fn()>,
|
||||
) -> Self {
|
||||
Self {
|
||||
name,
|
||||
module_path,
|
||||
key,
|
||||
register,
|
||||
unregister,
|
||||
callback: SpinLock::new(BTreeMap::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &'static str {
|
||||
self.name
|
||||
}
|
||||
|
||||
pub fn module_path(&self) -> &'static str {
|
||||
self.module_path
|
||||
}
|
||||
|
||||
/// Register a callback function to the tracepoint
|
||||
pub fn register(&self, func: fn(), data: Box<dyn Any + Sync + Send>) {
|
||||
let trace_point_func = TracePointFunc { func, data };
|
||||
let mut funcs = self.callback.lock();
|
||||
if let Some(register) = self.register {
|
||||
register();
|
||||
}
|
||||
let ptr = func as usize;
|
||||
funcs.entry(ptr).or_insert(trace_point_func);
|
||||
}
|
||||
|
||||
/// Unregister a callback function from the tracepoint
|
||||
pub fn unregister(&self, func: fn()) {
|
||||
let mut funcs = self.callback.lock();
|
||||
if let Some(unregister) = self.unregister {
|
||||
unregister();
|
||||
}
|
||||
let func_ptr = func as usize;
|
||||
funcs.remove(&func_ptr);
|
||||
}
|
||||
|
||||
/// Get the callback list
|
||||
pub fn callback_list(&self) -> SpinLockGuard<BTreeMap<usize, TracePointFunc>> {
|
||||
self.callback.lock()
|
||||
}
|
||||
|
||||
/// Enable the tracepoint
|
||||
pub fn enable(&self) {
|
||||
unsafe {
|
||||
self.key.enable();
|
||||
}
|
||||
}
|
||||
|
||||
/// Disable the tracepoint
|
||||
pub fn disable(&self) {
|
||||
unsafe {
|
||||
self.key.disable();
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if the tracepoint is enabled
|
||||
pub fn is_enabled(&self) -> bool {
|
||||
self.key.is_enabled()
|
||||
}
|
||||
}
|
||||
|
||||
/// Define a tracepoint
|
||||
///
|
||||
/// User should call register_trace_\$name to register a callback function to the tracepoint and
|
||||
/// call trace_\$name to trigger the callback function
|
||||
#[macro_export]
|
||||
macro_rules! define_trace_point {
|
||||
($name:ident $(,$arg:ident:$arg_type:ty),*) => {
|
||||
paste::paste!{
|
||||
static_keys::define_static_key_false!([<__ $name _KEY>]);
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[used]
|
||||
static [<__ $name>]: $crate::debug::tracing::tracepoint::TracePoint = $crate::debug::tracing::tracepoint::TracePoint::new(&[<__ $name _KEY>],stringify!($name), module_path!(),None,None);
|
||||
|
||||
#[inline(always)]
|
||||
#[allow(non_snake_case)]
|
||||
pub fn [<TRACE_ $name>]( $($arg:$arg_type),* ){
|
||||
|
||||
if static_keys::static_branch_unlikely!([<__ $name _KEY>]){
|
||||
let mut funcs = [<__ $name>].callback_list();
|
||||
for trace_func in funcs.values_mut(){
|
||||
let func = trace_func.func;
|
||||
let data = trace_func.data.as_mut();
|
||||
let func = unsafe{core::mem::transmute::<fn(),fn(&mut (dyn core::any::Any+Send+Sync),$($arg_type),*)>(func)};
|
||||
func(data $(,$arg)*);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[allow(unused,non_snake_case)]
|
||||
pub fn [<register_trace_ $name>](func:fn(&mut (dyn core::any::Any+Send+Sync),$($arg_type),*),data:alloc::boxed::Box<dyn core::any::Any+Send+Sync>){
|
||||
let func = unsafe{core::mem::transmute::<fn(&mut (dyn core::any::Any+Send+Sync),$($arg_type),*),fn()>(func)};
|
||||
[<__ $name>].register(func,data);
|
||||
}
|
||||
|
||||
#[allow(unused,non_snake_case)]
|
||||
pub fn [<unregister_trace_ $name>](func:fn(&mut (dyn core::any::Any+Send+Sync),$($arg_type),*)){
|
||||
let func = unsafe{core::mem::transmute::<fn(&mut (dyn core::any::Any+Send+Sync),$($arg_type),*),fn()>(func)};
|
||||
[<__ $name>].unregister(func);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! define_event_trace{
|
||||
($name:ident,
|
||||
($($arg:ident:$arg_type:ty),*),
|
||||
$fmt:expr) =>{
|
||||
define_trace_point!($name $(,$arg:$arg_type),*);
|
||||
paste::paste!{
|
||||
#[derive(Debug)]
|
||||
#[repr(C)]
|
||||
#[allow(non_snake_case)]
|
||||
|
||||
struct [<__ $name _TracePointMeta>]{
|
||||
trace_point: &'static $crate::debug::tracing::tracepoint::TracePoint,
|
||||
print_func: fn(&mut (dyn core::any::Any+Send+Sync),$($arg_type),*),
|
||||
}
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[link_section = ".tracepoint"]
|
||||
#[used]
|
||||
static [<__ $name _meta>]: [<__ $name _TracePointMeta>] = [<__ $name _TracePointMeta>]{
|
||||
trace_point:&[<__ $name>],
|
||||
print_func:[<TRACE_PRINT_ $name>],
|
||||
};
|
||||
#[allow(non_snake_case)]
|
||||
pub fn [<TRACE_PRINT_ $name>](_data:&mut (dyn core::any::Any+Send+Sync),$($arg:$arg_type),* ){
|
||||
let time = $crate::time::Instant::now();
|
||||
let cpu_id = $crate::arch::cpu::current_cpu_id().data();
|
||||
let current_pid = $crate::process::ProcessManager::current_pcb().pid().data();
|
||||
let format = format!("[{}][{}][{}] {}\n",time,cpu_id,current_pid,$fmt);
|
||||
$crate::debug::tracing::trace_pipe::trace_pipe_push_record(format);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
use super::KernFSInode;
|
||||
use crate::debug::tracing::tracepoint::TracePoint;
|
||||
use crate::{
|
||||
filesystem::{sysfs::SysFSKernPrivateData, vfs::PollStatus},
|
||||
libs::spinlock::SpinLockGuard,
|
||||
@ -6,8 +8,6 @@ use alloc::sync::Arc;
|
||||
use core::fmt::Debug;
|
||||
use system_error::SystemError;
|
||||
|
||||
use super::KernFSInode;
|
||||
|
||||
/// KernFS文件的回调接口
|
||||
///
|
||||
/// 当用户态程序打开、读取、写入、关闭文件时,kernfs会调用相应的回调函数。
|
||||
@ -86,24 +86,23 @@ impl<'a> KernCallbackData<'a> {
|
||||
#[derive(Debug)]
|
||||
pub enum KernInodePrivateData {
|
||||
SysFS(SysFSKernPrivateData),
|
||||
DebugFS(&'static TracePoint),
|
||||
}
|
||||
|
||||
impl KernInodePrivateData {
|
||||
#[inline(always)]
|
||||
pub fn callback_read(&self, buf: &mut [u8], offset: usize) -> Result<usize, SystemError> {
|
||||
match self {
|
||||
KernInodePrivateData::SysFS(private_data) => {
|
||||
return private_data.callback_read(buf, offset);
|
||||
}
|
||||
}
|
||||
return match self {
|
||||
KernInodePrivateData::SysFS(private_data) => private_data.callback_read(buf, offset),
|
||||
_ => Err(SystemError::ENOSYS),
|
||||
};
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn callback_write(&self, buf: &[u8], offset: usize) -> Result<usize, SystemError> {
|
||||
match self {
|
||||
KernInodePrivateData::SysFS(private_data) => {
|
||||
return private_data.callback_write(buf, offset);
|
||||
}
|
||||
}
|
||||
return match self {
|
||||
KernInodePrivateData::SysFS(private_data) => private_data.callback_write(buf, offset),
|
||||
_ => Err(SystemError::ENOSYS),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ use log::{error, info};
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
define_event_trace, define_trace_point,
|
||||
driver::base::block::{gendisk::GenDisk, manager::block_dev_manager},
|
||||
filesystem::{
|
||||
devfs::devfs_init,
|
||||
@ -155,7 +156,7 @@ pub fn mount_root_fs() -> Result<(), SystemError> {
|
||||
let fatfs: Arc<FATFileSystem> = fatfs.unwrap();
|
||||
let r = migrate_virtual_filesystem(fatfs);
|
||||
if r.is_err() {
|
||||
error!("Failed to migrate virtual filesystem to FAT32!");
|
||||
error!("Failed to migrate virtual filesyst em to FAT32!");
|
||||
loop {
|
||||
spin_loop();
|
||||
}
|
||||
@ -165,12 +166,15 @@ pub fn mount_root_fs() -> Result<(), SystemError> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
define_event_trace!(DO_MKDIR_AT,(path:&str,mode:FileMode),
|
||||
format_args!("mkdir at {} with mode {:?}",path, mode));
|
||||
/// @brief 创建文件/文件夹
|
||||
pub fn do_mkdir_at(
|
||||
dirfd: i32,
|
||||
path: &str,
|
||||
mode: FileMode,
|
||||
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
||||
TRACE_DO_MKDIR_AT(path, mode);
|
||||
// debug!("Call do mkdir at");
|
||||
let (mut current_inode, path) =
|
||||
user_path_at(&ProcessManager::current_pcb(), dirfd, path.trim())?;
|
||||
|
Reference in New Issue
Block a user