xref: /DragonOS/tools/debugging/logmonitor/src/backend/mod.rs (revision c635d8a9cfe25bc11779f323ef0c7d7a0f597d4a)
1 use std::{
2     path::PathBuf,
3     sync::{mpsc, Arc, Mutex, RwLock, Weak},
4     thread::JoinHandle,
5 };
6 
7 use log::info;
8 
9 use crate::{command::CommandLineArgs, event::Event};
10 
11 pub mod error;
12 pub mod event;
13 mod loader;
14 mod monitor;
15 
16 #[derive(Debug)]
17 pub struct AppBackend {
18     _command_line_args: CommandLineArgs,
19     _sender_to_frontend: mpsc::Sender<Event>,
20     data: Arc<Mutex<BackendData>>,
21     main_thread: RwLock<Option<std::thread::JoinHandle<()>>>,
22     /// All threads spawned by the backend.(Except the main thread)
23     threads: Mutex<Vec<JoinHandle<()>>>,
24 }
25 
26 impl AppBackend {
27     pub fn new(command_line_args: CommandLineArgs, sender: mpsc::Sender<Event>) -> Arc<Self> {
28         let r = Arc::new(Self {
29             _command_line_args: command_line_args.clone(),
30             _sender_to_frontend: sender.clone(),
31             data: Arc::new(Mutex::new(BackendData::new())),
32             main_thread: RwLock::new(None),
33             threads: Mutex::new(Vec::new()),
34         });
35 
36         r.data.lock().unwrap().kmem_path = Some(PathBuf::from(&command_line_args.kmem));
37 
38         let main_thread = {
39             let cmdargs = command_line_args.clone();
40             let instance = r.clone();
41             let sd = sender.clone();
42             let dt = r.data.clone();
43             std::thread::spawn(move || {
44                 let mut backend = BackendThread::new(cmdargs, sd, Arc::downgrade(&instance), dt);
45                 backend.run_main();
46             })
47         };
48 
49         *r.main_thread.write().unwrap() = Some(main_thread);
50 
51         return r;
52     }
53 }
54 
55 #[derive(Debug)]
56 pub(crate) struct BackendData {
57     kernel_metadata: Option<loader::KernelMetadata>,
58     /// Path to the QEMU shm which contains the kernel memory.
59     kmem_path: Option<PathBuf>,
60 }
61 
62 impl BackendData {
63     pub fn new() -> Self {
64         Self {
65             kernel_metadata: None,
66             kmem_path: None,
67         }
68     }
69 }
70 
71 #[derive(Debug)]
72 pub struct BackendThread {
73     _sender_to_frontend: mpsc::Sender<Event>,
74     command_line_args: CommandLineArgs,
75     shared_data: Arc<Mutex<BackendData>>,
76     backend_instance: Weak<AppBackend>,
77 }
78 
79 impl BackendThread {
80     fn new(
81         command_line_args: CommandLineArgs,
82         sender: mpsc::Sender<Event>,
83         backend_instance: Weak<AppBackend>,
84         backend_data: Arc<Mutex<BackendData>>,
85     ) -> Self {
86         Self {
87             command_line_args,
88             _sender_to_frontend: sender,
89             backend_instance,
90             shared_data: backend_data,
91         }
92     }
93 
94     pub fn run_main(&mut self) {
95         info!("DragonOS Log Monitor started.");
96         self.load_kernel();
97         self.run_mm_monitor();
98         loop {
99             // info!("BackendThread::run()");
100             std::thread::sleep(std::time::Duration::from_secs(1));
101         }
102     }
103 
104     /// 启动内存管理监视器
105     fn run_mm_monitor(&mut self) {
106         info!("run_mm_monitor()");
107         let mm_monitor = monitor::mm::MMLogMonitor::new(self.shared_data.clone());
108         let handle = std::thread::spawn(move || {
109             mm_monitor.run();
110         });
111 
112         self.backend_instance
113             .upgrade()
114             .unwrap()
115             .threads
116             .lock()
117             .unwrap()
118             .push(handle);
119     }
120 
121     /// 加载DragonOS内核并初始化
122     fn load_kernel(&self) {
123         let res = loader::KernelLoader::load(&self.command_line_args.kernel)
124             .expect("Failed to load kernel");
125         self.shared_data.lock().unwrap().kernel_metadata = Some(res);
126     }
127 }
128