xref: /DragonOS/tools/debugging/logmonitor/src/backend/mod.rs (revision dcf232f378b36fad754799fc121a70cadc8d5cb3)
17b32f508SLoGin use std::{
27b32f508SLoGin     path::PathBuf,
37b32f508SLoGin     sync::{mpsc, Arc, Mutex, RwLock, Weak},
47b32f508SLoGin     thread::JoinHandle,
57b32f508SLoGin };
67b32f508SLoGin 
77b32f508SLoGin use log::info;
87b32f508SLoGin 
97b32f508SLoGin use crate::{command::CommandLineArgs, event::Event};
107b32f508SLoGin 
117b32f508SLoGin pub mod error;
127b32f508SLoGin pub mod event;
137b32f508SLoGin mod loader;
147b32f508SLoGin mod monitor;
157b32f508SLoGin 
167b32f508SLoGin #[derive(Debug)]
177b32f508SLoGin pub struct AppBackend {
187b32f508SLoGin     _command_line_args: CommandLineArgs,
197b32f508SLoGin     _sender_to_frontend: mpsc::Sender<Event>,
207b32f508SLoGin     data: Arc<Mutex<BackendData>>,
217b32f508SLoGin     main_thread: RwLock<Option<std::thread::JoinHandle<()>>>,
227b32f508SLoGin     /// All threads spawned by the backend.(Except the main thread)
237b32f508SLoGin     threads: Mutex<Vec<JoinHandle<()>>>,
247b32f508SLoGin }
257b32f508SLoGin 
267b32f508SLoGin impl AppBackend {
new(command_line_args: CommandLineArgs, sender: mpsc::Sender<Event>) -> Arc<Self>277b32f508SLoGin     pub fn new(command_line_args: CommandLineArgs, sender: mpsc::Sender<Event>) -> Arc<Self> {
287b32f508SLoGin         let r = Arc::new(Self {
297b32f508SLoGin             _command_line_args: command_line_args.clone(),
307b32f508SLoGin             _sender_to_frontend: sender.clone(),
317b32f508SLoGin             data: Arc::new(Mutex::new(BackendData::new())),
327b32f508SLoGin             main_thread: RwLock::new(None),
337b32f508SLoGin             threads: Mutex::new(Vec::new()),
347b32f508SLoGin         });
357b32f508SLoGin 
367b32f508SLoGin         r.data.lock().unwrap().kmem_path = Some(PathBuf::from(&command_line_args.kmem));
377b32f508SLoGin 
387b32f508SLoGin         let main_thread = {
397b32f508SLoGin             let cmdargs = command_line_args.clone();
407b32f508SLoGin             let instance = r.clone();
417b32f508SLoGin             let sd = sender.clone();
427b32f508SLoGin             let dt = r.data.clone();
437b32f508SLoGin             std::thread::spawn(move || {
447b32f508SLoGin                 let mut backend = BackendThread::new(cmdargs, sd, Arc::downgrade(&instance), dt);
457b32f508SLoGin                 backend.run_main();
467b32f508SLoGin             })
477b32f508SLoGin         };
487b32f508SLoGin 
497b32f508SLoGin         *r.main_thread.write().unwrap() = Some(main_thread);
507b32f508SLoGin 
517b32f508SLoGin         return r;
527b32f508SLoGin     }
537b32f508SLoGin }
547b32f508SLoGin 
557b32f508SLoGin #[derive(Debug)]
56*dcf232f3SLoGin pub(crate) struct BackendData {
577b32f508SLoGin     kernel_metadata: Option<loader::KernelMetadata>,
587b32f508SLoGin     /// Path to the QEMU shm which contains the kernel memory.
597b32f508SLoGin     kmem_path: Option<PathBuf>,
607b32f508SLoGin }
617b32f508SLoGin 
627b32f508SLoGin impl BackendData {
new() -> Self637b32f508SLoGin     pub fn new() -> Self {
647b32f508SLoGin         Self {
657b32f508SLoGin             kernel_metadata: None,
667b32f508SLoGin             kmem_path: None,
677b32f508SLoGin         }
687b32f508SLoGin     }
697b32f508SLoGin }
707b32f508SLoGin 
717b32f508SLoGin #[derive(Debug)]
727b32f508SLoGin pub struct BackendThread {
737b32f508SLoGin     _sender_to_frontend: mpsc::Sender<Event>,
747b32f508SLoGin     command_line_args: CommandLineArgs,
757b32f508SLoGin     shared_data: Arc<Mutex<BackendData>>,
767b32f508SLoGin     backend_instance: Weak<AppBackend>,
777b32f508SLoGin }
787b32f508SLoGin 
797b32f508SLoGin impl BackendThread {
new( command_line_args: CommandLineArgs, sender: mpsc::Sender<Event>, backend_instance: Weak<AppBackend>, backend_data: Arc<Mutex<BackendData>>, ) -> Self807b32f508SLoGin     fn new(
817b32f508SLoGin         command_line_args: CommandLineArgs,
827b32f508SLoGin         sender: mpsc::Sender<Event>,
837b32f508SLoGin         backend_instance: Weak<AppBackend>,
847b32f508SLoGin         backend_data: Arc<Mutex<BackendData>>,
857b32f508SLoGin     ) -> Self {
867b32f508SLoGin         Self {
877b32f508SLoGin             command_line_args,
887b32f508SLoGin             _sender_to_frontend: sender,
897b32f508SLoGin             backend_instance,
907b32f508SLoGin             shared_data: backend_data,
917b32f508SLoGin         }
927b32f508SLoGin     }
937b32f508SLoGin 
run_main(&mut self)947b32f508SLoGin     pub fn run_main(&mut self) {
957b32f508SLoGin         info!("DragonOS Log Monitor started.");
967b32f508SLoGin         self.load_kernel();
977b32f508SLoGin         self.run_mm_monitor();
987b32f508SLoGin         loop {
997b32f508SLoGin             // info!("BackendThread::run()");
1007b32f508SLoGin             std::thread::sleep(std::time::Duration::from_secs(1));
1017b32f508SLoGin         }
1027b32f508SLoGin     }
1037b32f508SLoGin 
1047b32f508SLoGin     /// 启动内存管理监视器
run_mm_monitor(&mut self)1057b32f508SLoGin     fn run_mm_monitor(&mut self) {
1067b32f508SLoGin         info!("run_mm_monitor()");
1077b32f508SLoGin         let mm_monitor = monitor::mm::MMLogMonitor::new(self.shared_data.clone());
1087b32f508SLoGin         let handle = std::thread::spawn(move || {
1097b32f508SLoGin             mm_monitor.run();
1107b32f508SLoGin         });
1117b32f508SLoGin 
1127b32f508SLoGin         self.backend_instance
1137b32f508SLoGin             .upgrade()
1147b32f508SLoGin             .unwrap()
1157b32f508SLoGin             .threads
1167b32f508SLoGin             .lock()
1177b32f508SLoGin             .unwrap()
1187b32f508SLoGin             .push(handle);
1197b32f508SLoGin     }
1207b32f508SLoGin 
1217b32f508SLoGin     /// 加载DragonOS内核并初始化
load_kernel(&self)1227b32f508SLoGin     fn load_kernel(&self) {
1237b32f508SLoGin         let res = loader::KernelLoader::load(&self.command_line_args.kernel)
1247b32f508SLoGin             .expect("Failed to load kernel");
1257b32f508SLoGin         self.shared_data.lock().unwrap().kernel_metadata = Some(res);
1267b32f508SLoGin     }
1277b32f508SLoGin }
128