200 lines
6.4 KiB
Diff
200 lines
6.4 KiB
Diff
From 714eeceecbe09fd8855cd84279dc13e45a093fb2 Mon Sep 17 00:00:00 2001
|
|
From: chenjiayi <chenjiayi22@huawei.com>
|
|
Date: Thu, 16 Nov 2023 08:07:07 +0800
|
|
Subject: [PATCH 064/103] feature(devmaster): add devctl control subcommand to
|
|
let devmaster exit
|
|
|
|
Also decouple the configuration path into the parameter of run_daemon
|
|
function for unit test.
|
|
---
|
|
exts/devmaster/src/bin/devctl/daemon/mod.rs | 37 ++++++++++++++++++-
|
|
exts/devmaster/src/bin/devctl/main.rs | 19 +++++++++-
|
|
.../src/lib/framework/control_manager.rs | 9 ++++-
|
|
exts/devmaster/src/lib/framework/devmaster.rs | 5 ++-
|
|
4 files changed, 63 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/exts/devmaster/src/bin/devctl/daemon/mod.rs b/exts/devmaster/src/bin/devctl/daemon/mod.rs
|
|
index 6dfe9718..3e4bd96d 100644
|
|
--- a/exts/devmaster/src/bin/devctl/daemon/mod.rs
|
|
+++ b/exts/devmaster/src/bin/devctl/daemon/mod.rs
|
|
@@ -38,10 +38,10 @@ fn notify(unset_env: bool, msg: String) -> std::io::Result<()> {
|
|
}
|
|
}
|
|
|
|
-pub fn run_daemon() {
|
|
+pub fn run_daemon(config_path: &str) {
|
|
let events = Rc::new(Events::new().unwrap());
|
|
|
|
- let devmaster = Devmaster::new(events);
|
|
+ let devmaster = Devmaster::new(config_path, events);
|
|
|
|
if let Err(e) = notify(false, "READY=1\n".to_string()) {
|
|
log::warn!("Failed to notify pid 1: {}", e);
|
|
@@ -51,3 +51,36 @@ pub fn run_daemon() {
|
|
|
|
devmaster.as_ref().borrow().exit();
|
|
}
|
|
+
|
|
+#[cfg(test)]
|
|
+mod test {
|
|
+ use super::*;
|
|
+ use device::{Device, DeviceAction};
|
|
+ use libdevmaster::framework::control_manager::CONTROL_MANAGER_LISTEN_ADDR;
|
|
+ use std::io::Write;
|
|
+
|
|
+ #[test]
|
|
+ fn test_run_daemon() {
|
|
+ /* Require root privilege, skip in ci environment. */
|
|
+ let dev = Device::from_subsystem_sysname("net", "lo").unwrap();
|
|
+ if dev.trigger(DeviceAction::Change).is_err() {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ std::thread::spawn(|| {
|
|
+ std::thread::sleep(std::time::Duration::from_secs(1));
|
|
+
|
|
+ let dev = Device::from_subsystem_sysname("net", "lo").unwrap();
|
|
+ dev.trigger(DeviceAction::Change).unwrap();
|
|
+
|
|
+ /* Sleep more than 3 seconds to wait for the workers being recycled. */
|
|
+ std::thread::sleep(std::time::Duration::from_secs(4));
|
|
+
|
|
+ let mut stream =
|
|
+ std::os::unix::net::UnixStream::connect(CONTROL_MANAGER_LISTEN_ADDR).unwrap();
|
|
+ stream.write_all(b"exit ").unwrap();
|
|
+ });
|
|
+
|
|
+ run_daemon("none");
|
|
+ }
|
|
+}
|
|
diff --git a/exts/devmaster/src/bin/devctl/main.rs b/exts/devmaster/src/bin/devctl/main.rs
|
|
index 17645ee6..8f72285e 100644
|
|
--- a/exts/devmaster/src/bin/devctl/main.rs
|
|
+++ b/exts/devmaster/src/bin/devctl/main.rs
|
|
@@ -18,6 +18,7 @@ mod subcmds;
|
|
use basic::argv_util::invoked_as;
|
|
use clap::Parser;
|
|
use daemon::run_daemon;
|
|
+use libdevmaster::config::devmaster_conf::DEFAULT_CONFIG;
|
|
use libdevmaster::framework::control_manager::CONTROL_MANAGER_LISTEN_ADDR;
|
|
use log::init_log_to_console_syslog;
|
|
use log::Level;
|
|
@@ -204,6 +205,12 @@ enum SubCmd {
|
|
#[clap(short, long)]
|
|
root: Option<String>,
|
|
},
|
|
+ ///
|
|
+ #[clap(display_order = 7)]
|
|
+ Control {
|
|
+ #[clap(short, long)]
|
|
+ exit: bool,
|
|
+ },
|
|
}
|
|
|
|
/// subcommand for killing workers
|
|
@@ -212,10 +219,19 @@ fn subcommand_kill() {
|
|
stream.write_all(b"kill ").unwrap();
|
|
}
|
|
|
|
+/// subcommand for controlling devmaster
|
|
+fn subcommand_control(exit: bool) {
|
|
+ let mut stream = UnixStream::connect(CONTROL_MANAGER_LISTEN_ADDR).unwrap();
|
|
+
|
|
+ if exit {
|
|
+ stream.write_all(b"exit ").unwrap();
|
|
+ }
|
|
+}
|
|
+
|
|
fn main() -> Result<()> {
|
|
let argv: Vec<String> = std::env::args().collect();
|
|
if invoked_as(argv, "devmaster") {
|
|
- run_daemon();
|
|
+ run_daemon(DEFAULT_CONFIG);
|
|
return Ok(());
|
|
}
|
|
|
|
@@ -300,6 +316,7 @@ fn main() -> Result<()> {
|
|
strict,
|
|
root,
|
|
} => subcommand_hwdb(update, test, path, usr, strict, root),
|
|
+ SubCmd::Control { exit } => subcommand_control(exit),
|
|
}
|
|
|
|
Ok(())
|
|
diff --git a/exts/devmaster/src/lib/framework/control_manager.rs b/exts/devmaster/src/lib/framework/control_manager.rs
|
|
index 342c6a0c..d5a5f440 100644
|
|
--- a/exts/devmaster/src/lib/framework/control_manager.rs
|
|
+++ b/exts/devmaster/src/lib/framework/control_manager.rs
|
|
@@ -14,7 +14,7 @@
|
|
//!
|
|
use crate::framework::job_queue::JobQueue;
|
|
use crate::framework::worker_manager::WorkerManager;
|
|
-use event::Source;
|
|
+use event::{Events, Source};
|
|
use nix::unistd::unlink;
|
|
use std::os::unix::net::UnixListener;
|
|
use std::path::Path;
|
|
@@ -38,7 +38,7 @@ pub struct ControlManager {
|
|
worker_manager: Weak<WorkerManager>,
|
|
/// reference to job queue
|
|
_job_queue: Weak<JobQueue>,
|
|
- // events: Rc<Events>,
|
|
+ events: Rc<Events>,
|
|
}
|
|
|
|
/// public methods
|
|
@@ -48,6 +48,7 @@ impl ControlManager {
|
|
listen_addr: String,
|
|
worker_manager: Rc<WorkerManager>,
|
|
job_queue: Rc<JobQueue>,
|
|
+ events: Rc<Events>,
|
|
) -> ControlManager {
|
|
/*
|
|
* Cleanup remaining socket if it exists.
|
|
@@ -67,6 +68,7 @@ impl ControlManager {
|
|
listener,
|
|
worker_manager: Rc::downgrade(&worker_manager),
|
|
_job_queue: Rc::downgrade(&job_queue),
|
|
+ events,
|
|
}
|
|
}
|
|
}
|
|
@@ -83,6 +85,9 @@ impl ControlManager {
|
|
"kill" => {
|
|
self.worker_manager.upgrade().unwrap().kill_workers();
|
|
}
|
|
+ "exit" => {
|
|
+ self.events.set_exit();
|
|
+ }
|
|
_ => {
|
|
todo!();
|
|
}
|
|
diff --git a/exts/devmaster/src/lib/framework/devmaster.rs b/exts/devmaster/src/lib/framework/devmaster.rs
|
|
index 94b93ca0..20735614 100644
|
|
--- a/exts/devmaster/src/lib/framework/devmaster.rs
|
|
+++ b/exts/devmaster/src/lib/framework/devmaster.rs
|
|
@@ -71,10 +71,10 @@ impl Cache {
|
|
|
|
impl Devmaster {
|
|
/// generate a devmaster object
|
|
- pub fn new(events: Rc<Events>) -> Rc<RefCell<Devmaster>> {
|
|
+ pub fn new(config_path: &str, events: Rc<Events>) -> Rc<RefCell<Devmaster>> {
|
|
let config = DevmasterConfig::new();
|
|
|
|
- config.load(DEFAULT_CONFIG);
|
|
+ config.load(config_path);
|
|
|
|
init_log(
|
|
"devmaster",
|
|
@@ -127,6 +127,7 @@ impl Devmaster {
|
|
String::from(CONTROL_MANAGER_LISTEN_ADDR),
|
|
worker_manager.clone(),
|
|
job_queue.clone(),
|
|
+ events.clone(),
|
|
));
|
|
let monitor = Rc::new(UeventMonitor::new(job_queue.clone()));
|
|
let post = Rc::new(GarbageCollect::new(&devmaster));
|
|
--
|
|
2.33.0
|
|
|