|
@@ -1,139 +1,101 @@
|
|
|
-use crate::debug::tracing::tracepoint::{CommonTracePointMeta, TracePoint};
|
|
|
+use alloc::string::ToString;
|
|
|
+
|
|
|
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 crate::tracepoint::*;
|
|
|
use alloc::sync::Arc;
|
|
|
use system_error::SystemError;
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
-pub struct TracingEventsManager {
|
|
|
- root: Arc<KernFSInode>,
|
|
|
- subsystems: SpinLock<BTreeMap<String, Arc<EventsSubsystem>>>,
|
|
|
-}
|
|
|
+struct EnableCallBack;
|
|
|
|
|
|
-impl TracingEventsManager {
|
|
|
- pub fn new(root: Arc<KernFSInode>) -> Self {
|
|
|
- Self {
|
|
|
- root,
|
|
|
- subsystems: SpinLock::new(BTreeMap::new()),
|
|
|
+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> {
|
|
|
+ let pri_data = data.private_data().as_ref().unwrap();
|
|
|
+ let tracepoint_info = pri_data.debugfs_tracepoint().unwrap();
|
|
|
+ let enable_value = tracepoint_info.enable_file().read();
|
|
|
+ if offset >= enable_value.as_bytes().len() {
|
|
|
+ return Ok(0); // Offset is beyond the length of the string
|
|
|
}
|
|
|
+ let len = buf.len().min(enable_value.as_bytes().len() - offset);
|
|
|
+ buf[..len].copy_from_slice(&enable_value.as_bytes()[offset..offset + len]);
|
|
|
+ Ok(len)
|
|
|
}
|
|
|
|
|
|
- /// Create a subsystem by name
|
|
|
- ///
|
|
|
- /// If the subsystem already exists, return the existing subsystem.
|
|
|
- pub fn create_subsystem(
|
|
|
+ fn write(
|
|
|
&self,
|
|
|
- subsystem_name: &str,
|
|
|
- ) -> Result<Arc<EventsSubsystem>, SystemError> {
|
|
|
- if self.subsystems.lock().contains_key(subsystem_name) {
|
|
|
- return Ok(self.get_subsystem(subsystem_name).unwrap());
|
|
|
+ data: KernCallbackData,
|
|
|
+ buf: &[u8],
|
|
|
+ _offset: usize,
|
|
|
+ ) -> Result<usize, SystemError> {
|
|
|
+ let pri_data = data.private_data().as_ref().unwrap();
|
|
|
+ let tracepoint = pri_data.debugfs_tracepoint().unwrap();
|
|
|
+ if buf.is_empty() {
|
|
|
+ return Err(SystemError::EINVAL);
|
|
|
}
|
|
|
- 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)
|
|
|
+ tracepoint.enable_file().write(buf[0] as _);
|
|
|
+ Ok(buf.len())
|
|
|
}
|
|
|
|
|
|
- /// Get the subsystem by name
|
|
|
- pub fn get_subsystem(&self, subsystem_name: &str) -> Option<Arc<EventsSubsystem>> {
|
|
|
- self.subsystems.lock().get(subsystem_name).cloned()
|
|
|
+ fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
|
|
|
+ Err(SystemError::ENOSYS)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
-pub struct EventsSubsystem {
|
|
|
- root: Arc<KernFSInode>,
|
|
|
- events: SpinLock<BTreeMap<String, Arc<EventInfo>>>,
|
|
|
-}
|
|
|
+struct FormatCallBack;
|
|
|
|
|
|
-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);
|
|
|
+impl KernFSCallback for FormatCallBack {
|
|
|
+ fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> {
|
|
|
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()
|
|
|
+ fn read(
|
|
|
+ &self,
|
|
|
+ data: KernCallbackData,
|
|
|
+ buf: &mut [u8],
|
|
|
+ offset: usize,
|
|
|
+ ) -> Result<usize, SystemError> {
|
|
|
+ let pri_data = data.private_data().as_ref().unwrap();
|
|
|
+ let tracepoint = pri_data.debugfs_tracepoint().unwrap();
|
|
|
+ let format_str = tracepoint.format_file().read();
|
|
|
+ if offset >= format_str.as_bytes().len() {
|
|
|
+ return Ok(0); // Offset is beyond the length of the string
|
|
|
+ }
|
|
|
+ let len = buf.len().min(format_str.as_bytes().len() - offset);
|
|
|
+ buf[..len].copy_from_slice(&format_str.as_bytes()[offset..offset + len]);
|
|
|
+ Ok(len)
|
|
|
}
|
|
|
|
|
|
- /// Get the root inode of the subsystem
|
|
|
- pub fn root(&self) -> Arc<KernFSInode> {
|
|
|
- self.root.clone()
|
|
|
+ fn write(
|
|
|
+ &self,
|
|
|
+ _data: KernCallbackData,
|
|
|
+ _buf: &[u8],
|
|
|
+ _offset: usize,
|
|
|
+ ) -> Result<usize, SystemError> {
|
|
|
+ Err(SystemError::EPERM)
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-#[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,
|
|
|
- })
|
|
|
+ fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
|
|
|
+ Err(SystemError::ENOSYS)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl Drop for EventInfo {
|
|
|
- fn drop(&mut self) {}
|
|
|
-}
|
|
|
-
|
|
|
#[derive(Debug)]
|
|
|
-struct EnableCallBack;
|
|
|
-
|
|
|
-impl KernFSCallback for EnableCallBack {
|
|
|
+struct IDCallBack;
|
|
|
+impl KernFSCallback for IDCallBack {
|
|
|
fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> {
|
|
|
Ok(())
|
|
|
}
|
|
@@ -144,55 +106,25 @@ impl KernFSCallback for EnableCallBack {
|
|
|
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);
|
|
|
- }
|
|
|
+ let pri_data = data.private_data().as_ref().unwrap();
|
|
|
+ let tracepoint = pri_data.debugfs_tracepoint().unwrap();
|
|
|
+ let id_str = tracepoint.id_file().read();
|
|
|
+
|
|
|
+ if offset >= id_str.as_bytes().len() {
|
|
|
+ return Ok(0); // Offset is beyond the length of the string
|
|
|
}
|
|
|
+ let len = buf.len().min(id_str.as_bytes().len() - offset);
|
|
|
+ buf[..len].copy_from_slice(&id_str.as_bytes()[offset..offset + len]);
|
|
|
+ Ok(len)
|
|
|
}
|
|
|
|
|
|
fn write(
|
|
|
&self,
|
|
|
- data: KernCallbackData,
|
|
|
- buf: &[u8],
|
|
|
+ _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);
|
|
|
- }
|
|
|
- }
|
|
|
+ Err(SystemError::EPERM)
|
|
|
}
|
|
|
|
|
|
fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
|
|
@@ -202,38 +134,62 @@ impl KernFSCallback for EnableCallBack {
|
|
|
|
|
|
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)?;
|
|
|
+pub fn tracing_events_manager() -> &'static TracingEventsManager {
|
|
|
+ unsafe {
|
|
|
+ TRACING_EVENTS_MANAGER
|
|
|
+ .as_ref()
|
|
|
+ .expect("TracingEventsManager not initialized")
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
+pub fn init_events(root: Arc<KernFSInode>) -> Result<(), SystemError> {
|
|
|
+ let events_manager = crate::tracepoint::global_init_events()?;
|
|
|
+ // Register the global tracing events manager
|
|
|
+ for subsystem_name in events_manager.subsystem_names() {
|
|
|
+ let subsystem = events_manager.get_subsystem(&subsystem_name).unwrap();
|
|
|
+ // Register the subsystem in the root inode
|
|
|
+ let subsystem_inode = root.add_dir(
|
|
|
+ subsystem_name,
|
|
|
+ ModeType::from_bits_truncate(0o755),
|
|
|
+ None,
|
|
|
+ Some(&TracingDirCallBack),
|
|
|
+ )?;
|
|
|
+ for event_name in subsystem.event_names() {
|
|
|
+ let event_info = subsystem.get_event(&event_name).unwrap();
|
|
|
+ let event_inode = subsystem_inode.add_dir(
|
|
|
+ event_name,
|
|
|
+ ModeType::from_bits_truncate(0o755),
|
|
|
+ None,
|
|
|
+ Some(&TracingDirCallBack),
|
|
|
+ )?;
|
|
|
+ // add enable file for the event
|
|
|
+ let _enable_inode = event_inode.add_file(
|
|
|
+ "enable".to_string(),
|
|
|
+ ModeType::from_bits_truncate(0o644),
|
|
|
+ None,
|
|
|
+ Some(KernInodePrivateData::DebugFS(event_info.clone())),
|
|
|
+ Some(&EnableCallBack),
|
|
|
+ )?;
|
|
|
+ // add format file for the event
|
|
|
+ let _format_inode = event_inode.add_file(
|
|
|
+ "format".to_string(),
|
|
|
+ ModeType::from_bits_truncate(0o644),
|
|
|
+ None,
|
|
|
+ Some(KernInodePrivateData::DebugFS(event_info.clone())),
|
|
|
+ Some(&FormatCallBack),
|
|
|
+ )?;
|
|
|
+ // add id file for the event
|
|
|
+ let _id_inode = event_inode.add_file(
|
|
|
+ "id".to_string(),
|
|
|
+ ModeType::from_bits_truncate(0o644),
|
|
|
+ None,
|
|
|
+ Some(KernInodePrivateData::DebugFS(event_info)),
|
|
|
+ Some(&IDCallBack),
|
|
|
+ )?;
|
|
|
+ }
|
|
|
+ }
|
|
|
unsafe {
|
|
|
TRACING_EVENTS_MANAGER = Some(events_manager);
|
|
|
}
|
|
|
-
|
|
|
Ok(())
|
|
|
}
|
|
|
-extern "C" {
|
|
|
- fn _tracepoint();
|
|
|
- fn _etracepoint();
|
|
|
-}
|