From e0c70e5ccae8db1fc5efce725b60cbe3ec320219 Mon Sep 17 00:00:00 2001 From: love_hangzhou Date: Tue, 26 Oct 2021 07:56:15 +0800 Subject: [PATCH] add dynamic load plugin --- src/process1/Cargo.toml | 4 + src/process1/src/lib.rs | 23 +++ src/process1/src/manager/manager.rs | 60 ++++++ src/process1/src/manager/mod.rs | 2 + src/process1/src/manager/unit.rs | 284 ++++++++++++++++++++++++++++ src/process1/src/plugin/mod.rs | 49 ++++- 6 files changed, 420 insertions(+), 2 deletions(-) create mode 100644 src/process1/src/lib.rs create mode 100644 src/process1/src/manager/manager.rs create mode 100644 src/process1/src/manager/mod.rs create mode 100644 src/process1/src/manager/unit.rs diff --git a/src/process1/Cargo.toml b/src/process1/Cargo.toml index b69c2006..03b321d1 100644 --- a/src/process1/Cargo.toml +++ b/src/process1/Cargo.toml @@ -6,4 +6,8 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +path = "src/lib.rs" + [dependencies] +dynamic_reload = "0.4.0" diff --git a/src/process1/src/lib.rs b/src/process1/src/lib.rs new file mode 100644 index 00000000..eca1b3d4 --- /dev/null +++ b/src/process1/src/lib.rs @@ -0,0 +1,23 @@ +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + assert_eq!(2 + 2, 4); + } +} + + + +pub mod front_of_hourse { + pub mod hosting { + pub fn add_to_waitlist(name:String) -> Vec { + let mut result = Vec::new(); + result.push(name); + return result; + } + } +} + +pub mod manager; + +pub mod plugin; \ No newline at end of file diff --git a/src/process1/src/manager/manager.rs b/src/process1/src/manager/manager.rs new file mode 100644 index 00000000..062036af --- /dev/null +++ b/src/process1/src/manager/manager.rs @@ -0,0 +1,60 @@ + + +pub trait Mangerobj { + fn init(&self){ + + } + + fn load(&self); + + fn dispatch(&self) -> i32; + + fn reload(&self) -> Option; + + fn destroy(&self); + + // reserved for sd event + fn event_dispatch(&self) -> Option; +} + + + +pub struct MangerLoader { + pub managers: Vec>, +} + + +impl MangerLoader{ + pub fn new() -> Self{ + MangerLoader{ + managers: Vec::new() + } + } + pub fn load_plugins(&mut self, d: Box) { + self.managers.push(d); + } + + pub fn run(&mut self) -> i32{ + let mut ret:i32 = 0; + for m in self.managers.iter(){ + m.init(); + m.load(); + ret =m.dispatch(); + } + ret + } + + pub fn destroy(&self) { + for m in self.managers.iter(){ + m.destroy(); + } + } + + pub fn reload(&self){ + for m in self.managers.iter(){ + m.reload(); + } + } +} + + diff --git a/src/process1/src/manager/mod.rs b/src/process1/src/manager/mod.rs new file mode 100644 index 00000000..ddcec03e --- /dev/null +++ b/src/process1/src/manager/mod.rs @@ -0,0 +1,2 @@ +pub mod manager; +pub mod unit; \ No newline at end of file diff --git a/src/process1/src/manager/unit.rs b/src/process1/src/manager/unit.rs new file mode 100644 index 00000000..c382bc88 --- /dev/null +++ b/src/process1/src/manager/unit.rs @@ -0,0 +1,284 @@ +use super::manager; +use std::collections::HashSet; +use std::cell::RefCell; +use std::sync::Arc; + +enum UnitType { + UNIT_SERVICE = 0, + UNIT_SOCKET, + UNIT_BUSNAME, + UNIT_TARGET, + UNIT_SNAPSHOT, + UNIT_DEVICE, +} + +enum UnitLoadState { + UNIT_STUB = 0, + UNIT_LOADED, + UNIT_NOT_FOUND, + UNIT_ERROR, + UNIT_MERGED, + UNIT_MASKED, + _UNIT_LOAD_STATE_MAX, + _UNIT_LOAD_STATE_INVALID = -1, +} + +enum UnitDependency { + UNIT_REQUIRES, + UNIT_REQUIRES_OVERRIDABLE, + UNIT_REQUISITE, + UNIT_REQUISITE_OVERRIDABLE, +} + +enum UnitNameFlags { + UNIT_NAME_PLAIN =1, + UNIT_NAME_INSTANCE = 2, + UNIT_NAME_TEMPLATE = 4, + UNIT_NAME_ANY = 1|2|4, +} + +struct Unit { + unit_type: UnitType, + load_state: UnitLoadState, + id: String, + instance: Option, + name: String, + depencies: Vec, + desc: String, + documnetation: String, + fragment_path: String, + source_path: String, + fragment_mtine: u64, + source_mtime: u64, + dropin_mtime: u64, + + units_by_type: Vec, + has_requires_mounts_for: Vec, + load_queue: Vec, + dbus_queue: Vec, + cleanup_queue: Vec, + gc_queue: Vec, + cgroup_queue: Vec, + pids: HashSet, + sigchldgen: u64, + gc_marker: u64, + deseialize_job: i32, + load_error: i32, + stop_when_unneeded: bool, + refuse_manual_start: bool, + allow_isolate: bool, + ignore_on_isolate: bool, + ignore_on_snapshot: bool, + condition_result: bool, + assert_result: bool, + transient: bool, + in_load_queue: bool, + in_dubs_queue: bool, + in_cleanup_queue: bool, + in_gc_queue: bool, + manager: Option>, +} + +pub trait UnitObj { + fn init(&self){} + fn done(&self){} + fn load(&self){} + fn coldplug(&self){} + fn dump(&self){} + fn start(&self){} + fn stop(&self){} + fn reload(&self){} + fn kill(&self){} + fn check_gc(&self)->bool; + fn release_resources(&self){} + fn check_snapshot(&self){} + fn sigchld_events(&self, pid:u64,code:i32, status:i32){} + fn reset_failed(&self){} +} +struct MountUnit { + mount_unit:Unit, +} + +#[macro_export] +macro_rules! null_str{ + ($name:expr) => { + String::from($name) + } +} + +impl Unit { + pub fn new() -> Self { + Unit{ + unit_type: UnitType::UNIT_SERVICE, + load_state: UnitLoadState::UNIT_STUB, + id: String::from(""), + instance: Some(String::from("")), + name: String::from(""), + depencies: Vec::::new(), + desc: String::from(""), + documnetation: null_str!(""), + fragment_path: null_str!(""), + source_path: null_str!(""), + fragment_mtine: 0, + source_mtime: 0, + dropin_mtime: 0, + units_by_type: Vec::::new(), + has_requires_mounts_for: Vec::::new(), + load_queue: Vec::::new(), + dbus_queue: Vec::::new(), + cleanup_queue: Vec::::new(), + gc_queue: Vec::::new(), + cgroup_queue: Vec::::new(), + pids: HashSet::::new(), + sigchldgen: 0, + gc_marker: 0, + deseialize_job: 0, + load_error: 0, + stop_when_unneeded: false, + refuse_manual_start: false, + allow_isolate: false, + ignore_on_isolate: false, + ignore_on_snapshot: false, + condition_result: false, + assert_result: false, + transient: false, + in_load_queue: false, + in_dubs_queue: false, + in_cleanup_queue: false, + in_gc_queue: false, + manager:None, + } + } + pub fn set_manager(&mut self,manger: Option>){ + self.manager = manger; + } +} +/* +impl <'l> Default for Unit<'l> { + fn default() -> Self { + Self{ + unitType: UnitType::UNIT_SERVICE, + load_state: UnitLoadState::UNIT_STUB, + id: String::from(""), + instance: String::from(""), + name: String::from(""), + depencies: Vec::::new(), + desc: String::from(""), + documnetation: null_str!(""), + fragment_path: null_str!(""), + source_path: null_str!(""), + fragment_mtine: 0, + source_mtime: 0, + dropin_mtime: 0, + units_by_type: Vec::::new(), + has_requires_mounts_for: Vec::::new(), + load_queue: Vec::::new(), + dbus_queue: Vec::::new(), + cleanup_queue: Vec::::new(), + gc_queue: Vec::::new(), + cgroup_queue: Vec::::new(), + pids: HashSet::::new(), + sigchldgen: 0, + gc_marker: 0, + deseialize_job: 0, + load_error: 0, + stop_when_unneeded: false, + refuse_manual_start: false, + allow_isolate: false, + ignore_on_isolate: false, + ignore_on_snapshot: false, + condition_result: false, + assert_result: false, + transient: false, + in_load_queue: false, + in_dubs_queue: false, + in_cleanup_queue: false, + in_gc_queue: false, + manager: None, + } + } +} +*/ +impl UnitObj for Unit{ + + fn init(&self){ + + } + fn done(&self){ + + } + fn check_gc(&self) -> bool { todo!() } +} + +impl UnitObj for MountUnit{ + +fn init(&self) { todo!() } +fn done(&self) { todo!() } +fn load(&self) { todo!() } +fn coldplug(&self) { todo!() } +fn start(&self) { todo!() } +fn dump(&self) { todo!() } +fn stop(&self) { todo!() } +fn reload(&self) { todo!() } +fn kill(&self) { todo!() } +fn check_gc(&self) -> bool { todo!() } +fn release_resources(&self) { todo!() } +fn check_snapshot(&self) { todo!() } +fn sigchld_events(&self, _: u64, _: i32, _: i32) { todo!() } +fn reset_failed(&self) { todo!() } +} + + +pub struct UnitManager { + units: RefCell>>>, +} + +impl UnitManager{ + pub fn new() -> Self{ + UnitManager {units: RefCell::new(Vec::new())} + } +} + +impl manager::Mangerobj for UnitManager { + fn init(&self){ + } + + fn load(&self){ + let mut units_vec = self.units.borrow_mut(); + + let unit: Unit = Unit::new(); + + units_vec.push(RefCell::new(Box::new(unit))); + } + + fn dispatch(&self) -> i32 { + 0 + } + + fn reload(&self) -> Option{ + None + } + + fn destroy(&self){ + + } + + // reserved for sd event + fn event_dispatch(&self) -> Option{ + None + } +} + + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_mangerplugin(){ + let unit_manger = UnitManager::new(); + let mut mp = manager::MangerLoader::new(); + mp.load_plugins(Box::new(unit_manger)); + assert_eq!(mp.run(),0); + } +} \ No newline at end of file diff --git a/src/process1/src/plugin/mod.rs b/src/process1/src/plugin/mod.rs index ddcec03e..67753e32 100644 --- a/src/process1/src/plugin/mod.rs +++ b/src/process1/src/plugin/mod.rs @@ -1,2 +1,47 @@ -pub mod manager; -pub mod unit; \ No newline at end of file + +use dynamic_reload; +use std::sync::Arc; +use std::time::Duration; +use std::thread; + +struct LibLoaders{ + libs: Vec>, +} + +impl LibLoaders { + fn add_lib(&mut self, lib: &Arc) { + self.libs.push(lib.clone()); + } + + fn unload_lib(&mut self, lib: &Arc) { + for i in (0..self.libs.len()).rev() { + if &self.libs[i] == lib { + self.libs.swap_remove(i); + } + } + } + fn reload_lib(&mut self,lib:&Arc){ + Self::add_lib(self,lib); + } + + fn reload_callback(&mut self, state:dynamic_reload::UpdateState, lib: Option<&Arc>){ + match state { + dynamic_reload::UpdateState::Before => Self::unload_lib(self,lib.unwrap()), + dynamic_reload::UpdateState::After => Self::reload_lib(self,lib.unwrap()), + dynamic_reload::UpdateState::ReloadFailed(_) =>println!("Reload plugin failed"), + } + } +} + + +pub struct Plugin { + plugin_lists: Vec>, + loader_dir: Option +} + + +impl Plugin { + fn init() { + + } +} \ No newline at end of file -- Gitee