!79 sync patches from upstream
From: @jiayi0118 Reviewed-by: @licunlong Signed-off-by: @licunlong
This commit is contained in:
commit
5ff86c5cd5
1612
backport-feature-add-scsi_id.patch
Normal file
1612
backport-feature-add-scsi_id.patch
Normal file
File diff suppressed because it is too large
Load Diff
1093
backport-feature-devctl-add-devctl-info.patch
Normal file
1093
backport-feature-devctl-add-devctl-info.patch
Normal file
File diff suppressed because it is too large
Load Diff
1343
backport-feature-devmaster-Add-subcommands-for-devctl-trigger.patch
Normal file
1343
backport-feature-devmaster-Add-subcommands-for-devctl-trigger.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,199 @@
|
|||||||
|
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
|
||||||
|
|
||||||
157
backport-fix-Failed-to-devctl-info-dev-or-sys.patch
Normal file
157
backport-fix-Failed-to-devctl-info-dev-or-sys.patch
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
From b5b35912af30bd37d38496af6a28aec5cd27159e Mon Sep 17 00:00:00 2001
|
||||||
|
From: huyubiao <huyubiao@huawei.com>
|
||||||
|
Date: Wed, 8 Nov 2023 06:53:14 +0800
|
||||||
|
Subject: [PATCH 038/103] fix: Failed to devctl info /dev or /sys
|
||||||
|
|
||||||
|
---
|
||||||
|
.../src/bin/devctl/subcmds/devctl_info.rs | 67 ++++++-------------
|
||||||
|
1 file changed, 21 insertions(+), 46 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/bin/devctl/subcmds/devctl_info.rs b/exts/devmaster/src/bin/devctl/subcmds/devctl_info.rs
|
||||||
|
index e18c3898..71c9254d 100644
|
||||||
|
--- a/exts/devmaster/src/bin/devctl/subcmds/devctl_info.rs
|
||||||
|
+++ b/exts/devmaster/src/bin/devctl/subcmds/devctl_info.rs
|
||||||
|
@@ -35,20 +35,6 @@ enum QueryType {
|
||||||
|
All,
|
||||||
|
}
|
||||||
|
|
||||||
|
-struct QueryProperty {
|
||||||
|
- export: bool,
|
||||||
|
- export_prefix: Option<String>,
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-impl QueryProperty {
|
||||||
|
- fn new(export: bool, export_prefix: Option<String>) -> Self {
|
||||||
|
- QueryProperty {
|
||||||
|
- export,
|
||||||
|
- export_prefix,
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
struct SysAttr {
|
||||||
|
name: String,
|
||||||
|
value: String,
|
||||||
|
@@ -96,11 +82,6 @@ impl InfoArgs {
|
||||||
|
pub fn subcommand(&self) -> Result<()> {
|
||||||
|
let mut devs = Vec::new();
|
||||||
|
|
||||||
|
- let mut arg_export = false;
|
||||||
|
- if self.export || self.export_prefix.is_some() {
|
||||||
|
- arg_export = true;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
if self.export_db {
|
||||||
|
return export_devices();
|
||||||
|
}
|
||||||
|
@@ -113,12 +94,9 @@ impl InfoArgs {
|
||||||
|
log::error!("Positional arguments are not allowed with -d/--device-id-of-file.");
|
||||||
|
return Err(nix::Error::EINVAL);
|
||||||
|
}
|
||||||
|
- return self.stat_device(name, arg_export);
|
||||||
|
+ return self.stat_device(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
- let mut query_type = QueryType::All;
|
||||||
|
- self.parse_query_type(&mut query_type)?;
|
||||||
|
-
|
||||||
|
devs.extend(&self.devices);
|
||||||
|
if devs.is_empty() {
|
||||||
|
log::error!("A device name or path is required");
|
||||||
|
@@ -145,43 +123,44 @@ impl InfoArgs {
|
||||||
|
};
|
||||||
|
|
||||||
|
if self.query.is_some() {
|
||||||
|
- let query_property = QueryProperty::new(arg_export, self.export_prefix.clone());
|
||||||
|
- r = self.query_device(&query_type, device, query_property);
|
||||||
|
+ r = self.query_device(device);
|
||||||
|
} else if self.attribute_walk {
|
||||||
|
r = print_device_chain(device);
|
||||||
|
} else {
|
||||||
|
- log::error!("unknown action");
|
||||||
|
- return Err(nix::Error::EINVAL);
|
||||||
|
+ r = self.query_device(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r
|
||||||
|
}
|
||||||
|
|
||||||
|
- fn parse_query_type(&self, query_type: &mut QueryType) -> Result<()> {
|
||||||
|
+ fn is_export(&self) -> bool {
|
||||||
|
+ self.export || self.export_prefix.is_some()
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ fn parse_query_type(&self) -> Result<QueryType> {
|
||||||
|
match &self.query {
|
||||||
|
Some(q) => {
|
||||||
|
if q == "property" || q == "env" {
|
||||||
|
- *query_type = QueryType::Property;
|
||||||
|
+ Ok(QueryType::Property)
|
||||||
|
} else if q == "name" {
|
||||||
|
- *query_type = QueryType::Name;
|
||||||
|
+ Ok(QueryType::Name)
|
||||||
|
} else if q == "symlink" {
|
||||||
|
- *query_type = QueryType::Symlink;
|
||||||
|
+ Ok(QueryType::Symlink)
|
||||||
|
} else if q == "path" {
|
||||||
|
- *query_type = QueryType::Path;
|
||||||
|
+ Ok(QueryType::Path)
|
||||||
|
} else if q == "all" {
|
||||||
|
- *query_type = QueryType::All;
|
||||||
|
+ Ok(QueryType::All)
|
||||||
|
} else {
|
||||||
|
log::error!("unknown query type");
|
||||||
|
- return Err(nix::Error::EINVAL);
|
||||||
|
+ Err(nix::Error::EINVAL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- None => *query_type = QueryType::All,
|
||||||
|
+ None => Ok(QueryType::All),
|
||||||
|
}
|
||||||
|
- Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
- fn stat_device(&self, name: &str, export: bool) -> Result<()> {
|
||||||
|
+ fn stat_device(&self, name: &str) -> Result<()> {
|
||||||
|
let metadata = match fs::metadata(name) {
|
||||||
|
Ok(metadata) => metadata,
|
||||||
|
Err(err) => {
|
||||||
|
@@ -190,7 +169,7 @@ impl InfoArgs {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
- if export {
|
||||||
|
+ if self.is_export() {
|
||||||
|
match &self.export_prefix {
|
||||||
|
Some(p) => {
|
||||||
|
println!("{}MAJOR={}", p, nix::sys::stat::major(metadata.dev()));
|
||||||
|
@@ -212,12 +191,8 @@ impl InfoArgs {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
- fn query_device(
|
||||||
|
- &self,
|
||||||
|
- query: &QueryType,
|
||||||
|
- device: Device,
|
||||||
|
- property: QueryProperty,
|
||||||
|
- ) -> Result<()> {
|
||||||
|
+ fn query_device(&self, device: Device) -> Result<()> {
|
||||||
|
+ let query = self.parse_query_type()?;
|
||||||
|
match query {
|
||||||
|
QueryType::Name => {
|
||||||
|
let node = match device.get_devname() {
|
||||||
|
@@ -275,8 +250,8 @@ impl InfoArgs {
|
||||||
|
}
|
||||||
|
QueryType::Property => {
|
||||||
|
for (key, value) in &device.property_iter() {
|
||||||
|
- if property.export {
|
||||||
|
- match &property.export_prefix {
|
||||||
|
+ if self.is_export() {
|
||||||
|
+ match &self.export_prefix {
|
||||||
|
Some(export_prefix) => println!("{}{}='{}'", export_prefix, key, value),
|
||||||
|
None => println!("{}='{}'", key, value),
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
81
backport-fix-basic-complete-feature-dependencies.patch
Normal file
81
backport-fix-basic-complete-feature-dependencies.patch
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
From 241471ed8d54b769831fc383075233df967a897a Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Wed, 8 Nov 2023 02:09:09 +0800
|
||||||
|
Subject: [PATCH 045/103] fix(basic): complete feature dependencies
|
||||||
|
|
||||||
|
uuid depends on random.
|
||||||
|
|
||||||
|
random depends on io.
|
||||||
|
|
||||||
|
Also add get_errno method for basic Error.
|
||||||
|
---
|
||||||
|
libs/basic/Cargo.toml | 4 ++--
|
||||||
|
libs/basic/src/error.rs | 36 ++++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 38 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libs/basic/Cargo.toml b/libs/basic/Cargo.toml
|
||||||
|
index f7c84157..654c1a3b 100644
|
||||||
|
--- a/libs/basic/Cargo.toml
|
||||||
|
+++ b/libs/basic/Cargo.toml
|
||||||
|
@@ -111,9 +111,9 @@ string = []
|
||||||
|
sysfs = ["nix/dir"]
|
||||||
|
unistd = ["nix/user"]
|
||||||
|
unit_name = []
|
||||||
|
-uuid = ["bitflags"]
|
||||||
|
+uuid = ["bitflags", "random"]
|
||||||
|
murmurhash2 = []
|
||||||
|
strbuf = []
|
||||||
|
argv = []
|
||||||
|
exec_util = []
|
||||||
|
-random = []
|
||||||
|
+random = ["io"]
|
||||||
|
diff --git a/libs/basic/src/error.rs b/libs/basic/src/error.rs
|
||||||
|
index aead8ce7..d138f477 100644
|
||||||
|
--- a/libs/basic/src/error.rs
|
||||||
|
+++ b/libs/basic/src/error.rs
|
||||||
|
@@ -70,6 +70,42 @@ pub enum Error {
|
||||||
|
Other { msg: String },
|
||||||
|
}
|
||||||
|
|
||||||
|
+impl Error {
|
||||||
|
+ /// Translate the basic error to error number.
|
||||||
|
+ pub fn get_errno(&self) -> i32 {
|
||||||
|
+ match self {
|
||||||
|
+ Self::Syscall {
|
||||||
|
+ syscall: _,
|
||||||
|
+ ret: _,
|
||||||
|
+ errno,
|
||||||
|
+ } => *errno,
|
||||||
|
+ Error::Io { source } => source.raw_os_error().unwrap_or_default(),
|
||||||
|
+ Error::Caps { what: _ } => nix::errno::Errno::EINVAL as i32,
|
||||||
|
+ Error::Nix { source } => *source as i32,
|
||||||
|
+ Error::Var { source } => {
|
||||||
|
+ (match source {
|
||||||
|
+ std::env::VarError::NotPresent => nix::errno::Errno::ENOENT,
|
||||||
|
+ std::env::VarError::NotUnicode(_) => nix::errno::Errno::EINVAL,
|
||||||
|
+ }) as i32
|
||||||
|
+ }
|
||||||
|
+ Error::Proc { source } => match source {
|
||||||
|
+ procfs::ProcError::Incomplete(_) => nix::errno::Errno::EINVAL as i32,
|
||||||
|
+ procfs::ProcError::PermissionDenied(_) => nix::errno::Errno::EPERM as i32,
|
||||||
|
+ procfs::ProcError::NotFound(_) => nix::errno::Errno::ENOENT as i32,
|
||||||
|
+ procfs::ProcError::Io(_, _) => nix::errno::Errno::EIO as i32,
|
||||||
|
+ procfs::ProcError::Other(_) => nix::errno::Errno::EINVAL as i32,
|
||||||
|
+ procfs::ProcError::InternalError(_) => nix::errno::Errno::EINVAL as i32,
|
||||||
|
+ },
|
||||||
|
+ Error::NulError { source: _ } => nix::errno::Errno::EINVAL as i32,
|
||||||
|
+ Error::Parse { source: _ } => nix::errno::Errno::EINVAL as i32,
|
||||||
|
+ Error::ParseNamingScheme { what: _ } => nix::errno::Errno::EINVAL as i32,
|
||||||
|
+ Error::NotExisted { what: _ } => nix::errno::Errno::ENOENT as i32,
|
||||||
|
+ Error::Invalid { what: _ } => nix::errno::Errno::EINVAL as i32,
|
||||||
|
+ Error::Other { msg: _ } => nix::errno::Errno::EINVAL as i32,
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#[allow(unused_macros)]
|
||||||
|
macro_rules! errfrom {
|
||||||
|
($($st:ty),* => $variant:ident) => (
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
From 9af6528c348feab7c463a0710f6dacc8ac57db95 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Wed, 8 Nov 2023 05:17:04 +0800
|
||||||
|
Subject: [PATCH 048/103] fix(basic): use feature to control procfs compilation
|
||||||
|
in get_errno
|
||||||
|
|
||||||
|
---
|
||||||
|
libs/basic/src/error.rs | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/libs/basic/src/error.rs b/libs/basic/src/error.rs
|
||||||
|
index d138f477..89ac5a3e 100644
|
||||||
|
--- a/libs/basic/src/error.rs
|
||||||
|
+++ b/libs/basic/src/error.rs
|
||||||
|
@@ -88,6 +88,7 @@ impl Error {
|
||||||
|
std::env::VarError::NotUnicode(_) => nix::errno::Errno::EINVAL,
|
||||||
|
}) as i32
|
||||||
|
}
|
||||||
|
+ #[cfg(feature = "process")]
|
||||||
|
Error::Proc { source } => match source {
|
||||||
|
procfs::ProcError::Incomplete(_) => nix::errno::Errno::EINVAL as i32,
|
||||||
|
procfs::ProcError::PermissionDenied(_) => nix::errno::Errno::EPERM as i32,
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,86 @@
|
|||||||
|
From a71d702d98d090eb0bc68fa7950a590967de8716 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Thu, 23 Nov 2023 14:23:46 +0800
|
||||||
|
Subject: [PATCH 082/103] fix(device): avoid panic on shallow clone when
|
||||||
|
subsystem is not available
|
||||||
|
|
||||||
|
Some special sysfs device, such as /sys/devices/platform, may not contain
|
||||||
|
available subsystem. This leads to panic in shallow cloning such device
|
||||||
|
object when getting its subsystem.
|
||||||
|
---
|
||||||
|
libs/device/src/device.rs | 51 ++++++++++++++++++++++++---------------
|
||||||
|
1 files changed, 32 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libs/device/src/device.rs b/libs/device/src/device.rs
|
||||||
|
index e8e2dcc5..a9cb196c 100644
|
||||||
|
--- a/libs/device/src/device.rs
|
||||||
|
+++ b/libs/device/src/device.rs
|
||||||
|
@@ -2396,14 +2396,15 @@ impl Device {
|
||||||
|
|
||||||
|
device.set_syspath(&syspath, false)?;
|
||||||
|
|
||||||
|
- let subsystem = self.get_subsystem()?;
|
||||||
|
+ /* Some devices, such as /sys/devices/platform, do not have subsystem. */
|
||||||
|
+ if let Ok(subsystem) = self.get_subsystem() {
|
||||||
|
+ device.set_subsystem(&subsystem);
|
||||||
|
|
||||||
|
- device.set_subsystem(&subsystem);
|
||||||
|
-
|
||||||
|
- if subsystem == "drivers" {
|
||||||
|
- device
|
||||||
|
- .driver_subsystem
|
||||||
|
- .replace(self.driver_subsystem.borrow().clone());
|
||||||
|
+ if subsystem == "drivers" {
|
||||||
|
+ device
|
||||||
|
+ .driver_subsystem
|
||||||
|
+ .replace(self.driver_subsystem.borrow().clone());
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(ifindex) = self.get_property_value("IFINDEX") {
|
||||||
|
@@ -3506,19 +3507,31 @@ mod tests {
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_shallow_clone() {
|
||||||
|
- #[inline]
|
||||||
|
- fn inner_test(dev: &mut Device) -> Result<(), Error> {
|
||||||
|
- let s1 = dev.get_syspath().unwrap();
|
||||||
|
-
|
||||||
|
- let dev_clone = dev.shallow_clone().unwrap();
|
||||||
|
-
|
||||||
|
- assert_eq!(s1, dev_clone.get_syspath().unwrap());
|
||||||
|
-
|
||||||
|
- Ok(())
|
||||||
|
- }
|
||||||
|
+ /* Enumerator merely collect devices with valid subsystems,
|
||||||
|
+ * while get_parent method may not, e.g., /sys/devices/platform.
|
||||||
|
+ */
|
||||||
|
+ let mut e = DeviceEnumerator::new();
|
||||||
|
+ e.set_enumerator_type(DeviceEnumerationType::All);
|
||||||
|
+
|
||||||
|
+ for mut dev in e.iter() {
|
||||||
|
+ let dev_clone = dev.borrow().shallow_clone().unwrap();
|
||||||
|
+ dev_clone.get_syspath().unwrap();
|
||||||
|
+ dev_clone.get_subsystem().unwrap();
|
||||||
|
+
|
||||||
|
+ loop {
|
||||||
|
+ let ret = dev.borrow().get_parent();
|
||||||
|
+
|
||||||
|
+ if let Ok(parent) = ret {
|
||||||
|
+ parent.borrow().get_syspath().unwrap();
|
||||||
|
+ if let Err(e) = parent.borrow().get_subsystem() {
|
||||||
|
+ assert_eq!(e.get_errno(), Errno::ENOENT);
|
||||||
|
+ }
|
||||||
|
+ dev = parent;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if let Err(e) = LoopDev::inner_process("/tmp/test_shallow_clone", 1024 * 10, inner_test) {
|
||||||
|
- assert!(e.is_errno(nix::Error::EACCES) || e.is_errno(nix::Error::EBUSY));
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
2.33.0
|
||||||
|
|
||||||
35
backport-fix-device-cleanup-temporary-tag-files.patch
Normal file
35
backport-fix-device-cleanup-temporary-tag-files.patch
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
From 23a1923d6ef767e1f49a18129e515a67bf4ff70c Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Tue, 14 Nov 2023 22:35:01 +0800
|
||||||
|
Subject: [PATCH 060/103] fix(device): cleanup temporary tag files
|
||||||
|
|
||||||
|
Also make a tiny change to optimize the doc conmments.
|
||||||
|
---
|
||||||
|
libs/device/src/device.rs | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/libs/device/src/device.rs b/libs/device/src/device.rs
|
||||||
|
index 6a43be82..70070c72 100644
|
||||||
|
--- a/libs/device/src/device.rs
|
||||||
|
+++ b/libs/device/src/device.rs
|
||||||
|
@@ -2774,7 +2774,7 @@ impl Device {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the devlink iterator
|
||||||
|
- ///
|
||||||
|
+ ///
|
||||||
|
/// The device object will try to load devlinks from db firstly.
|
||||||
|
pub fn devlink_iter(&self) -> HashSetRefWrapper<String> {
|
||||||
|
let _ = self.read_db();
|
||||||
|
@@ -3452,6 +3452,8 @@ mod tests {
|
||||||
|
|
||||||
|
dev.cleanup_tags();
|
||||||
|
|
||||||
|
+ fs::remove_dir_all("/tmp/devmaster").unwrap();
|
||||||
|
+
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,96 @@
|
|||||||
|
From ed46964df74ff592f39295fe20d083b144089310 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Tue, 14 Nov 2023 17:14:36 +0800
|
||||||
|
Subject: [PATCH 059/103] fix(device): drop unnecessary error throwing out
|
||||||
|
|
||||||
|
In some device methods, the device object should prepare inner data by reading
|
||||||
|
database, but it tolerates failure.
|
||||||
|
---
|
||||||
|
libs/device/src/device.rs | 43 +++++++++++++--------------------------
|
||||||
|
1 file changed, 14 insertions(+), 29 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libs/device/src/device.rs b/libs/device/src/device.rs
|
||||||
|
index 3845e21c..6a43be82 100644
|
||||||
|
--- a/libs/device/src/device.rs
|
||||||
|
+++ b/libs/device/src/device.rs
|
||||||
|
@@ -955,14 +955,14 @@ impl Device {
|
||||||
|
|
||||||
|
/// check whether the device has the tag
|
||||||
|
pub fn has_tag(&self, tag: &str) -> Result<bool, Error> {
|
||||||
|
- self.read_db()?;
|
||||||
|
+ let _ = self.read_db();
|
||||||
|
|
||||||
|
Ok(self.all_tags.borrow().contains(tag))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// check whether the device has the current tag
|
||||||
|
pub fn has_current_tag(&self, tag: &str) -> Result<bool, Error> {
|
||||||
|
- self.read_db()?;
|
||||||
|
+ let _ = self.read_db();
|
||||||
|
|
||||||
|
Ok(self.current_tags.borrow().contains(tag))
|
||||||
|
}
|
||||||
|
@@ -2751,48 +2751,33 @@ impl<'a, 'b: 'a, K: 'a, V: 'a> IntoIterator for &'b HashMapRefWrapper<'a, K, V>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Device {
|
||||||
|
- /// return the tag iterator
|
||||||
|
+ /// Return the tag iterator.
|
||||||
|
+ ///
|
||||||
|
+ /// The device object will try to load tags from db firstly.
|
||||||
|
pub fn tag_iter(&self) -> HashSetRefWrapper<String> {
|
||||||
|
- if let Err(e) = self.read_db() {
|
||||||
|
- log::debug!(
|
||||||
|
- "failed to read db of '{}': {}",
|
||||||
|
- self.get_device_id()
|
||||||
|
- .unwrap_or_else(|_| self.devpath.borrow().clone()),
|
||||||
|
- e
|
||||||
|
- )
|
||||||
|
- }
|
||||||
|
+ let _ = self.read_db();
|
||||||
|
|
||||||
|
HashSetRefWrapper {
|
||||||
|
r: self.all_tags.borrow(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- /// return the current tag iterator
|
||||||
|
+ /// Return the current tag iterator.
|
||||||
|
+ ///
|
||||||
|
+ /// The device object will try to load tags from db firstly.
|
||||||
|
pub fn current_tag_iter(&self) -> HashSetRefWrapper<String> {
|
||||||
|
- if let Err(e) = self.read_db() {
|
||||||
|
- log::error!(
|
||||||
|
- "failed to read db of '{}': {}",
|
||||||
|
- self.get_device_id()
|
||||||
|
- .unwrap_or_else(|_| self.devpath.borrow().clone()),
|
||||||
|
- e
|
||||||
|
- )
|
||||||
|
- }
|
||||||
|
+ let _ = self.read_db();
|
||||||
|
|
||||||
|
HashSetRefWrapper {
|
||||||
|
r: self.current_tags.borrow(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- /// return the tag iterator
|
||||||
|
+ /// Return the devlink iterator
|
||||||
|
+ ///
|
||||||
|
+ /// The device object will try to load devlinks from db firstly.
|
||||||
|
pub fn devlink_iter(&self) -> HashSetRefWrapper<String> {
|
||||||
|
- if let Err(e) = self.read_db() {
|
||||||
|
- log::debug!(
|
||||||
|
- "failed to read db of '{}': {}",
|
||||||
|
- self.get_device_id()
|
||||||
|
- .unwrap_or_else(|_| self.devpath.borrow().clone()),
|
||||||
|
- e
|
||||||
|
- )
|
||||||
|
- }
|
||||||
|
+ let _ = self.read_db();
|
||||||
|
|
||||||
|
HashSetRefWrapper {
|
||||||
|
r: self.devlinks.borrow(),
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
75
backport-fix-device-fix-UT-privilege-error-in-ci.patch
Normal file
75
backport-fix-device-fix-UT-privilege-error-in-ci.patch
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
From f5299cda3a36ea68d248835db6733bbd14fd25cc Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Wed, 8 Nov 2023 16:55:29 +0800
|
||||||
|
Subject: [PATCH 051/103] fix(device): fix UT privilege error in ci
|
||||||
|
|
||||||
|
The user in ci has limited privileges, which will prevent actions
|
||||||
|
like writing some device sysattrs.
|
||||||
|
---
|
||||||
|
libs/device/src/device.rs | 23 ++++++++++++++---------
|
||||||
|
1 file changed, 14 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libs/device/src/device.rs b/libs/device/src/device.rs
|
||||||
|
index 284cd6e9..4f5779ce 100644
|
||||||
|
--- a/libs/device/src/device.rs
|
||||||
|
+++ b/libs/device/src/device.rs
|
||||||
|
@@ -3626,7 +3626,7 @@ G:devmaster
|
||||||
|
Q:devmaster
|
||||||
|
V:100
|
||||||
|
";
|
||||||
|
- touch_file("/tmp/tmp_db", false, None, None, None).unwrap();
|
||||||
|
+ touch_file("/tmp/tmp_db", false, Some(0o777), None, None).unwrap();
|
||||||
|
let mut f = OpenOptions::new().write(true).open("/tmp/tmp_db").unwrap();
|
||||||
|
f.write_all(content.as_bytes()).unwrap();
|
||||||
|
let device = Device::new();
|
||||||
|
@@ -3675,19 +3675,22 @@ V:100
|
||||||
|
}
|
||||||
|
|
||||||
|
unlink("/tmp/tmp_db").unwrap();
|
||||||
|
+ unlink("/tmp/tmp_db_writeonly").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_set_is_initialized() {
|
||||||
|
let device = Device::from_subsystem_sysname("net", "lo").unwrap();
|
||||||
|
device.set_is_initialized();
|
||||||
|
- device
|
||||||
|
+ if device
|
||||||
|
.trigger_with_uuid(DeviceAction::Change, false)
|
||||||
|
- .unwrap();
|
||||||
|
- device
|
||||||
|
- .trigger_with_uuid(DeviceAction::Change, true)
|
||||||
|
- .unwrap();
|
||||||
|
- device.trigger(DeviceAction::Change).unwrap();
|
||||||
|
+ .is_ok()
|
||||||
|
+ {
|
||||||
|
+ device
|
||||||
|
+ .trigger_with_uuid(DeviceAction::Change, true)
|
||||||
|
+ .unwrap();
|
||||||
|
+ device.trigger(DeviceAction::Change).unwrap();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
@@ -3707,14 +3710,16 @@ V:100
|
||||||
|
device.set_devmode("666").unwrap();
|
||||||
|
device.set_diskseq("1").unwrap();
|
||||||
|
device.set_action_from_string("change").unwrap();
|
||||||
|
- device.set_sysattr_value("ifalias", Some("test")).unwrap();
|
||||||
|
+
|
||||||
|
+ if device.set_sysattr_value("ifalias", Some("test")).is_ok() {
|
||||||
|
+ assert_eq!(&device.get_cached_sysattr_value("ifalias").unwrap(), "test");
|
||||||
|
+ }
|
||||||
|
|
||||||
|
assert_eq!(&device.get_property_value("DEVUID").unwrap(), "1");
|
||||||
|
assert_eq!(&device.get_property_value("DEVGID").unwrap(), "1");
|
||||||
|
assert_eq!(&device.get_property_value("DEVMODE").unwrap(), "666");
|
||||||
|
assert_eq!(&device.get_property_value("DISKSEQ").unwrap(), "1");
|
||||||
|
assert_eq!(&device.get_property_value("ACTION").unwrap(), "change");
|
||||||
|
- assert_eq!(&device.get_cached_sysattr_value("ifalias").unwrap(), "test");
|
||||||
|
|
||||||
|
assert!(device.set_devuid("invalid").is_err());
|
||||||
|
assert!(device.set_devgid("invalid").is_err());
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
From 6188872fbc38cd38a3f2e909d9b4fe27473a8f67 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Tue, 21 Nov 2023 20:06:29 +0800
|
||||||
|
Subject: [PATCH 078/103] fix(device): keep consistent on the base path for db
|
||||||
|
cloned device object
|
||||||
|
|
||||||
|
The db cloned device object should collect data from the same base path with
|
||||||
|
the original device object.
|
||||||
|
---
|
||||||
|
libs/device/src/device.rs | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/libs/device/src/device.rs b/libs/device/src/device.rs
|
||||||
|
index b8507fe0..e8e2dcc5 100644
|
||||||
|
--- a/libs/device/src/device.rs
|
||||||
|
+++ b/libs/device/src/device.rs
|
||||||
|
@@ -2390,6 +2390,8 @@ impl Device {
|
||||||
|
pub fn shallow_clone(&self) -> Result<Device, Error> {
|
||||||
|
let device = Self::default();
|
||||||
|
|
||||||
|
+ device.set_base_path(self.base_path.borrow().as_str());
|
||||||
|
+
|
||||||
|
let syspath = self.get_syspath()?;
|
||||||
|
|
||||||
|
device.set_syspath(&syspath, false)?;
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
From 7c4bfcad52d1e8b2de7c6c2d5bfc1c08b401341f Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Wed, 8 Nov 2023 02:10:37 +0800
|
||||||
|
Subject: [PATCH 046/103] fix(device): replenish feature dependency of uuid on
|
||||||
|
basic crate
|
||||||
|
|
||||||
|
uuid is used on trigger_with_uuid method.
|
||||||
|
---
|
||||||
|
libs/device/Cargo.toml | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/libs/device/Cargo.toml b/libs/device/Cargo.toml
|
||||||
|
index 6af6a404..ecb9955c 100644
|
||||||
|
--- a/libs/device/Cargo.toml
|
||||||
|
+++ b/libs/device/Cargo.toml
|
||||||
|
@@ -12,6 +12,7 @@ basic = { path = "../basic", default-features = false, features = [
|
||||||
|
"fs",
|
||||||
|
"fd",
|
||||||
|
"murmurhash2",
|
||||||
|
+ "uuid",
|
||||||
|
] }
|
||||||
|
event = { path = "../event" }
|
||||||
|
log = { path = "../log" }
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,92 @@
|
|||||||
|
From 400c6e270583c62724dd2bfd8b92ad96a2f0cfcb Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Wed, 8 Nov 2023 22:59:44 +0800
|
||||||
|
Subject: [PATCH 053/103] fix(device): set driver subsystem after generating
|
||||||
|
device from nulstr
|
||||||
|
|
||||||
|
The driver subsystem is omitted when receiving device object from nulstr,
|
||||||
|
which leads to incorrect device id in /run/devmaster/data/ for driver
|
||||||
|
subsystems.
|
||||||
|
---
|
||||||
|
libs/device/src/device.rs | 32 ++++++++++++++++++++++++++++---
|
||||||
|
libs/device/src/device_monitor.rs | 5 +++--
|
||||||
|
2 files changed, 32 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libs/device/src/device.rs b/libs/device/src/device.rs
|
||||||
|
index 4f5779ce..3845e21c 100644
|
||||||
|
--- a/libs/device/src/device.rs
|
||||||
|
+++ b/libs/device/src/device.rs
|
||||||
|
@@ -246,7 +246,29 @@ impl Device {
|
||||||
|
|
||||||
|
device.update_properties_bufs()?;
|
||||||
|
|
||||||
|
- Ok(device)
|
||||||
|
+ device.verify()
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /// Verify the legality of a device object from nulstr.
|
||||||
|
+ fn verify(self) -> Result<Device, Error> {
|
||||||
|
+ if self.devpath.borrow().is_empty()
|
||||||
|
+ || self.subsystem.borrow().is_empty()
|
||||||
|
+ || *self.action.borrow() == DeviceAction::Invalid
|
||||||
|
+ || *self.seqnum.borrow() == 0
|
||||||
|
+ {
|
||||||
|
+ return Err(Error::Nix {
|
||||||
|
+ msg: "Received invalid device object from uevent".to_string(),
|
||||||
|
+ source: Errno::EINVAL,
|
||||||
|
+ });
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if &*self.subsystem.borrow() == "drivers" {
|
||||||
|
+ self.set_drivers_subsystem()?;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ self.sealed.replace(true);
|
||||||
|
+
|
||||||
|
+ Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// create a Device instance from devname
|
||||||
|
@@ -1237,7 +1259,7 @@ impl Device {
|
||||||
|
/// shadow clone a device object and import properties from db
|
||||||
|
pub fn clone_with_db(&self) -> Result<Device, Error> {
|
||||||
|
let device = self.shallow_clone()?;
|
||||||
|
- device.read_db()?;
|
||||||
|
+ device.read_db_internal(true)?;
|
||||||
|
device.sealed.replace(true);
|
||||||
|
Ok(device)
|
||||||
|
}
|
||||||
|
@@ -3535,9 +3557,13 @@ mod tests {
|
||||||
|
let syspath = dev.get_syspath().unwrap();
|
||||||
|
let devnum = dev.get_devnum().unwrap();
|
||||||
|
let id = dev.get_device_id().unwrap();
|
||||||
|
- let (nulstr, _) = dev.get_properties_nulstr().unwrap();
|
||||||
|
let devname = dev.get_devname().unwrap();
|
||||||
|
|
||||||
|
+ dev.set_action_from_string("change").unwrap();
|
||||||
|
+ dev.set_seqnum_from_string("1000").unwrap();
|
||||||
|
+
|
||||||
|
+ let (nulstr, _) = dev.get_properties_nulstr().unwrap();
|
||||||
|
+
|
||||||
|
let dev_new = Device::from_syspath(&syspath, true).unwrap();
|
||||||
|
assert_eq!(dev, &dev_new);
|
||||||
|
|
||||||
|
diff --git a/libs/device/src/device_monitor.rs b/libs/device/src/device_monitor.rs
|
||||||
|
index db51c40f..3f1d1ba6 100644
|
||||||
|
--- a/libs/device/src/device_monitor.rs
|
||||||
|
+++ b/libs/device/src/device_monitor.rs
|
||||||
|
@@ -249,8 +249,9 @@ mod tests {
|
||||||
|
|
||||||
|
///
|
||||||
|
fn dispatch(&self, e: &Events) -> i32 {
|
||||||
|
- let device = self.device_monitor.receive_device().unwrap();
|
||||||
|
- println!("{}", device.get_device_id().unwrap());
|
||||||
|
+ if let Ok(device) = self.device_monitor.receive_device() {
|
||||||
|
+ println!("{}", device.get_device_id().unwrap());
|
||||||
|
+ }
|
||||||
|
e.set_exit();
|
||||||
|
0
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,138 @@
|
|||||||
|
From 19d481dbf79337924cb0a389cb2e073e80ce5495 Mon Sep 17 00:00:00 2001
|
||||||
|
From: root <root@localhost.localdomain>
|
||||||
|
Date: Wed, 6 Dec 2023 20:53:59 +0800
|
||||||
|
Subject: [PATCH 1/1] loopdev
|
||||||
|
|
||||||
|
---
|
||||||
|
Cargo.lock | 1 +
|
||||||
|
exts/devmaster/Cargo.toml | 5 ++++-
|
||||||
|
libs/device/Cargo.toml | 6 ++++--
|
||||||
|
libs/device/src/device.rs | 9 +++++----
|
||||||
|
libs/device/src/utils.rs | 9 +++++++--
|
||||||
|
5 files changed, 21 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Cargo.lock b/Cargo.lock
|
||||||
|
index f103489..616a69c 100644
|
||||||
|
--- a/Cargo.lock
|
||||||
|
+++ b/Cargo.lock
|
||||||
|
@@ -378,6 +378,7 @@ version = "0.5.1"
|
||||||
|
dependencies = [
|
||||||
|
"basic",
|
||||||
|
"bitflags",
|
||||||
|
+ "device",
|
||||||
|
"event",
|
||||||
|
"fnmatch-sys",
|
||||||
|
"libc",
|
||||||
|
diff --git a/exts/devmaster/Cargo.toml b/exts/devmaster/Cargo.toml
|
||||||
|
index c52e988..f9f2961 100644
|
||||||
|
--- a/exts/devmaster/Cargo.toml
|
||||||
|
+++ b/exts/devmaster/Cargo.toml
|
||||||
|
@@ -34,7 +34,7 @@ basic = { path = "../../libs/basic", default-features = false, features = [
|
||||||
|
"argv",
|
||||||
|
] }
|
||||||
|
blkid_rs = { path = "../../libs/blkid_rs" }
|
||||||
|
-device = { path = "../../libs/device" }
|
||||||
|
+device = { path = "../../libs/device", default-features = false }
|
||||||
|
event = { path = "../../libs/event" }
|
||||||
|
input_event_codes_rs = { path = "../../libs/input_event_codes_rs" }
|
||||||
|
kmod_rs = { path = "../../libs/kmod_rs" }
|
||||||
|
@@ -78,3 +78,6 @@ fnmatch-sys = "1.0.0"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
basic = { path = "../../libs/basic", features = ["cargo"] }
|
||||||
|
+
|
||||||
|
+[dev-dependencies]
|
||||||
|
+device = { path = "../../libs/device", features = ["loopdev"] }
|
||||||
|
diff --git a/libs/device/Cargo.toml b/libs/device/Cargo.toml
|
||||||
|
index ecb9955..1737c17 100644
|
||||||
|
--- a/libs/device/Cargo.toml
|
||||||
|
+++ b/libs/device/Cargo.toml
|
||||||
|
@@ -20,8 +20,7 @@ log = { path = "../log" }
|
||||||
|
# third libraries
|
||||||
|
bitflags = "1.3.2"
|
||||||
|
libc = { default-features = false, version = "0.2.140" }
|
||||||
|
-# only used in test case
|
||||||
|
-loopdev = "0.4.0"
|
||||||
|
+loopdev = { version = "0.4.0", optional = true } # only used in test case
|
||||||
|
nix = { default-features = false, version = "0.24", features = [
|
||||||
|
"ioctl",
|
||||||
|
"user",
|
||||||
|
@@ -32,3 +31,6 @@ nix = { default-features = false, version = "0.24", features = [
|
||||||
|
] }
|
||||||
|
snafu = { default-features = false, version = "0.7" }
|
||||||
|
fnmatch-sys = "1.0.0"
|
||||||
|
+
|
||||||
|
+[dev-dependencies]
|
||||||
|
+device = { path = ".", features = ["loopdev"] }
|
||||||
|
diff --git a/libs/device/src/device.rs b/libs/device/src/device.rs
|
||||||
|
index d1ab230..c11de5b 100644
|
||||||
|
--- a/libs/device/src/device.rs
|
||||||
|
+++ b/libs/device/src/device.rs
|
||||||
|
@@ -2845,16 +2845,17 @@ impl PartialEq for Device {
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
- use std::fs::OpenOptions;
|
||||||
|
- use std::panic::catch_unwind;
|
||||||
|
-
|
||||||
|
use crate::{
|
||||||
|
device::*,
|
||||||
|
device_enumerator::{DeviceEnumerationType, DeviceEnumerator},
|
||||||
|
- utils::LoopDev,
|
||||||
|
};
|
||||||
|
use basic::IN_SET;
|
||||||
|
use libc::S_IFBLK;
|
||||||
|
+ use std::fs::OpenOptions;
|
||||||
|
+ use std::panic::catch_unwind;
|
||||||
|
+
|
||||||
|
+ #[cfg(feature = "loopdev")]
|
||||||
|
+ use crate::utils::LoopDev;
|
||||||
|
|
||||||
|
fn compare(dev1: &Device, dev2: &Device) -> bool {
|
||||||
|
let syspath_1 = dev1.get_syspath().unwrap();
|
||||||
|
diff --git a/libs/device/src/utils.rs b/libs/device/src/utils.rs
|
||||||
|
index df750ed..2b814fa 100644
|
||||||
|
--- a/libs/device/src/utils.rs
|
||||||
|
+++ b/libs/device/src/utils.rs
|
||||||
|
@@ -11,12 +11,14 @@
|
||||||
|
// See the Mulan PSL v2 for more details.
|
||||||
|
|
||||||
|
//! utilities for device operation
|
||||||
|
+use crate::{error::*, Device};
|
||||||
|
use nix::errno::Errno;
|
||||||
|
+use std::{cmp::Ordering, fmt::Debug, fs::DirEntry, path::Path};
|
||||||
|
|
||||||
|
-use crate::{error::*, Device};
|
||||||
|
+#[cfg(feature = "loopdev")]
|
||||||
|
use loopdev::*;
|
||||||
|
+#[cfg(feature = "loopdev")]
|
||||||
|
use std::path::PathBuf;
|
||||||
|
-use std::{cmp::Ordering, fmt::Debug, fs::DirEntry, path::Path};
|
||||||
|
|
||||||
|
/// compare sound device
|
||||||
|
pub(crate) fn sound_device_compare(devpath_a: &str, devpath_b: &str) -> Ordering {
|
||||||
|
@@ -106,11 +108,13 @@ pub(crate) fn readlink_value<P: AsRef<Path> + Debug>(path: P) -> Result<String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// loop device
|
||||||
|
+#[cfg(feature = "loopdev")]
|
||||||
|
pub struct LoopDev {
|
||||||
|
tmpfile: String,
|
||||||
|
lodev: LoopDevice,
|
||||||
|
}
|
||||||
|
|
||||||
|
+#[cfg(feature = "loopdev")]
|
||||||
|
impl LoopDev {
|
||||||
|
/// create a temporate file with specific size
|
||||||
|
#[allow(dead_code)]
|
||||||
|
@@ -194,6 +198,7 @@ impl LoopDev {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+#[cfg(feature = "loopdev")]
|
||||||
|
impl Drop for LoopDev {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let _ = self.lodev.detach();
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
From 912387598bfaac6ad8a58e1810844daa27e0781e Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Fri, 17 Nov 2023 07:44:31 +0800
|
||||||
|
Subject: [PATCH 071/103] fix(devmaster): CONST can only take arch or virt as
|
||||||
|
attribute
|
||||||
|
|
||||||
|
The inverse operator '!' is missed previously.
|
||||||
|
---
|
||||||
|
exts/devmaster/src/lib/rules/rules_load.rs | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/rules/rules_load.rs b/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
index eee77e63..57ff19ac 100644
|
||||||
|
--- a/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
@@ -832,7 +832,7 @@ impl RuleToken {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"CONST" => {
|
||||||
|
- if attr.is_none() || matches!(attr.as_ref().unwrap().as_str(), "arch" | "virt") {
|
||||||
|
+ if attr.is_none() || !matches!(attr.as_ref().unwrap().as_str(), "arch" | "virt") {
|
||||||
|
return Err(Error::RulesLoadError {
|
||||||
|
msg: "Key 'CONST' has invalid attribute.".location(&context),
|
||||||
|
});
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,97 @@
|
|||||||
|
From 26a93ec411098bf29fa8ebe9b84940f8c9455423 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Tue, 31 Oct 2023 20:24:30 +0800
|
||||||
|
Subject: [PATCH 014/103] fix(devmaster): adjust temporary file permissions
|
||||||
|
|
||||||
|
Adjust temporary file permissions.
|
||||||
|
---
|
||||||
|
exts/devmaster/src/lib/rules/node.rs | 10 +++++++++-
|
||||||
|
libs/device/src/device.rs | 22 +++++++++++++++++++---
|
||||||
|
2 files changed, 28 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/rules/node.rs b/exts/devmaster/src/lib/rules/node.rs
|
||||||
|
index 45b8b36b..9fba906e 100644
|
||||||
|
--- a/exts/devmaster/src/lib/rules/node.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/rules/node.rs
|
||||||
|
@@ -33,7 +33,7 @@
|
||||||
|
//! directory, the directory will be removed.
|
||||||
|
|
||||||
|
use crate::{error::*, log_dev, log_dev_option};
|
||||||
|
-use basic::fs_util::path_simplify;
|
||||||
|
+use basic::fs_util::{chmod, path_simplify};
|
||||||
|
use basic::fs_util::{fchmod_and_chown, futimens_opath, symlink};
|
||||||
|
use basic::{fd_util::xopendirat, fs_util::remove_dir_until};
|
||||||
|
use cluFlock::ExclusiveFlock;
|
||||||
|
@@ -355,6 +355,14 @@ pub(crate) fn open_prior_dir(symlink: &str) -> Result<(Dir, File)> {
|
||||||
|
})
|
||||||
|
.log_error(&format!("failed to create directory all '{}'", dirname))?;
|
||||||
|
|
||||||
|
+ if let Err(e) = chmod(dirname.as_str(), 0o750) {
|
||||||
|
+ log::error!("Failed to set permission for {}: {}", &dirname, e);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if let Err(e) = chmod("/run/devmaster/links", 0o750) {
|
||||||
|
+ log::error!("Failed to set permission for /run/devmaster/links: {}", e);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
let dir = nix::dir::Dir::from_fd(
|
||||||
|
nix::fcntl::open(
|
||||||
|
dirname.as_str(),
|
||||||
|
diff --git a/libs/device/src/device.rs b/libs/device/src/device.rs
|
||||||
|
index 5b1eff1f..5a95e0f5 100644
|
||||||
|
--- a/libs/device/src/device.rs
|
||||||
|
+++ b/libs/device/src/device.rs
|
||||||
|
@@ -15,7 +15,7 @@
|
||||||
|
use crate::err_wrapper;
|
||||||
|
use crate::utils::readlink_value;
|
||||||
|
use crate::{error::*, DeviceAction};
|
||||||
|
-use basic::fs_util::{open_temporary, touch_file};
|
||||||
|
+use basic::fs_util::{chmod, open_temporary, touch_file};
|
||||||
|
use basic::parse::{device_path_parse_devnum, parse_devnum, parse_ifindex};
|
||||||
|
use libc::{
|
||||||
|
dev_t, faccessat, gid_t, mode_t, uid_t, F_OK, S_IFBLK, S_IFCHR, S_IFDIR, S_IFLNK, S_IFMT,
|
||||||
|
@@ -1532,6 +1532,10 @@ impl Device {
|
||||||
|
.map_or_else(|| nix::Error::EIO, nix::Error::from_i32),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
+ if let Err(e) = chmod(DB_BASE_DIR, 0o750) {
|
||||||
|
+ log::error!("Failed to set permission for /run/devmaster/data/: {}", e);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
let (mut file, tmp_file) = open_temporary(&db_path).map_err(|e| {
|
||||||
|
let errno = match e {
|
||||||
|
basic::error::Error::Nix { source } => source,
|
||||||
|
@@ -1546,9 +1550,9 @@ impl Device {
|
||||||
|
fchmod(
|
||||||
|
file.as_raw_fd(),
|
||||||
|
if *self.db_persist.borrow() {
|
||||||
|
- Mode::from_bits(0o1644).unwrap()
|
||||||
|
+ Mode::from_bits(0o1640).unwrap()
|
||||||
|
} else {
|
||||||
|
- Mode::from_bits(0o644).unwrap()
|
||||||
|
+ Mode::from_bits(0o640).unwrap()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
@@ -1697,6 +1701,18 @@ impl Device {
|
||||||
|
source: nix::Error::EINVAL,
|
||||||
|
})?;
|
||||||
|
|
||||||
|
+ if let Err(e) = chmod(TAGS_BASE_DIR, 0o750) {
|
||||||
|
+ log::error!("Failed to set permission for {}: {}", TAGS_BASE_DIR, e);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if let Err(e) = chmod(&format!("{}{}", TAGS_BASE_DIR, tag), 0o750) {
|
||||||
|
+ log::error!(
|
||||||
|
+ "Failed to set permission for {}: {}",
|
||||||
|
+ format!("{}{}", TAGS_BASE_DIR, tag),
|
||||||
|
+ e
|
||||||
|
+ );
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
27
backport-fix-devmaster-append-zero-to-the-file-name.patch
Normal file
27
backport-fix-devmaster-append-zero-to-the-file-name.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From 498398f0b59824726a9bc0bbc4c53af5c8b7b4a2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Thu, 2 Nov 2023 18:14:40 +0800
|
||||||
|
Subject: [PATCH 021/103] fix(devmaster): append zero to the file name
|
||||||
|
|
||||||
|
The file name is transferred to 'faccessat', which should be a C
|
||||||
|
like string that ends with zero.
|
||||||
|
---
|
||||||
|
exts/devmaster/src/lib/builtin/net_id.rs | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/builtin/net_id.rs b/exts/devmaster/src/lib/builtin/net_id.rs
|
||||||
|
index 2b2cc59b..e5f1faa6 100644
|
||||||
|
--- a/exts/devmaster/src/lib/builtin/net_id.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/builtin/net_id.rs
|
||||||
|
@@ -401,7 +401,7 @@ fn parse_hotplug_slot_from_function_id(
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- let filename = format!("{:08}", function_id);
|
||||||
|
+ let filename = format!("{:08}\0", function_id);
|
||||||
|
|
||||||
|
if unsafe { faccessat(slots_dirfd, filename.as_ptr() as *const c_char, F_OK, 0) } < 0 {
|
||||||
|
log_dev!(
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
265
backport-fix-devmaster-avoid-potential-test-case-failures.patch
Normal file
265
backport-fix-devmaster-avoid-potential-test-case-failures.patch
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
From ecab786d75eaf3ab6a110f1d6b47c1b1d7e2ec01 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Tue, 21 Nov 2023 15:17:23 +0800
|
||||||
|
Subject: [PATCH 076/103] fix(devmaster): avoid potential test case failures
|
||||||
|
|
||||||
|
Sharing the same temporary rules directory in multiple test cases
|
||||||
|
may lead to weird and occasional failures.
|
||||||
|
---
|
||||||
|
exts/devmaster/src/lib/rules/rules_load.rs | 123 ++++++++++++---------
|
||||||
|
1 file changed, 69 insertions(+), 54 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/rules/rules_load.rs b/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
index e9dd2259..999c9692 100644
|
||||||
|
--- a/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
@@ -1736,14 +1736,24 @@ mod tests {
|
||||||
|
use std::panic::catch_unwind;
|
||||||
|
use std::{fs, path::Path};
|
||||||
|
|
||||||
|
- fn create_tmp_rules(dir: &'static str, file: &str, content: &str) {
|
||||||
|
+ fn create_tmp_rules(dir: &'static str, file: &str, content: &str, truncate: bool) {
|
||||||
|
assert!(fs::create_dir_all(dir).is_ok());
|
||||||
|
- assert!(fs::write(format!("{}/{}", dir, file), content,).is_ok());
|
||||||
|
+ let s = format!("{}/{}", dir, file);
|
||||||
|
+ let p = Path::new(&s);
|
||||||
|
+ assert!(fs::write(p, content,).is_ok());
|
||||||
|
+ let mut f = fs::OpenOptions::new()
|
||||||
|
+ .write(true)
|
||||||
|
+ .truncate(truncate)
|
||||||
|
+ .open(p)
|
||||||
|
+ .unwrap();
|
||||||
|
+ f.write_all(content.as_bytes()).unwrap();
|
||||||
|
+ f.flush().unwrap();
|
||||||
|
+ while !p.exists() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_tmp_rules(dir: &'static str) {
|
||||||
|
if Path::new(dir).exists() {
|
||||||
|
- assert!(fs::remove_dir_all(dir).is_ok());
|
||||||
|
+ fs::remove_dir_all(dir).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1758,7 +1768,7 @@ mod tests {
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
- clear_tmp_rules("/tmp/devmaster/rules");
|
||||||
|
+ clear_tmp_rules("/tmp/devmaster/test_load_rules");
|
||||||
|
|
||||||
|
let legal_rule = vec![
|
||||||
|
"ACTION == \"change\", SYMLINK += \"test1\"", // Test legal rules.
|
||||||
|
@@ -1810,23 +1820,21 @@ mod tests {
|
||||||
|
"SECLABEL{x}:=\"$hello\"", // Illegal placeholder in value will throw warning rather than panic.
|
||||||
|
];
|
||||||
|
|
||||||
|
- create_tmp_rules("/tmp/devmaster/rules", "00-test.rules", "");
|
||||||
|
-
|
||||||
|
for &content in legal_rule.iter() {
|
||||||
|
- let mut f = fs::OpenOptions::new()
|
||||||
|
- .write(true)
|
||||||
|
- .truncate(true)
|
||||||
|
- .open("/tmp/devmaster/rules/00-test.rules")
|
||||||
|
- .unwrap();
|
||||||
|
- f.write_all(content.as_bytes()).unwrap();
|
||||||
|
+ create_tmp_rules(
|
||||||
|
+ "/tmp/devmaster/test_load_rules",
|
||||||
|
+ "00-test.rules",
|
||||||
|
+ content,
|
||||||
|
+ true,
|
||||||
|
+ );
|
||||||
|
|
||||||
|
let _ = Rules::load_rules(
|
||||||
|
- vec!["/tmp/devmaster/rules".to_string()],
|
||||||
|
+ vec!["/tmp/devmaster/test_load_rules".to_string()],
|
||||||
|
ResolveNameTime::Early,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
- clear_tmp_rules("/tmp/devmaster/rules");
|
||||||
|
+ clear_tmp_rules("/tmp/devmaster/test_load_rules");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
@@ -1840,7 +1848,7 @@ mod tests {
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
- clear_tmp_rules("/tmp/devmaster/rules");
|
||||||
|
+ clear_tmp_rules("/tmp/devmaster/test_load_rules_panic");
|
||||||
|
|
||||||
|
let illegal_rule = vec![
|
||||||
|
"action==\"change\"", // Error in State::Pre
|
||||||
|
@@ -1945,26 +1953,24 @@ mod tests {
|
||||||
|
"XXX=\"xxx\"", // Invalid token key.
|
||||||
|
];
|
||||||
|
|
||||||
|
- create_tmp_rules("/tmp/devmaster/rules", "00-test.rules", "");
|
||||||
|
-
|
||||||
|
for content in illegal_rule.iter() {
|
||||||
|
- let mut f = fs::OpenOptions::new()
|
||||||
|
- .write(true)
|
||||||
|
- .truncate(true)
|
||||||
|
- .open("/tmp/devmaster/rules/00-test.rules")
|
||||||
|
- .unwrap();
|
||||||
|
- f.write_all(content.as_bytes()).unwrap();
|
||||||
|
+ create_tmp_rules(
|
||||||
|
+ "/tmp/devmaster/test_load_rules_panic",
|
||||||
|
+ "00-test.rules",
|
||||||
|
+ content,
|
||||||
|
+ true,
|
||||||
|
+ );
|
||||||
|
|
||||||
|
assert!(catch_unwind(|| {
|
||||||
|
let _ = Rules::load_rules(
|
||||||
|
- vec!["/tmp/devmaster/rules".to_string()],
|
||||||
|
+ vec!["/tmp/devmaster/test_load_rules_panic".to_string()],
|
||||||
|
ResolveNameTime::Early,
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
- clear_tmp_rules("/tmp/devmaster/rules");
|
||||||
|
+ clear_tmp_rules("/tmp/devmaster/test_load_rules_panic");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
@@ -1978,50 +1984,48 @@ mod tests {
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
- clear_tmp_rules("/tmp/devmaster/rules");
|
||||||
|
+ clear_tmp_rules("/tmp/devmaster/test_resolve_name_time");
|
||||||
|
|
||||||
|
let legal = vec!["OWNER=\"root\"", "GROUP=\"root\""];
|
||||||
|
let illegal = vec!["OWNER=\"xxxx\"", "GROUP=\"xxxx\""];
|
||||||
|
|
||||||
|
- create_tmp_rules("/tmp/devmaster/rules", "00-test.rules", "");
|
||||||
|
-
|
||||||
|
for &content in legal.iter() {
|
||||||
|
- let mut f = fs::OpenOptions::new()
|
||||||
|
- .write(true)
|
||||||
|
- .truncate(true)
|
||||||
|
- .open("/tmp/devmaster/rules/00-test.rules")
|
||||||
|
- .unwrap();
|
||||||
|
- f.write_all(content.as_bytes()).unwrap();
|
||||||
|
+ create_tmp_rules(
|
||||||
|
+ "/tmp/devmaster/test_resolve_name_time",
|
||||||
|
+ "00-test.rules",
|
||||||
|
+ content,
|
||||||
|
+ true,
|
||||||
|
+ );
|
||||||
|
|
||||||
|
let _ = Rules::load_rules(
|
||||||
|
- vec!["/tmp/devmaster/rules".to_string()],
|
||||||
|
+ vec!["/tmp/devmaster/test_resolve_name_time".to_string()],
|
||||||
|
ResolveNameTime::Early,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for &content in illegal.iter() {
|
||||||
|
- let mut f = fs::OpenOptions::new()
|
||||||
|
- .write(true)
|
||||||
|
- .truncate(true)
|
||||||
|
- .open("/tmp/devmaster/rules/00-test.rules")
|
||||||
|
- .unwrap();
|
||||||
|
- f.write_all(content.as_bytes()).unwrap();
|
||||||
|
+ create_tmp_rules(
|
||||||
|
+ "/tmp/devmaster/test_resolve_name_time",
|
||||||
|
+ "00-test.rules",
|
||||||
|
+ content,
|
||||||
|
+ true,
|
||||||
|
+ );
|
||||||
|
|
||||||
|
let _ = Rules::load_rules(
|
||||||
|
- vec!["/tmp/devmaster/rules".to_string()],
|
||||||
|
+ vec!["/tmp/devmaster/test_resolve_name_time".to_string()],
|
||||||
|
ResolveNameTime::Late,
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(catch_unwind(|| {
|
||||||
|
let _ = Rules::load_rules(
|
||||||
|
- vec!["/tmp/devmaster/rules".to_string()],
|
||||||
|
+ vec!["/tmp/devmaster/test_resolve_name_time".to_string()],
|
||||||
|
ResolveNameTime::Early,
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
- clear_tmp_rules("/tmp/devmaster/rules");
|
||||||
|
+ clear_tmp_rules("/tmp/devmaster/test_resolve_name_time");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
@@ -2330,11 +2334,11 @@ mod tests {
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_rules() {
|
||||||
|
- create_dir_all("/tmp/devmaster/rules").unwrap();
|
||||||
|
+ create_dir_all("/tmp/devmaster/test_parse_rules").unwrap();
|
||||||
|
|
||||||
|
/* Normal rule file. */
|
||||||
|
touch_file(
|
||||||
|
- "/tmp/devmaster/rules/00-a.rules",
|
||||||
|
+ "/tmp/devmaster/test_parse_rules/00-a.rules",
|
||||||
|
false,
|
||||||
|
Some(0o777),
|
||||||
|
None,
|
||||||
|
@@ -2342,10 +2346,17 @@ mod tests {
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
/* Skip parsing the file with invalid suffix. */
|
||||||
|
- touch_file("/tmp/devmaster/rules/01-b", false, Some(0o777), None, None).unwrap();
|
||||||
|
+ touch_file(
|
||||||
|
+ "/tmp/devmaster/test_parse_rules/01-b",
|
||||||
|
+ false,
|
||||||
|
+ Some(0o777),
|
||||||
|
+ None,
|
||||||
|
+ None,
|
||||||
|
+ )
|
||||||
|
+ .unwrap();
|
||||||
|
/* Failed to parse the file as it is not readable. */
|
||||||
|
touch_file(
|
||||||
|
- "/tmp/devmaster/rules/02-c.rules",
|
||||||
|
+ "/tmp/devmaster/test_parse_rules/02-c.rules",
|
||||||
|
false,
|
||||||
|
Some(0o000),
|
||||||
|
None,
|
||||||
|
@@ -2354,21 +2365,25 @@ mod tests {
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let rules = Arc::new(RwLock::new(Rules::new(
|
||||||
|
- vec!["/tmp/devmaster/rules".to_string()],
|
||||||
|
+ vec!["/tmp/devmaster/test_parse_rules".to_string()],
|
||||||
|
ResolveNameTime::Never,
|
||||||
|
)));
|
||||||
|
|
||||||
|
- // Rules::parse_rules(Arc::new(RwLock::new(rules)));
|
||||||
|
-
|
||||||
|
- RuleFile::load_file("/tmp/devmaster/rules/00-a.rules".to_string(), rules.clone());
|
||||||
|
+ RuleFile::load_file(
|
||||||
|
+ "/tmp/devmaster/test_parse_rules/00-a.rules".to_string(),
|
||||||
|
+ rules.clone(),
|
||||||
|
+ );
|
||||||
|
|
||||||
|
if nix::unistd::getuid().as_raw() != 0 {
|
||||||
|
assert!(catch_unwind(|| {
|
||||||
|
- RuleFile::load_file("/tmp/devmaster/rules/02-c.rules".to_string(), rules.clone());
|
||||||
|
+ RuleFile::load_file(
|
||||||
|
+ "/tmp/devmaster/test_parse_rules/02-c.rules".to_string(),
|
||||||
|
+ rules.clone(),
|
||||||
|
+ );
|
||||||
|
})
|
||||||
|
.is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
- remove_dir_all("/tmp/devmaster").unwrap();
|
||||||
|
+ remove_dir_all("/tmp/devmaster/test_parse_rules").unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
64
backport-fix-devmaster-cache-the-parsed-user-and-group.patch
Normal file
64
backport-fix-devmaster-cache-the-parsed-user-and-group.patch
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
From 0ee8078d05e8fd67251b20383fc5b3cf04aedfb1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Fri, 17 Nov 2023 01:20:21 +0800
|
||||||
|
Subject: [PATCH 069/103] fix(devmaster): cache the parsed user and group
|
||||||
|
|
||||||
|
The previously parsed user and group should be cached to avoid repeatedly
|
||||||
|
parsed later. Also fix and open the corresponding test case that is ignored
|
||||||
|
previously.
|
||||||
|
---
|
||||||
|
exts/devmaster/src/lib/rules/rules_load.rs | 21 ++++++++++++++-------
|
||||||
|
1 file changed, 14 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/rules/rules_load.rs b/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
index 19b7aaa4..a4535b52 100644
|
||||||
|
--- a/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
@@ -133,7 +133,10 @@ impl Rules {
|
||||||
|
|
||||||
|
match User::from_name(username) {
|
||||||
|
Ok(user) => match user {
|
||||||
|
- Some(u) => Ok(u),
|
||||||
|
+ Some(u) => {
|
||||||
|
+ self.users.insert(username.to_string(), u.clone());
|
||||||
|
+ Ok(u)
|
||||||
|
+ }
|
||||||
|
None => Err(Error::RulesLoadError {
|
||||||
|
msg: format!("The user name {} has no credential.", username),
|
||||||
|
}),
|
||||||
|
@@ -152,7 +155,10 @@ impl Rules {
|
||||||
|
|
||||||
|
match Group::from_name(groupname) {
|
||||||
|
Ok(group) => match group {
|
||||||
|
- Some(g) => Ok(g),
|
||||||
|
+ Some(g) => {
|
||||||
|
+ self.groups.insert(groupname.to_string(), g.clone());
|
||||||
|
+ Ok(g)
|
||||||
|
+ }
|
||||||
|
None => Err(Error::RulesLoadError {
|
||||||
|
msg: format!("The group name {} has no credential.", groupname),
|
||||||
|
}),
|
||||||
|
@@ -1983,14 +1989,15 @@ SYMLINK += \"test111111\"",
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
- #[ignore]
|
||||||
|
- fn test_resolve_user() {
|
||||||
|
+ fn test_resolve_user_group() {
|
||||||
|
let mut rules = Rules::new(vec![], ResolveNameTime::Early);
|
||||||
|
- assert!(rules.resolve_user("tss").is_ok());
|
||||||
|
assert!(rules.resolve_user("root").is_ok());
|
||||||
|
- assert!(rules.users.contains_key("tss"));
|
||||||
|
assert!(rules.users.contains_key("root"));
|
||||||
|
- assert!(rules.resolve_user("cjy").is_err());
|
||||||
|
+ assert!(rules.resolve_user("abcdefg").is_err());
|
||||||
|
+
|
||||||
|
+ assert!(rules.resolve_group("root").is_ok());
|
||||||
|
+ assert!(rules.groups.contains_key("root"));
|
||||||
|
+ assert!(rules.resolve_group("abcdefg").is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,123 @@
|
|||||||
|
From f923eda87854adb2d245f43ba3656b0fb46fe7c1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Fri, 3 Nov 2023 01:47:16 +0800
|
||||||
|
Subject: [PATCH 028/103] fix(devmaster): check the validity of kmod context
|
||||||
|
during new method
|
||||||
|
|
||||||
|
The kmod_sys::kmod_new may return a null pointer. Check the validity
|
||||||
|
of the pointer before using it to constuct the kmod instance.
|
||||||
|
---
|
||||||
|
exts/devmaster/src/lib/builtin/kmod.rs | 21 +++++++++++++++++----
|
||||||
|
libs/kmod_rs/src/lib.rs | 17 ++++++++---------
|
||||||
|
2 files changed, 25 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/builtin/kmod.rs b/exts/devmaster/src/lib/builtin/kmod.rs
|
||||||
|
index ac73d1bb..cf718d41 100644
|
||||||
|
--- a/exts/devmaster/src/lib/builtin/kmod.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/builtin/kmod.rs
|
||||||
|
@@ -24,14 +24,14 @@ use std::rc::Rc;
|
||||||
|
/// kmod builtin command
|
||||||
|
pub(crate) struct Kmod {
|
||||||
|
/// kmod struct
|
||||||
|
- kernel_module: Rc<RefCell<kmod_rs::LibKmod>>,
|
||||||
|
+ kernel_module: Option<Rc<RefCell<kmod_rs::LibKmod>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Kmod {
|
||||||
|
/// create Kmod
|
||||||
|
pub(crate) fn new() -> Kmod {
|
||||||
|
Kmod {
|
||||||
|
- kernel_module: Rc::new(RefCell::new(kmod_rs::LibKmod::new())),
|
||||||
|
+ kernel_module: kmod_rs::LibKmod::new().map(|inner| Rc::new(RefCell::new(inner))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -53,7 +53,8 @@ impl Builtin for Kmod {
|
||||||
|
) -> Result<bool> {
|
||||||
|
let device = exec_unit.get_device();
|
||||||
|
|
||||||
|
- if self.kernel_module.borrow().is_ctx_null() {
|
||||||
|
+ if self.kernel_module.is_none() {
|
||||||
|
+ log::error!("Kmod context is not loaded.");
|
||||||
|
return Ok(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -72,6 +73,8 @@ impl Builtin for Kmod {
|
||||||
|
if !modalias.is_empty() {
|
||||||
|
if let Err(e) = self
|
||||||
|
.kernel_module
|
||||||
|
+ .as_ref()
|
||||||
|
+ .unwrap()
|
||||||
|
.borrow_mut()
|
||||||
|
.module_load_and_warn(&modalias, false)
|
||||||
|
{
|
||||||
|
@@ -82,6 +85,8 @@ impl Builtin for Kmod {
|
||||||
|
for i in 2..argc {
|
||||||
|
if let Err(e) = self
|
||||||
|
.kernel_module
|
||||||
|
+ .as_ref()
|
||||||
|
+ .unwrap()
|
||||||
|
.borrow_mut()
|
||||||
|
.module_load_and_warn(&argv[i as usize], false)
|
||||||
|
{
|
||||||
|
@@ -94,7 +99,13 @@ impl Builtin for Kmod {
|
||||||
|
|
||||||
|
/// builtin init function
|
||||||
|
fn init(&self) {
|
||||||
|
- if let Err(e) = self.kernel_module.borrow_mut().load_resources() {
|
||||||
|
+ if let Err(e) = self
|
||||||
|
+ .kernel_module
|
||||||
|
+ .as_ref()
|
||||||
|
+ .unwrap()
|
||||||
|
+ .borrow_mut()
|
||||||
|
+ .load_resources()
|
||||||
|
+ {
|
||||||
|
log::error!("Load resources failed! {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -105,6 +116,8 @@ impl Builtin for Kmod {
|
||||||
|
/// check whether builtin command should reload
|
||||||
|
fn should_reload(&self) -> bool {
|
||||||
|
self.kernel_module
|
||||||
|
+ .as_ref()
|
||||||
|
+ .unwrap()
|
||||||
|
.borrow_mut()
|
||||||
|
.validate_resources()
|
||||||
|
.map_or(false, |e| {
|
||||||
|
diff --git a/libs/kmod_rs/src/lib.rs b/libs/kmod_rs/src/lib.rs
|
||||||
|
index d0efabc5..f95cd32a 100644
|
||||||
|
--- a/libs/kmod_rs/src/lib.rs
|
||||||
|
+++ b/libs/kmod_rs/src/lib.rs
|
||||||
|
@@ -73,21 +73,20 @@ impl Drop for LibKmod {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-impl Default for LibKmod {
|
||||||
|
- fn default() -> Self {
|
||||||
|
- Self::new()
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
impl LibKmod {
|
||||||
|
/// Create libkmod
|
||||||
|
- pub fn new() -> LibKmod {
|
||||||
|
+ pub fn new() -> Option<LibKmod> {
|
||||||
|
let c = unsafe { kmod_sys::kmod_new(std::ptr::null(), std::ptr::null()) };
|
||||||
|
- LibKmod {
|
||||||
|
+
|
||||||
|
+ if c.is_null() {
|
||||||
|
+ return None;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ Some(LibKmod {
|
||||||
|
ctx: c,
|
||||||
|
kmod_list_head: ptr::null::<kmod_sys::kmod_list>() as *mut kmod_sys::kmod_list,
|
||||||
|
module: ptr::null::<kmod_sys::kmod_module>() as *mut kmod_sys::kmod_module,
|
||||||
|
- }
|
||||||
|
+ })
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create KmodListIter with internal members
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
From adf0de497132a30577cd38c6a9e0079c5224c279 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Fri, 17 Nov 2023 06:12:36 +0800
|
||||||
|
Subject: [PATCH 070/103] fix(devmaster): drop incorrect preventation on
|
||||||
|
removal op for SYMLINK token
|
||||||
|
|
||||||
|
The preventation code makes the rules loading panic when SYMLINK takes
|
||||||
|
the removal assignment op, which is incorrect.
|
||||||
|
---
|
||||||
|
exts/devmaster/src/lib/rules/rules_load.rs | 5 -----
|
||||||
|
1 file changed, 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/rules/rules_load.rs b/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
index a4535b52..eee77e63 100644
|
||||||
|
--- a/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
@@ -693,11 +693,6 @@ impl RuleToken {
|
||||||
|
msg: "Key 'SYMLINK' can not carry attribute.".location(&context),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
- if op == OperatorType::Remove {
|
||||||
|
- return Err(Error::RulesLoadError {
|
||||||
|
- msg: "Key 'SYMLINK' can not take remove operator.".location(&context),
|
||||||
|
- });
|
||||||
|
- }
|
||||||
|
|
||||||
|
if !op_is_match {
|
||||||
|
if let Err(e) = check_value_format(key.as_str(), value.as_str(), false) {
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,107 @@
|
|||||||
|
From 4c23e696a6bbf19f4f0806501af04aaf606ab3fa Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Wed, 8 Nov 2023 14:28:35 +0800
|
||||||
|
Subject: [PATCH 050/103] fix(devmaster): drop unnecessary debug trait
|
||||||
|
implementations
|
||||||
|
|
||||||
|
The debug trait derivations will break the compilation.
|
||||||
|
---
|
||||||
|
.../src/lib/framework/control_manager.rs | 1 -
|
||||||
|
.../src/lib/framework/garbage_collect.rs | 2 --
|
||||||
|
.../src/lib/framework/worker_manager.rs | 2 --
|
||||||
|
libs/device/src/error.rs | 16 +++-------------
|
||||||
|
4 files changed, 3 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/framework/control_manager.rs b/exts/devmaster/src/lib/framework/control_manager.rs
|
||||||
|
index 75fae984..342c6a0c 100644
|
||||||
|
--- a/exts/devmaster/src/lib/framework/control_manager.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/framework/control_manager.rs
|
||||||
|
@@ -30,7 +30,6 @@ use std::{
|
||||||
|
pub const CONTROL_MANAGER_LISTEN_ADDR: &str = "/run/devmaster/control";
|
||||||
|
|
||||||
|
/// control manager
|
||||||
|
-#[derive(Debug)]
|
||||||
|
pub struct ControlManager {
|
||||||
|
/// listener for devctl messages
|
||||||
|
listener: RefCell<UnixListener>,
|
||||||
|
diff --git a/exts/devmaster/src/lib/framework/garbage_collect.rs b/exts/devmaster/src/lib/framework/garbage_collect.rs
|
||||||
|
index 7a12ede8..c154f430 100644
|
||||||
|
--- a/exts/devmaster/src/lib/framework/garbage_collect.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/framework/garbage_collect.rs
|
||||||
|
@@ -25,7 +25,6 @@ use std::{
|
||||||
|
/// max time interval for idle worker
|
||||||
|
const WORKER_MAX_IDLE_INTERVAL: u64 = 3;
|
||||||
|
|
||||||
|
-#[derive(Debug)]
|
||||||
|
pub(crate) struct GarbageCollect {
|
||||||
|
devmaster: Weak<RefCell<Devmaster>>,
|
||||||
|
|
||||||
|
@@ -128,7 +127,6 @@ impl Source for GarbageCollect {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// kill idle workers
|
||||||
|
-#[derive(Debug)]
|
||||||
|
pub(crate) struct IdleWorkerKiller {
|
||||||
|
/// time interval
|
||||||
|
pub(crate) time: u64,
|
||||||
|
diff --git a/exts/devmaster/src/lib/framework/worker_manager.rs b/exts/devmaster/src/lib/framework/worker_manager.rs
|
||||||
|
index c7c1d45f..870f6779 100644
|
||||||
|
--- a/exts/devmaster/src/lib/framework/worker_manager.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/framework/worker_manager.rs
|
||||||
|
@@ -47,7 +47,6 @@ pub(crate) enum WorkerMessage {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// worker manager
|
||||||
|
-#[derive(Debug)]
|
||||||
|
pub struct WorkerManager {
|
||||||
|
/// max number of workers
|
||||||
|
pub(crate) workers_capacity: u32,
|
||||||
|
@@ -65,7 +64,6 @@ pub struct WorkerManager {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// worker
|
||||||
|
-#[derive(Debug)]
|
||||||
|
pub struct Worker {
|
||||||
|
/// worker unique id
|
||||||
|
id: u32,
|
||||||
|
diff --git a/libs/device/src/error.rs b/libs/device/src/error.rs
|
||||||
|
index 10410301..2cea6f4b 100644
|
||||||
|
--- a/libs/device/src/error.rs
|
||||||
|
+++ b/libs/device/src/error.rs
|
||||||
|
@@ -19,22 +19,13 @@ use snafu::prelude::Snafu;
|
||||||
|
#[derive(Debug, Snafu)]
|
||||||
|
#[snafu(visibility(pub))]
|
||||||
|
#[non_exhaustive]
|
||||||
|
+#[allow(missing_docs)]
|
||||||
|
pub enum Error {
|
||||||
|
- /// other error
|
||||||
|
#[snafu(context, display("Device error: {}", msg))]
|
||||||
|
- Nix {
|
||||||
|
- /// message
|
||||||
|
- msg: String,
|
||||||
|
- /// errno indicates the error kind
|
||||||
|
- source: nix::Error,
|
||||||
|
- },
|
||||||
|
+ Nix { msg: String, source: nix::Error },
|
||||||
|
|
||||||
|
#[snafu(context, display("IO error: {}", msg))]
|
||||||
|
- Io {
|
||||||
|
- /// message
|
||||||
|
- msg: String,
|
||||||
|
- source: std::io::Error,
|
||||||
|
- },
|
||||||
|
+ Io { msg: String, source: std::io::Error },
|
||||||
|
|
||||||
|
#[snafu(context, display("Basic error: {}", msg))]
|
||||||
|
Basic { msg: String, source: basic::Error },
|
||||||
|
@@ -106,7 +97,6 @@ impl Error {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
From f309964ae6101b94b2dd3c90f6e363e175685301 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Fri, 3 Nov 2023 01:11:39 +0800
|
||||||
|
Subject: [PATCH 027/103] fix(devmaster): fix misspelt sysattr sas_address
|
||||||
|
|
||||||
|
The 'sas_address' attribte is misspelt.
|
||||||
|
---
|
||||||
|
exts/devmaster/src/lib/builtin/path_id.rs | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/builtin/path_id.rs b/exts/devmaster/src/lib/builtin/path_id.rs
|
||||||
|
index ecd730f8..303b7528 100644
|
||||||
|
--- a/exts/devmaster/src/lib/builtin/path_id.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/builtin/path_id.rs
|
||||||
|
@@ -390,7 +390,7 @@ impl PathId {
|
||||||
|
Err(_) => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
- let sas_address = match asadev.get_sysattr_value("asa_address") {
|
||||||
|
+ let sas_address = match asadev.get_sysattr_value("sas_address") {
|
||||||
|
Ok(addr) => addr,
|
||||||
|
Err(_) => return None,
|
||||||
|
};
|
||||||
|
@@ -430,7 +430,7 @@ impl PathId {
|
||||||
|
Err(_) => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
- let target = match sessiondev.get_sysattr_value("asa_address") {
|
||||||
|
+ let target = match sessiondev.get_sysattr_value("sas_address") {
|
||||||
|
Ok(port) => port,
|
||||||
|
Err(_) => return None,
|
||||||
|
};
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
27
backport-fix-devmaster-fix-out-of-bounds-in-net_id.patch
Normal file
27
backport-fix-devmaster-fix-out-of-bounds-in-net_id.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From 84d4b4fcf0b2809e1857be3c17099ba1c41d7ea7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Thu, 2 Nov 2023 21:44:50 +0800
|
||||||
|
Subject: [PATCH 023/103] fix(devmaster): fix out-of-bounds in net_id
|
||||||
|
|
||||||
|
The pci subclass consists of two numbers, but is captured with three
|
||||||
|
length by mistake.
|
||||||
|
---
|
||||||
|
exts/devmaster/src/lib/builtin/net_id.rs | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/builtin/net_id.rs b/exts/devmaster/src/lib/builtin/net_id.rs
|
||||||
|
index e5f1faa6..091d6ccd 100644
|
||||||
|
--- a/exts/devmaster/src/lib/builtin/net_id.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/builtin/net_id.rs
|
||||||
|
@@ -338,7 +338,7 @@ fn is_pci_bridge(dev: Rc<RefCell<Device>>) -> bool {
|
||||||
|
|
||||||
|
/* PCI device subclass 04 corresponds to PCI bridge */
|
||||||
|
// modalias[idx+2:2
|
||||||
|
- let pci_subclass = match modalias.get(idx + 2..idx + 5) {
|
||||||
|
+ let pci_subclass = match modalias.get(idx + 2..idx + 4) {
|
||||||
|
Some(s) => s,
|
||||||
|
None => return false,
|
||||||
|
};
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
From f57218f2439ec7f0920af7f9e446ce3449944c7c Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Thu, 2 Nov 2023 19:47:28 +0800
|
||||||
|
Subject: [PATCH 022/103] fix(devmaster): fix potential integer overflow in
|
||||||
|
scsi_id
|
||||||
|
|
||||||
|
The buffer is a u8 vector, whose element may overflow if it add 4
|
||||||
|
before changing type to usize.
|
||||||
|
---
|
||||||
|
exts/devmaster/src/bin/tools/scsi_id/main.rs | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/bin/tools/scsi_id/main.rs b/exts/devmaster/src/bin/tools/scsi_id/main.rs
|
||||||
|
index 8098c8bf..0e621cd3 100644
|
||||||
|
--- a/exts/devmaster/src/bin/tools/scsi_id/main.rs
|
||||||
|
+++ b/exts/devmaster/src/bin/tools/scsi_id/main.rs
|
||||||
|
@@ -1158,7 +1158,7 @@ fn do_scsi_page80_inquiry(
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- let len: usize = (buffer[3] + 4) as usize;
|
||||||
|
+ let len: usize = buffer[3] as usize + 4;
|
||||||
|
|
||||||
|
if get_serial {
|
||||||
|
dev_scsi.serial = "S".to_string();
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
From 9f50a5627a9cfb9b6dba4eeaa524d8986f2408b8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Mon, 30 Oct 2023 20:58:53 +0800
|
||||||
|
Subject: [PATCH 008/103] fix(devmaster): keep the same name with udev control
|
||||||
|
socket
|
||||||
|
|
||||||
|
The libudev api will check the /run/udev/control socket to indicate
|
||||||
|
wether udevd is running. Keep the name of control socket same with
|
||||||
|
udev.
|
||||||
|
---
|
||||||
|
exts/devmaster/src/lib/framework/control_manager.rs | 2 +-
|
||||||
|
exts/devmaster/src/lib/framework/worker_manager.rs | 2 +-
|
||||||
|
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/framework/control_manager.rs b/exts/devmaster/src/lib/framework/control_manager.rs
|
||||||
|
index 38c7c337..75fae984 100644
|
||||||
|
--- a/exts/devmaster/src/lib/framework/control_manager.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/framework/control_manager.rs
|
||||||
|
@@ -27,7 +27,7 @@ use std::{
|
||||||
|
};
|
||||||
|
|
||||||
|
/// listening address for control manager
|
||||||
|
-pub const CONTROL_MANAGER_LISTEN_ADDR: &str = "/run/devmaster/control.sock";
|
||||||
|
+pub const CONTROL_MANAGER_LISTEN_ADDR: &str = "/run/devmaster/control";
|
||||||
|
|
||||||
|
/// control manager
|
||||||
|
#[derive(Debug)]
|
||||||
|
diff --git a/exts/devmaster/src/lib/framework/worker_manager.rs b/exts/devmaster/src/lib/framework/worker_manager.rs
|
||||||
|
index 55778ddb..c7c1d45f 100644
|
||||||
|
--- a/exts/devmaster/src/lib/framework/worker_manager.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/framework/worker_manager.rs
|
||||||
|
@@ -38,7 +38,7 @@ use std::{
|
||||||
|
use super::devmaster::Devmaster;
|
||||||
|
|
||||||
|
/// worker manager listen address
|
||||||
|
-pub const WORKER_MANAGER_LISTEN_ADDR: &str = "/run/devmaster/worker.sock";
|
||||||
|
+pub const WORKER_MANAGER_LISTEN_ADDR: &str = "/run/devmaster/worker";
|
||||||
|
|
||||||
|
/// messages sended by manager to workers
|
||||||
|
pub(crate) enum WorkerMessage {
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
From 0df31891bfd0ab047d29afbd2313bd98bcf69a98 Mon Sep 17 00:00:00 2001
|
||||||
|
From: huyubiao <huyubiao@huawei.com>
|
||||||
|
Date: Mon, 6 Nov 2023 20:13:11 +0800
|
||||||
|
Subject: [PATCH 033/103] fix: return Ok when the .hwdb and hwdb.bin files
|
||||||
|
cannot be found
|
||||||
|
|
||||||
|
---
|
||||||
|
libs/hwdb/src/hwdb_util.rs | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/libs/hwdb/src/hwdb_util.rs b/libs/hwdb/src/hwdb_util.rs
|
||||||
|
index 2ff6243a..a5c2eac0 100644
|
||||||
|
--- a/libs/hwdb/src/hwdb_util.rs
|
||||||
|
+++ b/libs/hwdb/src/hwdb_util.rs
|
||||||
|
@@ -753,7 +753,7 @@ impl HwdbUtil {
|
||||||
|
hwdb_bin
|
||||||
|
),
|
||||||
|
Err(e) => {
|
||||||
|
- if e == nix::Error::ENOENT {
|
||||||
|
+ if e != nix::Error::ENOENT {
|
||||||
|
log::error!(
|
||||||
|
"Failed to remove compiled hwdb database {:?}:{:?}",
|
||||||
|
hwdb_bin,
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
68
backport-refactor-devmaster-compress-unnecessary-code.patch
Normal file
68
backport-refactor-devmaster-compress-unnecessary-code.patch
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
From a01bde892736601aa57a2780e45b00cdb842dc16 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Thu, 16 Nov 2023 10:05:37 +0800
|
||||||
|
Subject: [PATCH 065/103] refactor(devmaster): compress unnecessary code
|
||||||
|
|
||||||
|
Eliminate unnecessary code for error handling.
|
||||||
|
---
|
||||||
|
.../src/lib/framework/uevent_monitor.rs | 32 ++++---------------
|
||||||
|
1 file changed, 6 insertions(+), 26 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/framework/uevent_monitor.rs b/exts/devmaster/src/lib/framework/uevent_monitor.rs
|
||||||
|
index 809071d1..30bbd570 100644
|
||||||
|
--- a/exts/devmaster/src/lib/framework/uevent_monitor.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/framework/uevent_monitor.rs
|
||||||
|
@@ -12,12 +12,9 @@
|
||||||
|
|
||||||
|
//! uevent_monitor
|
||||||
|
//!
|
||||||
|
-use crate::error::*;
|
||||||
|
use crate::framework::job_queue::JobQueue;
|
||||||
|
use device::device_monitor::{DeviceMonitor, MonitorNetlinkGroup};
|
||||||
|
use event::{EventType, Events, Source};
|
||||||
|
-use nix::errno::Errno;
|
||||||
|
-use snafu::ResultExt;
|
||||||
|
use std::os::unix::io::RawFd;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
@@ -71,31 +68,14 @@ impl Source for UeventMonitor {
|
||||||
|
fn dispatch(&self, _: &Events) -> i32 {
|
||||||
|
let device = match self.device_monitor.receive_device() {
|
||||||
|
Ok(ret) => ret,
|
||||||
|
- Err(e) => match e {
|
||||||
|
- device::error::Error::Nix {
|
||||||
|
- msg: _,
|
||||||
|
- source: Errno::EAGAIN,
|
||||||
|
- } => {
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
- device::error::Error::Nix { msg: _, source: _ } => {
|
||||||
|
- log::error!("{}", e);
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
- _ => {
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
- },
|
||||||
|
+ Err(e) => {
|
||||||
|
+ log::error!("Monitor Error: {}", e);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
};
|
||||||
|
|
||||||
|
- log::debug!(
|
||||||
|
- "Monitor: received device {}",
|
||||||
|
- device
|
||||||
|
- .get_devpath()
|
||||||
|
- .context(DeviceSnafu)
|
||||||
|
- .log_error("uevent has no devpath")
|
||||||
|
- .unwrap_or_default()
|
||||||
|
- );
|
||||||
|
+ /* The devpath is guaranteed to be valid. */
|
||||||
|
+ log::debug!("Monitor: received device {}", device.get_devpath().unwrap());
|
||||||
|
|
||||||
|
self.job_queue.job_queue_insert(device);
|
||||||
|
0
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
From 2fa2b67a81b6bbb1af175703bf00ebf990bac026 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Tue, 21 Nov 2023 20:02:49 +0800
|
||||||
|
Subject: [PATCH 077/103] refactor(devmaster): rename the create_tmp_rules
|
||||||
|
function to create_tmp_file
|
||||||
|
|
||||||
|
The function is used to create a temporary file and write content inside it.
|
||||||
|
It is more proper to have a more general name.
|
||||||
|
---
|
||||||
|
exts/devmaster/src/lib/rules/rules_load.rs | 12 ++++++------
|
||||||
|
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/rules/rules_load.rs b/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
index 999c9692..b035f562 100644
|
||||||
|
--- a/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
@@ -1724,7 +1724,7 @@ impl RuleToken {
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
-mod tests {
|
||||||
|
+pub(crate) mod tests {
|
||||||
|
use basic::fs_util::touch_file;
|
||||||
|
use log::init_log;
|
||||||
|
use log::Level;
|
||||||
|
@@ -1736,7 +1736,7 @@ mod tests {
|
||||||
|
use std::panic::catch_unwind;
|
||||||
|
use std::{fs, path::Path};
|
||||||
|
|
||||||
|
- fn create_tmp_rules(dir: &'static str, file: &str, content: &str, truncate: bool) {
|
||||||
|
+ pub(crate) fn create_tmp_file(dir: &'static str, file: &str, content: &str, truncate: bool) {
|
||||||
|
assert!(fs::create_dir_all(dir).is_ok());
|
||||||
|
let s = format!("{}/{}", dir, file);
|
||||||
|
let p = Path::new(&s);
|
||||||
|
@@ -1821,7 +1821,7 @@ mod tests {
|
||||||
|
];
|
||||||
|
|
||||||
|
for &content in legal_rule.iter() {
|
||||||
|
- create_tmp_rules(
|
||||||
|
+ create_tmp_file(
|
||||||
|
"/tmp/devmaster/test_load_rules",
|
||||||
|
"00-test.rules",
|
||||||
|
content,
|
||||||
|
@@ -1954,7 +1954,7 @@ mod tests {
|
||||||
|
];
|
||||||
|
|
||||||
|
for content in illegal_rule.iter() {
|
||||||
|
- create_tmp_rules(
|
||||||
|
+ create_tmp_file(
|
||||||
|
"/tmp/devmaster/test_load_rules_panic",
|
||||||
|
"00-test.rules",
|
||||||
|
content,
|
||||||
|
@@ -1990,7 +1990,7 @@ mod tests {
|
||||||
|
let illegal = vec!["OWNER=\"xxxx\"", "GROUP=\"xxxx\""];
|
||||||
|
|
||||||
|
for &content in legal.iter() {
|
||||||
|
- create_tmp_rules(
|
||||||
|
+ create_tmp_file(
|
||||||
|
"/tmp/devmaster/test_resolve_name_time",
|
||||||
|
"00-test.rules",
|
||||||
|
content,
|
||||||
|
@@ -2004,7 +2004,7 @@ mod tests {
|
||||||
|
}
|
||||||
|
|
||||||
|
for &content in illegal.iter() {
|
||||||
|
- create_tmp_rules(
|
||||||
|
+ create_tmp_file(
|
||||||
|
"/tmp/devmaster/test_resolve_name_time",
|
||||||
|
"00-test.rules",
|
||||||
|
content,
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
1111
backport-test-device-add-UT-for-device-enumerator.patch
Normal file
1111
backport-test-device-add-UT-for-device-enumerator.patch
Normal file
File diff suppressed because it is too large
Load Diff
75
backport-test-device-add-UT-for-device-monitor.patch
Normal file
75
backport-test-device-add-UT-for-device-monitor.patch
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
From c600ca109d74c38f130b84353b6f21ff2439a36d Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Wed, 15 Nov 2023 15:35:26 +0800
|
||||||
|
Subject: [PATCH 062/103] test(device): add UT for device monitor
|
||||||
|
|
||||||
|
---
|
||||||
|
libs/device/src/device_monitor.rs | 19 +++++++++++++------
|
||||||
|
1 file changed, 13 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libs/device/src/device_monitor.rs b/libs/device/src/device_monitor.rs
|
||||||
|
index 3f1d1ba6..c6ad3ec6 100644
|
||||||
|
--- a/libs/device/src/device_monitor.rs
|
||||||
|
+++ b/libs/device/src/device_monitor.rs
|
||||||
|
@@ -216,7 +216,7 @@ impl Drop for DeviceMonitor {
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
- use crate::device::*;
|
||||||
|
+ use crate::{device::*, DeviceAction};
|
||||||
|
use event::*;
|
||||||
|
use std::{os::unix::prelude::RawFd, rc::Rc, thread::spawn};
|
||||||
|
|
||||||
|
@@ -264,9 +264,13 @@ mod tests {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// test whether device monitor can receive uevent from kernel normally
|
||||||
|
- #[ignore]
|
||||||
|
#[test]
|
||||||
|
fn test_monitor_kernel() {
|
||||||
|
+ let device = Device::from_subsystem_sysname("net", "lo").unwrap();
|
||||||
|
+ if device.trigger(DeviceAction::Change).is_err() {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
let e = Events::new().unwrap();
|
||||||
|
let s: Rc<dyn Source> = Rc::new(Monitor {
|
||||||
|
device_monitor: DeviceMonitor::new(MonitorNetlinkGroup::Kernel, None),
|
||||||
|
@@ -275,7 +279,7 @@ mod tests {
|
||||||
|
e.set_enabled(s.clone(), EventState::On).unwrap();
|
||||||
|
|
||||||
|
spawn(|| {
|
||||||
|
- let device = Device::from_devname("/dev/sda").unwrap();
|
||||||
|
+ let device = Device::from_subsystem_sysname("net", "lo").unwrap();
|
||||||
|
device.set_sysattr_value("uevent", Some("change")).unwrap();
|
||||||
|
})
|
||||||
|
.join()
|
||||||
|
@@ -287,9 +291,13 @@ mod tests {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// test whether device monitor can receive device message from userspace normally
|
||||||
|
- #[ignore]
|
||||||
|
#[test]
|
||||||
|
fn test_monitor_userspace() {
|
||||||
|
+ let device = Device::from_subsystem_sysname("net", "lo").unwrap();
|
||||||
|
+ if device.trigger(DeviceAction::Change).is_err() {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
let e = Events::new().unwrap();
|
||||||
|
let s: Rc<dyn Source> = Rc::new(Monitor {
|
||||||
|
device_monitor: DeviceMonitor::new(MonitorNetlinkGroup::Userspace, None),
|
||||||
|
@@ -298,9 +306,8 @@ mod tests {
|
||||||
|
e.set_enabled(s.clone(), EventState::On).unwrap();
|
||||||
|
|
||||||
|
spawn(|| {
|
||||||
|
- let device = Device::from_devname("/dev/sda").unwrap();
|
||||||
|
+ let device = Device::from_subsystem_sysname("net", "lo").unwrap();
|
||||||
|
device.set_action_from_string("change").unwrap();
|
||||||
|
- device.set_subsystem("block");
|
||||||
|
device.set_seqnum(1000);
|
||||||
|
|
||||||
|
let broadcaster = DeviceMonitor::new(MonitorNetlinkGroup::None, None);
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
1565
backport-test-device-compress-closures-and-add-some-unit-case.patch
Normal file
1565
backport-test-device-compress-closures-and-add-some-unit-case.patch
Normal file
File diff suppressed because it is too large
Load Diff
1606
backport-test-device-refactor-and-increase-test-line-coverage.patch
Normal file
1606
backport-test-device-refactor-and-increase-test-line-coverage.patch
Normal file
File diff suppressed because it is too large
Load Diff
410
backport-test-devmaster-add-UT-cases-for-rules-load.patch
Normal file
410
backport-test-devmaster-add-UT-cases-for-rules-load.patch
Normal file
@ -0,0 +1,410 @@
|
|||||||
|
From 2d38b2906a0b71c1ea591d83fba9879ce9fb6e65 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Fri, 17 Nov 2023 06:01:41 +0800
|
||||||
|
Subject: [PATCH 072/103] test(devmaster): add UT cases for rules load
|
||||||
|
|
||||||
|
---
|
||||||
|
exts/devmaster/src/lib/rules/rules_load.rs | 342 +++++++++++++++++----
|
||||||
|
1 file changed, 287 insertions(+), 55 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/rules/rules_load.rs b/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
index 57ff19ac..e9dd2259 100644
|
||||||
|
--- a/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
@@ -1725,7 +1725,6 @@ impl RuleToken {
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
- use crate::config::*;
|
||||||
|
use basic::fs_util::touch_file;
|
||||||
|
use log::init_log;
|
||||||
|
use log::Level;
|
||||||
|
@@ -1733,32 +1732,245 @@ mod tests {
|
||||||
|
use super::*;
|
||||||
|
use std::fs::create_dir_all;
|
||||||
|
use std::fs::remove_dir_all;
|
||||||
|
- use std::{fs, path::Path, thread::JoinHandle};
|
||||||
|
-
|
||||||
|
- fn create_test_rules_dir(dir: &'static str) {
|
||||||
|
- assert!(fs::create_dir(dir).is_ok());
|
||||||
|
- assert!(fs::write(
|
||||||
|
- format!("{}/test.rules", dir),
|
||||||
|
- "ACTION == \"change\", SYMLINK += \"test1\"
|
||||||
|
-ACTION == \"change\", SYMLINK += \"test11\", \\
|
||||||
|
-SYMLINK += \"test111\"
|
||||||
|
-ACTION == \"change\", SYMLINK += \"test1111\", \\
|
||||||
|
-SYMLINK += \"test11111\", \\
|
||||||
|
-SYMLINK += \"test111111\"",
|
||||||
|
- )
|
||||||
|
- .is_ok());
|
||||||
|
+ use std::io::Write;
|
||||||
|
+ use std::panic::catch_unwind;
|
||||||
|
+ use std::{fs, path::Path};
|
||||||
|
+
|
||||||
|
+ fn create_tmp_rules(dir: &'static str, file: &str, content: &str) {
|
||||||
|
+ assert!(fs::create_dir_all(dir).is_ok());
|
||||||
|
+ assert!(fs::write(format!("{}/{}", dir, file), content,).is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
- fn clear_test_rules_dir(dir: &'static str) {
|
||||||
|
+ fn clear_tmp_rules(dir: &'static str) {
|
||||||
|
if Path::new(dir).exists() {
|
||||||
|
assert!(fs::remove_dir_all(dir).is_ok());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
- fn test_rules_new() {
|
||||||
|
+ fn test_load_rules() {
|
||||||
|
+ init_log(
|
||||||
|
+ "test_load_rules",
|
||||||
|
+ Level::Debug,
|
||||||
|
+ vec!["console"],
|
||||||
|
+ "",
|
||||||
|
+ 0,
|
||||||
|
+ 0,
|
||||||
|
+ false,
|
||||||
|
+ );
|
||||||
|
+ clear_tmp_rules("/tmp/devmaster/rules");
|
||||||
|
+
|
||||||
|
+ let legal_rule = vec![
|
||||||
|
+ "ACTION == \"change\", SYMLINK += \"test1\"", // Test legal rules.
|
||||||
|
+ "ACTION == \"change\", SYMLINK += \"test11\", \\
|
||||||
|
+ SYMLINK += \"test111\"", // Test double line tying.
|
||||||
|
+ "ACTION == \"change\", SYMLINK += \"test1111\", \\
|
||||||
|
+ SYMLINK += \"test11111\", \\
|
||||||
|
+ SYMLINK += \"test111111\"", // Test triple line tying.
|
||||||
|
+ "SYMLINK == \"$hello\"", // Illegal placeholder will throw warning rather than panic.
|
||||||
|
+ "NAME += \"xxx\"", // NAME will transfer operator += to =.
|
||||||
|
+ "NAME == \"$hello\"", // Illegal placeholder will throw warning rather than panic.
|
||||||
|
+ "ENV{xxx}:=\"xxx\"", // ENV will transfer final assignment := to =.
|
||||||
|
+ "ENV{xxx}=\"$hello\"", // Illegal placeholder will throw warning rather than panic.
|
||||||
|
+ "CONST{arch}==\"x86_64\"", // Test legal CONST usage.
|
||||||
|
+ "CONST{virt}==\"qemu\"", // Test legal CONST usage.
|
||||||
|
+ "SUBSYSTEM==\"bus\"", // SUBSYSTEM will throw warning if the value is 'bus' or 'class'.
|
||||||
|
+ "DRIVER==\"xxx\"", // Test DRIVER usage.
|
||||||
|
+ /* ATTR will throw warning if the operator is += or :=,
|
||||||
|
+ * and transfer the operator into =.
|
||||||
|
+ */
|
||||||
|
+ "ATTR{xxx}+=\"xxx\"",
|
||||||
|
+ "ATTR{xxx}:=\"xxx\"",
|
||||||
|
+ "ATTR{xxx}=\"$hello\"", // Illegal placeholder in value will throw warning rather than panic.
|
||||||
|
+ /* Test SYSCTL usage. */
|
||||||
|
+ "SYSCTL{hello}=\"world\"",
|
||||||
|
+ "SYSCTL{hello}==\"world\"",
|
||||||
|
+ /* SYSCTL will transfer the += and := operator to =, and trow warning. */
|
||||||
|
+ "SYSCTL{hello}+=\"world\"",
|
||||||
|
+ "SYSCTL{hello}:=\"world\"",
|
||||||
|
+ "SYSCTL{hello}=\"$hello\"", // Illegal placeholder in value will throw warning rather than panic.
|
||||||
|
+ "ATTRS{device/xxx}==\"xxx\"", // The attribute with prefix of 'device/' will trow warning.
|
||||||
|
+ "ATTRS{../xxx}==\"xxx\"", // The attribute with prefix of 'device/' will throw warning.
|
||||||
|
+ "TAGS==\"xxx\"", // Test TAGS usage.
|
||||||
|
+ "TEST{777}==\"xx\"", // Test TEST usage.
|
||||||
|
+ "TEST{777}==\"$hello\"", // Illegal placeholder in value will throw warning rather than panic.
|
||||||
|
+ "PROGRAM==\"$hello\"", // Illegal placeholder in value will throw warning rather than panic.
|
||||||
|
+ "IMPORT{program}==\"$hello\"", // Illegal placeholder in value will throw warning rather than panic.
|
||||||
|
+ "IMPORT{file}=\"x\"", // IMPORT will throw warning if the operator is not matching or unmatching and transfer it to ==.
|
||||||
|
+ "IMPORT{program}==\"path_id $kernel\"", // If the program is a built-in command, IMPORT will identify it.
|
||||||
|
+ /* Test OPTIONS usages. */
|
||||||
|
+ "OPTIONS+=\"string_escape=none\"",
|
||||||
|
+ "OPTIONS+=\"db_persist\"",
|
||||||
|
+ "OPTIONS+=\"log_level=rest\"",
|
||||||
|
+ "OPTIONS+=\"log_level=10\"",
|
||||||
|
+ "OWNER+=\"0\"", // OWNER will transfer += to =, and trow a warning.
|
||||||
|
+ "GROUP+=\"0\"", // GROUP will transfer += to =, and trow a warning.
|
||||||
|
+ "MODE+=\"777\"", // MODE will transfer += to =, and trow a warning.
|
||||||
|
+ "MODE=\"$hello\"", // Illegal placeholder in value will throw warning rather than panic.
|
||||||
|
+ "SECLABEL{x}:=\"$hello\"", // Illegal placeholder in value will throw warning rather than panic.
|
||||||
|
+ ];
|
||||||
|
+
|
||||||
|
+ create_tmp_rules("/tmp/devmaster/rules", "00-test.rules", "");
|
||||||
|
+
|
||||||
|
+ for &content in legal_rule.iter() {
|
||||||
|
+ let mut f = fs::OpenOptions::new()
|
||||||
|
+ .write(true)
|
||||||
|
+ .truncate(true)
|
||||||
|
+ .open("/tmp/devmaster/rules/00-test.rules")
|
||||||
|
+ .unwrap();
|
||||||
|
+ f.write_all(content.as_bytes()).unwrap();
|
||||||
|
+
|
||||||
|
+ let _ = Rules::load_rules(
|
||||||
|
+ vec!["/tmp/devmaster/rules".to_string()],
|
||||||
|
+ ResolveNameTime::Early,
|
||||||
|
+ );
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ clear_tmp_rules("/tmp/devmaster/rules");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ #[test]
|
||||||
|
+ fn test_load_rules_panic() {
|
||||||
|
+ init_log(
|
||||||
|
+ "test_load_rules_panic",
|
||||||
|
+ Level::Debug,
|
||||||
|
+ vec!["console"],
|
||||||
|
+ "",
|
||||||
|
+ 0,
|
||||||
|
+ 0,
|
||||||
|
+ false,
|
||||||
|
+ );
|
||||||
|
+ clear_tmp_rules("/tmp/devmaster/rules");
|
||||||
|
+
|
||||||
|
+ let illegal_rule = vec![
|
||||||
|
+ "action==\"change\"", // Error in State::Pre
|
||||||
|
+ "ACtion==\"change\"", // Error in State::Key
|
||||||
|
+ "ENV{!}==\"hello\"", // Error in State::Attribute
|
||||||
|
+ "ACTION #= \"hello\"", // Error in State::PreOp
|
||||||
|
+ "ACTION =# \"hello\"", // Error in State::Op
|
||||||
|
+ "ACTION == hello", // Error in State::PostOp
|
||||||
|
+ "ACTION == \"change\"x", // Error in State::PostValue
|
||||||
|
+ "ACTION = \"change\"", // ACTION can not take assign operator.
|
||||||
|
+ "DEVPATH{xxx} == \"xxx\"", // DEVPATH can not take attribute.
|
||||||
|
+ "DEVPATH = \"xxx\"", // DEVPATH can no take assign operator.
|
||||||
|
+ "KERNEL{xxx} == \"xxx\"", // KERNEL can not take attribute.
|
||||||
|
+ "KERNEL = \"xxx\"", // KERNEL can not take assign operator.
|
||||||
|
+ "SYMLINK{xxx} = \"hello\"", // SYMLINK can not take attribute.
|
||||||
|
+ "NAME{xxx} = \"xxx\"", // NAME can not take attribute.
|
||||||
|
+ "NAME -= \"xxx\"", // NAME can not take removal operator.
|
||||||
|
+ "NAME=\"%k\"", // NAME can not take '%k' value.
|
||||||
|
+ "NAME=\"\"", // NAME can not take empty value.
|
||||||
|
+ "ENV=\"xxx\"", // ENV must take attribute.
|
||||||
|
+ "ENV{xxx}-=\"xxx\"", // ENV can not take removal operator.
|
||||||
|
+ /* ENV with non-match operator can not take the following attributes:
|
||||||
|
+ * "ACTION"
|
||||||
|
+ * "DEVLINKS"
|
||||||
|
+ * "DEVNAME"
|
||||||
|
+ * "DEVTYPE"
|
||||||
|
+ * "DRIVER"
|
||||||
|
+ * "IFINDEX"
|
||||||
|
+ * "MAJOR"
|
||||||
|
+ * "MINOR"
|
||||||
|
+ * "SEQNUM"
|
||||||
|
+ * "SUBSYSTEM"
|
||||||
|
+ * "TAGS"
|
||||||
|
+ */
|
||||||
|
+ "ENV{ACTION}=\"xxx\"",
|
||||||
|
+ "ENV{DEVLINKS}=\"xxx\"",
|
||||||
|
+ "ENV{DEVNAME}=\"xxx\"",
|
||||||
|
+ "ENV{DEVTYPE}=\"xxx\"",
|
||||||
|
+ "ENV{DRIVER}=\"xxx\"",
|
||||||
|
+ "ENV{IFINDEX}=\"xxx\"",
|
||||||
|
+ "ENV{MAJOR}=\"xxx\"",
|
||||||
|
+ "ENV{MINOR}=\"xxx\"",
|
||||||
|
+ "ENV{SEQNUM}=\"xxx\"",
|
||||||
|
+ "ENV{SUBSYSTEM}=\"xxx\"",
|
||||||
|
+ "ENV{TAGS}=\"xxx\"",
|
||||||
|
+ "CONST==\"xxx\"", // CONST must take an attribute.
|
||||||
|
+ "CONST{xxx}==\"xxx\"", // CONST can only take "arch" or "virt" attribute.
|
||||||
|
+ "CONST{virt}=\"qemu\"", // CONST can not take assignment operator.
|
||||||
|
+ "TAG{xxx}+=\"xxx\"", // TAG can not take attribute.
|
||||||
|
+ "SUBSYSTEM{xxx}==\"block\"", // SUBSYSTEM can not take attribute.
|
||||||
|
+ "SUBSYSTEM=\"block\"", // SUBSYSTEM can only take matching or unmatching operators.
|
||||||
|
+ "DRIVER{xxx}==\"xxx\"", // DRIVER can not take attribute.
|
||||||
|
+ "DRIVER=\"xxx\"", // DRIVER can only take matching or unmatching operators.
|
||||||
|
+ "ATTR{$hello}==\"xxx\"", // ATTR can not take illegal attribute.
|
||||||
|
+ "ATTR{hello}-=\"xxx\"", // ATTR can not take removal operator.
|
||||||
|
+ /* SYSCTL must take attribute. */
|
||||||
|
+ "SYSCTL=\"xxx\"",
|
||||||
|
+ "SYSCTL==\"xxx\"",
|
||||||
|
+ "SYSCTL{xxx}-=\"xxx\"", // SYSCTL can not take removal operator.
|
||||||
|
+ "KERNELS{xxx}==\"xxx\"", // KERNELS can not take attribute.
|
||||||
|
+ "KERNELS=\"xxx\"", // KERNELS can only take matching or unmatching operators.
|
||||||
|
+ "SUBSYSTEMS{xxx}==\"xxx\"", // SUBSYSTEMS can not take attribute.
|
||||||
|
+ "SUBSYSTEMS=\"xxx\"", // SUBSYSTEMS can not take assignment operators.
|
||||||
|
+ "DRIVERS{xxx}=\"xxx\"", // DRIVERS can not take attribute.
|
||||||
|
+ "DRIVERS=\"xxx\"", // DRIVERS can not take assignment operators.
|
||||||
|
+ "ATTRS==\"xxx\"", // ATTRS must take an attribute.
|
||||||
|
+ "ATTRS{xxx}=\"x\"", // ATTRS can not take assignment operators.
|
||||||
|
+ "TAGS{xxx}=\"xxx\"", // TAGS can not take attribute.
|
||||||
|
+ "TAGS=\"xxx\"", // TAGS can not take assignment operators.
|
||||||
|
+ "TEST{777}=\"x\"", // TEST can not take assignment operators.
|
||||||
|
+ "PROGRAM{x}==\"x\"", // PROGRAM can not take attribute.
|
||||||
|
+ "PROGRAM-=\"x\"", // PROGRAM can not take removal attribute.
|
||||||
|
+ "IMPORT==\"x\"", // IMPORT must take an attribute.
|
||||||
|
+ "IMPORT{builtin}==\"xxx $kernel\"", // IMPORT{builtin} will panic if the command is not a valid built-in.
|
||||||
|
+ "IMPORT{x}==\"x\"", // IMPORT will panic if the attribute is invalid.
|
||||||
|
+ "RESULT{x}==\"x\"", // RESULT can not take attribute.
|
||||||
|
+ "RESULT{x}=\"x\"", // RESULT can only take matching or unmatching operator.
|
||||||
|
+ "OPTIONS{x}+=\"x\"", // OPTIONS can not take attribute.
|
||||||
|
+ "OPTIONS{x}==\"x\"", // OPTIONS can not take matching or unmatching operator.
|
||||||
|
+ "OPTIONS{x}-=\"x\"", // OPTIONS can not take removal operator.
|
||||||
|
+ "OPTIONS+=\"link_priority=x\"", // Invalid number of link priority.
|
||||||
|
+ "OPTIONS+=\"log_level=xxx\"", // Invalid log_level.
|
||||||
|
+ "OWNER{x}==\"x\"", // OWNER can not take attribute.
|
||||||
|
+ "OWNER==\"0\"", // OWNER can not take matching or unmatching operator.
|
||||||
|
+ "OWNER-=\"0\"", // OWNER can not take removal operator.
|
||||||
|
+ "GROUP==\"0\"", // OWNER can not take matching or unmatching operator.
|
||||||
|
+ "GROUP-=\"0\"", // OWNER can not take removal operator.
|
||||||
|
+ "MODE{x}=\"777\"", // MODE can not take attribute.
|
||||||
|
+ "MODE==\"777\"", // MODE can not take matching or unmatching operator.
|
||||||
|
+ "MODE-=\"777\"", // MODE can not take removal operator.
|
||||||
|
+ "SECLABEL=\"xxx\"", // SECLABEL must take an attribute.
|
||||||
|
+ "SECLABEL{x}==\"x\"", // SECLABEL can not take matching or unmatching operator.
|
||||||
|
+ "SECLABEL{x}-=\"x\"", // SECLABEL can not take removal operator.
|
||||||
|
+ "RUN==\"xxx\"", // RUN can not take matching or unmatching operator.
|
||||||
|
+ "RUN-=\"xxx\"", // RUN can not take removal operator.
|
||||||
|
+ "RUN{builtin}==\"xxx\"", // RUN will panic if the builtin is invalid.
|
||||||
|
+ "RUN{xxx}==\"xxx\"", // RUN will panic if the attribute is not builtin or program.
|
||||||
|
+ "GOTO{xx}=\"xx\"", // GOTO can not take attribute.
|
||||||
|
+ "GOTO==\"xx\"", // GOTO can only take assignment operator.
|
||||||
|
+ "LABEL{x}==\"x\"", // LABEL can not take attribute.
|
||||||
|
+ "LABEL==\"x\"", // LABEL can only take assignment operator.
|
||||||
|
+ "XXX=\"xxx\"", // Invalid token key.
|
||||||
|
+ ];
|
||||||
|
+
|
||||||
|
+ create_tmp_rules("/tmp/devmaster/rules", "00-test.rules", "");
|
||||||
|
+
|
||||||
|
+ for content in illegal_rule.iter() {
|
||||||
|
+ let mut f = fs::OpenOptions::new()
|
||||||
|
+ .write(true)
|
||||||
|
+ .truncate(true)
|
||||||
|
+ .open("/tmp/devmaster/rules/00-test.rules")
|
||||||
|
+ .unwrap();
|
||||||
|
+ f.write_all(content.as_bytes()).unwrap();
|
||||||
|
+
|
||||||
|
+ assert!(catch_unwind(|| {
|
||||||
|
+ let _ = Rules::load_rules(
|
||||||
|
+ vec!["/tmp/devmaster/rules".to_string()],
|
||||||
|
+ ResolveNameTime::Early,
|
||||||
|
+ );
|
||||||
|
+ })
|
||||||
|
+ .is_err());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ clear_tmp_rules("/tmp/devmaster/rules");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ #[test]
|
||||||
|
+ fn test_resolve_name_time() {
|
||||||
|
init_log(
|
||||||
|
- "test_rules_new",
|
||||||
|
+ "test_load_rules",
|
||||||
|
Level::Debug,
|
||||||
|
vec!["console"],
|
||||||
|
"",
|
||||||
|
@@ -1766,11 +1978,50 @@ SYMLINK += \"test111111\"",
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
- clear_test_rules_dir("test_rules_new");
|
||||||
|
- create_test_rules_dir("test_rules_new");
|
||||||
|
- let rules = Rules::load_rules(DEFAULT_RULES_DIRS.to_vec(), ResolveNameTime::Early);
|
||||||
|
- println!("{}", rules.read().unwrap());
|
||||||
|
- clear_test_rules_dir("test_rules_new");
|
||||||
|
+ clear_tmp_rules("/tmp/devmaster/rules");
|
||||||
|
+
|
||||||
|
+ let legal = vec!["OWNER=\"root\"", "GROUP=\"root\""];
|
||||||
|
+ let illegal = vec!["OWNER=\"xxxx\"", "GROUP=\"xxxx\""];
|
||||||
|
+
|
||||||
|
+ create_tmp_rules("/tmp/devmaster/rules", "00-test.rules", "");
|
||||||
|
+
|
||||||
|
+ for &content in legal.iter() {
|
||||||
|
+ let mut f = fs::OpenOptions::new()
|
||||||
|
+ .write(true)
|
||||||
|
+ .truncate(true)
|
||||||
|
+ .open("/tmp/devmaster/rules/00-test.rules")
|
||||||
|
+ .unwrap();
|
||||||
|
+ f.write_all(content.as_bytes()).unwrap();
|
||||||
|
+
|
||||||
|
+ let _ = Rules::load_rules(
|
||||||
|
+ vec!["/tmp/devmaster/rules".to_string()],
|
||||||
|
+ ResolveNameTime::Early,
|
||||||
|
+ );
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for &content in illegal.iter() {
|
||||||
|
+ let mut f = fs::OpenOptions::new()
|
||||||
|
+ .write(true)
|
||||||
|
+ .truncate(true)
|
||||||
|
+ .open("/tmp/devmaster/rules/00-test.rules")
|
||||||
|
+ .unwrap();
|
||||||
|
+ f.write_all(content.as_bytes()).unwrap();
|
||||||
|
+
|
||||||
|
+ let _ = Rules::load_rules(
|
||||||
|
+ vec!["/tmp/devmaster/rules".to_string()],
|
||||||
|
+ ResolveNameTime::Late,
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ assert!(catch_unwind(|| {
|
||||||
|
+ let _ = Rules::load_rules(
|
||||||
|
+ vec!["/tmp/devmaster/rules".to_string()],
|
||||||
|
+ ResolveNameTime::Early,
|
||||||
|
+ );
|
||||||
|
+ })
|
||||||
|
+ .is_err());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ clear_tmp_rules("/tmp/devmaster/rules");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
@@ -1955,34 +2206,6 @@ SYMLINK += \"test111111\"",
|
||||||
|
println!("{:?}", t);
|
||||||
|
}
|
||||||
|
|
||||||
|
- #[test]
|
||||||
|
- fn test_rules_share_among_threads() {
|
||||||
|
- create_test_rules_dir("test_rules_share_among_threads");
|
||||||
|
- let rules = Rules::new(
|
||||||
|
- vec![
|
||||||
|
- "test_rules_new_1".to_string(),
|
||||||
|
- "test_rules_new_2".to_string(),
|
||||||
|
- ],
|
||||||
|
- ResolveNameTime::Early,
|
||||||
|
- );
|
||||||
|
- let mut handles = Vec::<JoinHandle<()>>::new();
|
||||||
|
- (0..5).for_each(|i| {
|
||||||
|
- let rules_clone = rules.clone();
|
||||||
|
- let handle = std::thread::spawn(move || {
|
||||||
|
- println!("thread {}", i);
|
||||||
|
- println!("{}", rules_clone);
|
||||||
|
- });
|
||||||
|
-
|
||||||
|
- handles.push(handle);
|
||||||
|
- });
|
||||||
|
-
|
||||||
|
- for thread in handles {
|
||||||
|
- thread.join().unwrap();
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- clear_test_rules_dir("test_rules_share_among_threads");
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
#[test]
|
||||||
|
fn test_resolve_user_group() {
|
||||||
|
let mut rules = Rules::new(vec![], ResolveNameTime::Early);
|
||||||
|
@@ -2124,18 +2347,27 @@ SYMLINK += \"test111111\"",
|
||||||
|
touch_file(
|
||||||
|
"/tmp/devmaster/rules/02-c.rules",
|
||||||
|
false,
|
||||||
|
- Some(0o222),
|
||||||
|
+ Some(0o000),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
- let rules = Rules::new(
|
||||||
|
+ let rules = Arc::new(RwLock::new(Rules::new(
|
||||||
|
vec!["/tmp/devmaster/rules".to_string()],
|
||||||
|
ResolveNameTime::Never,
|
||||||
|
- );
|
||||||
|
+ )));
|
||||||
|
+
|
||||||
|
+ // Rules::parse_rules(Arc::new(RwLock::new(rules)));
|
||||||
|
|
||||||
|
- Rules::parse_rules(Arc::new(RwLock::new(rules)));
|
||||||
|
+ RuleFile::load_file("/tmp/devmaster/rules/00-a.rules".to_string(), rules.clone());
|
||||||
|
+
|
||||||
|
+ if nix::unistd::getuid().as_raw() != 0 {
|
||||||
|
+ assert!(catch_unwind(|| {
|
||||||
|
+ RuleFile::load_file("/tmp/devmaster/rules/02-c.rules".to_string(), rules.clone());
|
||||||
|
+ })
|
||||||
|
+ .is_err());
|
||||||
|
+ }
|
||||||
|
|
||||||
|
remove_dir_all("/tmp/devmaster").unwrap();
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
275
backport-test-devmaster-add-UT-for-execute-unit.patch
Normal file
275
backport-test-devmaster-add-UT-for-execute-unit.patch
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
From ac6f7187a7e696e1a90210cbcfb6c649385616ac Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Thu, 23 Nov 2023 20:17:49 +0800
|
||||||
|
Subject: [PATCH 084/103] test(devmaster): add UT for execute unit
|
||||||
|
|
||||||
|
---
|
||||||
|
exts/devmaster/src/lib/rules/exec_unit.rs | 255 ++++++++++++++++++++++
|
||||||
|
1 file changed, 255 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/rules/exec_unit.rs b/exts/devmaster/src/lib/rules/exec_unit.rs
|
||||||
|
index 828fe1af..93684659 100644
|
||||||
|
--- a/exts/devmaster/src/lib/rules/exec_unit.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/rules/exec_unit.rs
|
||||||
|
@@ -987,3 +987,258 @@ fn get_subst_type(
|
||||||
|
*idx = idx_b;
|
||||||
|
Ok(Some((subst, attr)))
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#[cfg(test)]
|
||||||
|
+mod test {
|
||||||
|
+ use super::*;
|
||||||
|
+ use crate::rules::rules_load::tests::create_tmp_file;
|
||||||
|
+ use device::utils::*;
|
||||||
|
+ use nix::sys::stat::{major, minor};
|
||||||
|
+ use std::cell::RefCell;
|
||||||
|
+ use std::fs::remove_dir_all;
|
||||||
|
+ use std::path::Path;
|
||||||
|
+ use std::rc::Rc;
|
||||||
|
+
|
||||||
|
+ #[test]
|
||||||
|
+ fn test_update_devnode() {
|
||||||
|
+ if let Err(e) = LoopDev::inner_process(
|
||||||
|
+ "/tmp/test_update_devnode_tmpfile",
|
||||||
|
+ 1024 * 1024 * 10,
|
||||||
|
+ |dev| {
|
||||||
|
+ let dev = Rc::new(RefCell::new(dev.shallow_clone().unwrap()));
|
||||||
|
+ let id = dev.borrow().get_device_id().unwrap();
|
||||||
|
+ let devnum = dev.borrow().get_devnum().unwrap();
|
||||||
|
+ let major_minor = format!("{}:{}", major(devnum), minor(devnum));
|
||||||
|
+
|
||||||
|
+ create_tmp_file("/tmp/test_update_devnode/data", &id, "", true);
|
||||||
|
+
|
||||||
|
+ dev.borrow().sealed.replace(true);
|
||||||
|
+ dev.borrow().set_base_path("/tmp/test_update_devnode");
|
||||||
|
+ dev.borrow().set_devgid("1").unwrap();
|
||||||
|
+ dev.borrow().set_devuid("1").unwrap();
|
||||||
|
+ dev.borrow().set_devmode("666").unwrap();
|
||||||
|
+ dev.borrow().add_devlink("test_update_devnode/bbb").unwrap();
|
||||||
|
+
|
||||||
|
+ let mut unit = ExecuteUnitData::new(dev.clone());
|
||||||
|
+ unit.clone_device_db().unwrap();
|
||||||
|
+
|
||||||
|
+ unit.update_devnode(&HashMap::new()).unwrap();
|
||||||
|
+ /* Record the devlink in db */
|
||||||
|
+ dev.borrow().update_db().unwrap();
|
||||||
|
+
|
||||||
|
+ let p = Path::new("/dev/test_update_devnode/bbb");
|
||||||
|
+ let p_block_s = format!("/dev/block/{}", major_minor);
|
||||||
|
+ let prior_p_s = format!("/run/devmaster/links/test_update_devnode\\x2fbbb/{}", id);
|
||||||
|
+ let prior_p = Path::new(&prior_p_s);
|
||||||
|
+ assert!(p.exists());
|
||||||
|
+ assert!(Path::new(&p_block_s).exists());
|
||||||
|
+ assert!(p
|
||||||
|
+ .canonicalize()
|
||||||
|
+ .unwrap()
|
||||||
|
+ .ends_with(&dev.borrow().get_sysname().unwrap()));
|
||||||
|
+ let _ = prior_p.symlink_metadata().unwrap(); // Test symlink exists.
|
||||||
|
+
|
||||||
|
+ let new_dev = Rc::new(RefCell::new(Device::from_device_id(&id).unwrap()));
|
||||||
|
+ new_dev.borrow().sealed.replace(true);
|
||||||
|
+ new_dev.borrow().set_base_path("/tmp/test_update_devnode");
|
||||||
|
+ new_dev.borrow().set_devgid("0").unwrap();
|
||||||
|
+ new_dev.borrow().set_devuid("0").unwrap();
|
||||||
|
+ new_dev.borrow().set_devmode("600").unwrap();
|
||||||
|
+
|
||||||
|
+ let mut unit = ExecuteUnitData::new(new_dev);
|
||||||
|
+ /* See the devlink in db, but it is absent in the current device object.
|
||||||
|
+ *
|
||||||
|
+ * Then update_devnode method will remove the devlink.
|
||||||
|
+ */
|
||||||
|
+ unit.clone_device_db().unwrap();
|
||||||
|
+ unit.update_devnode(&HashMap::new()).unwrap();
|
||||||
|
+
|
||||||
|
+ assert!(!Path::new("/dev/test_update_devnode/bbb").exists());
|
||||||
|
+ assert!(Path::new(&p_block_s).exists());
|
||||||
|
+ let _ = prior_p.symlink_metadata().unwrap_err(); // Test symlink does not exists.
|
||||||
|
+
|
||||||
|
+ remove_dir_all("/tmp/test_update_devnode").unwrap();
|
||||||
|
+
|
||||||
|
+ /* Non-block devices do not have device nodes, thus update_devnode method will do nothing. */
|
||||||
|
+ let lo = Rc::new(RefCell::new(
|
||||||
|
+ Device::from_subsystem_sysname("net", "lo").unwrap(),
|
||||||
|
+ ));
|
||||||
|
+
|
||||||
|
+ let mut unit = ExecuteUnitData::new(lo);
|
||||||
|
+ unit.update_devnode(&HashMap::new()).unwrap();
|
||||||
|
+
|
||||||
|
+ /* Cover error paths when uid, gid or mode is not set. */
|
||||||
|
+ let dev = Rc::new(RefCell::new(Device::from_device_id(&id).unwrap()));
|
||||||
|
+ dev.borrow().sealed.replace(true);
|
||||||
|
+ dev.borrow().add_devlink("test_update_devnode/xxx").unwrap();
|
||||||
|
+
|
||||||
|
+ let mut unit = ExecuteUnitData::new(dev.clone());
|
||||||
|
+ unit.clone_device_db().unwrap();
|
||||||
|
+ unit.update_devnode(&HashMap::new()).unwrap();
|
||||||
|
+
|
||||||
|
+ let p = Path::new("/dev/test_update_devnode/xxx");
|
||||||
|
+ let prior_p_s = format!("/run/devmaster/links/test_update_devnode\\x2fxxx/{}", id);
|
||||||
|
+ assert!(p.exists());
|
||||||
|
+ assert!(Path::new(&p_block_s).exists());
|
||||||
|
+ assert!(p
|
||||||
|
+ .canonicalize()
|
||||||
|
+ .unwrap()
|
||||||
|
+ .ends_with(&dev.borrow().get_sysname().unwrap()));
|
||||||
|
+ let _ = Path::new(&prior_p_s).symlink_metadata().unwrap(); // Test symlink exists.
|
||||||
|
+
|
||||||
|
+ cleanup_node(dev).unwrap();
|
||||||
|
+
|
||||||
|
+ assert!(!p.exists());
|
||||||
|
+ assert!(!Path::new(&p_block_s).exists());
|
||||||
|
+ let _ = Path::new(&prior_p_s).symlink_metadata().unwrap_err(); // Test symlink exists.
|
||||||
|
+
|
||||||
|
+ Ok(())
|
||||||
|
+ },
|
||||||
|
+ ) {
|
||||||
|
+ assert!(e.is_errno(nix::Error::EACCES) || e.is_errno(nix::Error::EBUSY));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ #[test]
|
||||||
|
+ fn test_subst_format() {
|
||||||
|
+ if let Err(e) =
|
||||||
|
+ LoopDev::inner_process("/tmp/test_subst_format_tmpfile", 1024 * 1024 * 10, |dev| {
|
||||||
|
+ let dev = Rc::new(RefCell::new(dev.shallow_clone().unwrap()));
|
||||||
|
+ let mut unit = ExecuteUnitData::new(dev.clone());
|
||||||
|
+ let devnum = dev.borrow().get_devnum().unwrap();
|
||||||
|
+ let major_minor = format!("{}:{}", major(devnum), minor(devnum));
|
||||||
|
+ let sysname = dev.borrow().get_sysname().unwrap();
|
||||||
|
+
|
||||||
|
+ assert_eq!(
|
||||||
|
+ unit.subst_format(FormatSubstitutionType::Attr, Some("dev".to_string()))
|
||||||
|
+ .unwrap(),
|
||||||
|
+ major_minor
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ assert_eq!(
|
||||||
|
+ unit.subst_format(
|
||||||
|
+ FormatSubstitutionType::Attr,
|
||||||
|
+ Some(format!("[block/{}]dev", sysname))
|
||||||
|
+ )
|
||||||
|
+ .unwrap(),
|
||||||
|
+ major_minor
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ unit.set_parent(Some(Rc::new(RefCell::new(
|
||||||
|
+ Device::from_subsystem_sysname("net", "lo").unwrap(),
|
||||||
|
+ ))));
|
||||||
|
+
|
||||||
|
+ /* Get the sysattr of parent device set in unit. */
|
||||||
|
+ assert_eq!(
|
||||||
|
+ unit.subst_format(FormatSubstitutionType::Attr, Some("ifindex".to_string()))
|
||||||
|
+ .unwrap(),
|
||||||
|
+ "1".to_string()
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ /* Invalid sysattr will be replaced with empty string. */
|
||||||
|
+ assert!(unit
|
||||||
|
+ .subst_format(
|
||||||
|
+ FormatSubstitutionType::Attr,
|
||||||
|
+ Some("asdfasdfads".to_string())
|
||||||
|
+ )
|
||||||
|
+ .unwrap()
|
||||||
|
+ .is_empty());
|
||||||
|
+
|
||||||
|
+ dev.borrow().add_property("hello", "world").unwrap();
|
||||||
|
+
|
||||||
|
+ assert_eq!(
|
||||||
|
+ unit.subst_format(FormatSubstitutionType::Env, Some("hello".to_string()))
|
||||||
|
+ .unwrap(),
|
||||||
|
+ "world".to_string()
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ assert!(unit
|
||||||
|
+ .subst_format(FormatSubstitutionType::Env, Some("asdfgasd".to_string()))
|
||||||
|
+ .unwrap()
|
||||||
|
+ .is_empty());
|
||||||
|
+
|
||||||
|
+ assert!(unit
|
||||||
|
+ .subst_format(FormatSubstitutionType::Driver, None)
|
||||||
|
+ .unwrap()
|
||||||
|
+ .is_empty());
|
||||||
|
+
|
||||||
|
+ assert_eq!(
|
||||||
|
+ unit.subst_format(FormatSubstitutionType::Id, None).unwrap(),
|
||||||
|
+ "lo".to_string()
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ let major = unit
|
||||||
|
+ .subst_format(FormatSubstitutionType::Major, None)
|
||||||
|
+ .unwrap();
|
||||||
|
+ let minor = unit
|
||||||
|
+ .subst_format(FormatSubstitutionType::Minor, None)
|
||||||
|
+ .unwrap();
|
||||||
|
+ assert_eq!(format!("{}:{}", major, minor), major_minor);
|
||||||
|
+
|
||||||
|
+ unit.program_result = "hello world test".to_string();
|
||||||
|
+ assert_eq!(
|
||||||
|
+ unit.subst_format(FormatSubstitutionType::Result, None)
|
||||||
|
+ .unwrap(),
|
||||||
|
+ "hello world test".to_string()
|
||||||
|
+ );
|
||||||
|
+ assert_eq!(
|
||||||
|
+ unit.subst_format(FormatSubstitutionType::Result, Some("0".to_string()))
|
||||||
|
+ .unwrap(),
|
||||||
|
+ "hello".to_string()
|
||||||
|
+ );
|
||||||
|
+ assert_eq!(
|
||||||
|
+ unit.subst_format(FormatSubstitutionType::Result, Some("1+".to_string()))
|
||||||
|
+ .unwrap(),
|
||||||
|
+ "world test".to_string()
|
||||||
|
+ );
|
||||||
|
+ unit.subst_format(FormatSubstitutionType::Result, Some("x".to_string()))
|
||||||
|
+ .unwrap_err();
|
||||||
|
+ unit.subst_format(FormatSubstitutionType::Result, Some("x+".to_string()))
|
||||||
|
+ .unwrap_err();
|
||||||
|
+
|
||||||
|
+ assert!(unit
|
||||||
|
+ .subst_format(FormatSubstitutionType::Result, Some("3+".to_string()))
|
||||||
|
+ .unwrap()
|
||||||
|
+ .is_empty());
|
||||||
|
+
|
||||||
|
+ assert_eq!(
|
||||||
|
+ unit.subst_format(FormatSubstitutionType::Name, None)
|
||||||
|
+ .unwrap(),
|
||||||
|
+ sysname
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ unit.name = "test".to_string();
|
||||||
|
+ assert_eq!(
|
||||||
|
+ unit.subst_format(FormatSubstitutionType::Name, None)
|
||||||
|
+ .unwrap(),
|
||||||
|
+ "test".to_string(),
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ dev.borrow().add_devlink("test").unwrap();
|
||||||
|
+ dev.borrow().sealed.replace(true);
|
||||||
|
+ assert_eq!(
|
||||||
|
+ unit.subst_format(FormatSubstitutionType::Links, None)
|
||||||
|
+ .unwrap(),
|
||||||
|
+ "test".to_string(),
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ unit.subst_format(FormatSubstitutionType::Invalid, None)
|
||||||
|
+ .unwrap_err();
|
||||||
|
+
|
||||||
|
+ Ok(())
|
||||||
|
+ })
|
||||||
|
+ {
|
||||||
|
+ assert!(e.is_errno(nix::Error::EACCES) || e.is_errno(nix::Error::EBUSY));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ let dev = Rc::new(RefCell::new(
|
||||||
|
+ Device::from_subsystem_sysname("net", "lo").unwrap(),
|
||||||
|
+ ));
|
||||||
|
+ let unit = ExecuteUnitData::new(dev);
|
||||||
|
+ assert_eq!(
|
||||||
|
+ unit.subst_format(FormatSubstitutionType::Name, None)
|
||||||
|
+ .unwrap(),
|
||||||
|
+ "lo".to_string()
|
||||||
|
+ );
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,134 @@
|
|||||||
|
From e0d987db5fb3a13b07e148991af3aa8c434cb074 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Fri, 24 Nov 2023 15:09:11 +0800
|
||||||
|
Subject: [PATCH 086/103] test(devmaster): add UT for node and modify the
|
||||||
|
displaying format of rules token
|
||||||
|
|
||||||
|
---
|
||||||
|
exts/devmaster/src/lib/rules/node.rs | 103 ++++++++++++++++++++++++++-
|
||||||
|
1 file changed, 101 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/rules/node.rs b/exts/devmaster/src/lib/rules/node.rs
|
||||||
|
index 9fba906e..de600f72 100644
|
||||||
|
--- a/exts/devmaster/src/lib/rules/node.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/rules/node.rs
|
||||||
|
@@ -702,10 +702,11 @@ pub(crate) fn cleanup_prior_dir() -> Result<()> {
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
- use basic::fs_util::is_symlink;
|
||||||
|
+ use basic::fs_util::{is_symlink, touch_file};
|
||||||
|
+ use device::device_enumerator::*;
|
||||||
|
use device::utils::LoopDev;
|
||||||
|
use nix::unistd::unlink;
|
||||||
|
- use std::fs::{self, read_link, remove_dir, remove_dir_all};
|
||||||
|
+ use std::fs::{self, read_link, remove_dir, remove_dir_all, remove_file};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_update_node() {
|
||||||
|
@@ -816,4 +817,102 @@ mod test {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ #[test]
|
||||||
|
+ fn test_escape_prior_dir() {
|
||||||
|
+ assert_eq!(&escape_prior_dir("aaa/bbb"), "aaa\\x2fbbb");
|
||||||
|
+ assert_eq!(&escape_prior_dir("aaa\\bbb"), "aaa\\x5cbbb");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ #[test]
|
||||||
|
+ fn test_get_prior_dir() {
|
||||||
|
+ assert_eq!(
|
||||||
|
+ get_prior_dir("/../xxx").unwrap_err().get_errno(),
|
||||||
|
+ nix::Error::EINVAL
|
||||||
|
+ );
|
||||||
|
+ assert_eq!(
|
||||||
|
+ get_prior_dir("xxx").unwrap_err().get_errno(),
|
||||||
|
+ nix::Error::EINVAL
|
||||||
|
+ );
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ #[test]
|
||||||
|
+ fn test_prior_dir_read_one() {
|
||||||
|
+ if let Err(e) =
|
||||||
|
+ LoopDev::inner_process("/tmp/test_prior_dir_read_one", 1024 * 1024 * 10, |dev| {
|
||||||
|
+ let devname = dev.get_devname().unwrap();
|
||||||
|
+ let id = dev.get_device_id().unwrap();
|
||||||
|
+
|
||||||
|
+ create_dir_all("/tmp/test_prior_dir_read_one_dir").unwrap();
|
||||||
|
+
|
||||||
|
+ let p = Path::new("/tmp/test_prior_dir_read_one_dir");
|
||||||
|
+
|
||||||
|
+ let dir = nix::dir::Dir::open(p, OFlag::O_DIRECTORY, Mode::S_IRWXU).unwrap();
|
||||||
|
+
|
||||||
|
+ /* Missing link priority. */
|
||||||
|
+ symlink(
|
||||||
|
+ &format!(":{}", devname),
|
||||||
|
+ &format!("/tmp/test_prior_dir_read_one_dir/{}", id),
|
||||||
|
+ false,
|
||||||
|
+ )
|
||||||
|
+ .unwrap();
|
||||||
|
+
|
||||||
|
+ prior_dir_read_one(dir.as_raw_fd(), &id).unwrap_err();
|
||||||
|
+
|
||||||
|
+ /* Non-existing device node path. */
|
||||||
|
+ symlink(
|
||||||
|
+ "0:xxx",
|
||||||
|
+ &format!("/tmp/test_prior_dir_read_one_dir/{}", id),
|
||||||
|
+ false,
|
||||||
|
+ )
|
||||||
|
+ .unwrap();
|
||||||
|
+
|
||||||
|
+ prior_dir_read_one(dir.as_raw_fd(), &id).unwrap_err();
|
||||||
|
+
|
||||||
|
+ remove_dir_all("/tmp/test_prior_dir_read_one_dir").unwrap();
|
||||||
|
+
|
||||||
|
+ Ok(())
|
||||||
|
+ })
|
||||||
|
+ {
|
||||||
|
+ assert!(e.is_errno(nix::Error::EACCES) || e.is_errno(nix::Error::EBUSY));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ #[test]
|
||||||
|
+ fn test_node_symlink() {
|
||||||
|
+ if let Err(e) = LoopDev::inner_process("/tmp/test_node_symlink", 1024 * 1024 * 10, |dev| {
|
||||||
|
+ let dev = Rc::new(RefCell::new(dev.shallow_clone().unwrap()));
|
||||||
|
+
|
||||||
|
+ touch_file(
|
||||||
|
+ "/tmp/test_node_symlink_link",
|
||||||
|
+ false,
|
||||||
|
+ Some(0o777),
|
||||||
|
+ None,
|
||||||
|
+ None,
|
||||||
|
+ )
|
||||||
|
+ .unwrap();
|
||||||
|
+
|
||||||
|
+ /* If the target exists, the symlink will not be created. */
|
||||||
|
+ node_symlink(dev, "", "/tmp/test_node_symlink_link").unwrap_err();
|
||||||
|
+
|
||||||
|
+ remove_file("/tmp/test_node_symlink_link").unwrap();
|
||||||
|
+
|
||||||
|
+ Ok(())
|
||||||
|
+ }) {
|
||||||
|
+ assert!(e.is_errno(nix::Error::EACCES) || e.is_errno(nix::Error::EBUSY));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ #[test]
|
||||||
|
+ fn test_device_get_symlink_by_devnum() {
|
||||||
|
+ let mut e = DeviceEnumerator::new();
|
||||||
|
+ e.set_enumerator_type(DeviceEnumerationType::Devices);
|
||||||
|
+ e.add_match_subsystem("tty", true).unwrap();
|
||||||
|
+ e.add_match_subsystem("block", true).unwrap();
|
||||||
|
+
|
||||||
|
+ for d in e.iter() {
|
||||||
|
+ let s = device_get_symlink_by_devnum(d).unwrap();
|
||||||
|
+ println!("{}", s);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
947
backport-test-devmaster-add-UT-for-rules-applying.patch
Normal file
947
backport-test-devmaster-add-UT-for-rules-applying.patch
Normal file
@ -0,0 +1,947 @@
|
|||||||
|
From 9eab33e9cfaa97cac808ba5ebc3c2d2c30157681 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Wed, 22 Nov 2023 15:45:16 +0800
|
||||||
|
Subject: [PATCH 079/103] test(devmaster): add UT for rules applying
|
||||||
|
|
||||||
|
---
|
||||||
|
exts/devmaster/src/lib/rules/exec_mgr.rs | 917 +++++++++++++++++++++++
|
||||||
|
1 file changed, 917 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/rules/exec_mgr.rs b/exts/devmaster/src/lib/rules/exec_mgr.rs
|
||||||
|
index 66c1a06c..03da901d 100644
|
||||||
|
--- a/exts/devmaster/src/lib/rules/exec_mgr.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/rules/exec_mgr.rs
|
||||||
|
@@ -2140,8 +2140,13 @@ impl RuleLine {
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
+ use std::fs::remove_file;
|
||||||
|
+
|
||||||
|
use super::*;
|
||||||
|
+ use crate::rules::rules_load::tests::create_tmp_file;
|
||||||
|
use crate::rules::FormatSubstitutionType;
|
||||||
|
+ use device::utils::LoopDev;
|
||||||
|
+ use log::{init_log, Level};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
@@ -2294,4 +2299,916 @@ mod tests {
|
||||||
|
assert_eq!(unit.apply_format("$parent", false).unwrap(), "sda");
|
||||||
|
assert_eq!(unit.apply_format("$devnode", false).unwrap(), "/dev/sda1");
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ impl ExecuteManager {
|
||||||
|
+ #[allow(clippy::too_many_arguments)]
|
||||||
|
+ fn test_apply_one_rule_token(
|
||||||
|
+ &self,
|
||||||
|
+ key: &str,
|
||||||
|
+ attr: &str,
|
||||||
|
+ op: &str,
|
||||||
|
+ value: &str,
|
||||||
|
+ rules: Arc<RwLock<Rules>>,
|
||||||
|
+ rule_line: Arc<RwLock<Option<RuleLine>>>,
|
||||||
|
+ device: Rc<RefCell<Device>>,
|
||||||
|
+ ) -> Result<bool> {
|
||||||
|
+ let token = RuleToken::parse_token(
|
||||||
|
+ key.to_string(),
|
||||||
|
+ if attr.is_empty() {
|
||||||
|
+ None
|
||||||
|
+ } else {
|
||||||
|
+ Some(attr.to_string())
|
||||||
|
+ },
|
||||||
|
+ op.to_string(),
|
||||||
|
+ value.to_string(),
|
||||||
|
+ rules,
|
||||||
|
+ rule_line,
|
||||||
|
+ )
|
||||||
|
+ .unwrap();
|
||||||
|
+ *self.current_rule_token.borrow_mut() = Arc::new(RwLock::new(Some(token)));
|
||||||
|
+ self.apply_rule_token(device)
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ #[test]
|
||||||
|
+ fn test_apply_rules() {
|
||||||
|
+ init_log(
|
||||||
|
+ "test_apply_rules",
|
||||||
|
+ Level::Debug,
|
||||||
|
+ vec!["console"],
|
||||||
|
+ "",
|
||||||
|
+ 0,
|
||||||
|
+ 0,
|
||||||
|
+ false,
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ let device = Rc::new(RefCell::new(
|
||||||
|
+ Device::from_subsystem_sysname("net", "lo").unwrap(),
|
||||||
|
+ ));
|
||||||
|
+ device.borrow().set_base_path("/tmp/devmaster");
|
||||||
|
+ let rules = Arc::new(RwLock::new(Rules::new(vec![], ResolveNameTime::Early)));
|
||||||
|
+ let rule_file = Arc::new(RwLock::new(Some(RuleFile::new("".to_string()))));
|
||||||
|
+ let rule_line = Arc::new(RwLock::new(Some(RuleLine::new(
|
||||||
|
+ "".to_string(),
|
||||||
|
+ 0,
|
||||||
|
+ rule_file,
|
||||||
|
+ ))));
|
||||||
|
+ let unit = ExecuteUnit::new(device.clone());
|
||||||
|
+ let mgr = ExecuteManager::new(Arc::new(RwLock::new(Cache::new(vec![], vec![]))));
|
||||||
|
+ *mgr.current_unit.borrow_mut() = Some(unit);
|
||||||
|
+
|
||||||
|
+ device.borrow().set_action_from_string("change").unwrap();
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "ACTION",
|
||||||
|
+ "",
|
||||||
|
+ "==",
|
||||||
|
+ "change",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+ assert!(!mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "ACTION",
|
||||||
|
+ "",
|
||||||
|
+ "==",
|
||||||
|
+ "add",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "DEVPATH",
|
||||||
|
+ "",
|
||||||
|
+ "==",
|
||||||
|
+ "*lo",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(!mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "ENV",
|
||||||
|
+ "xxx",
|
||||||
|
+ "==",
|
||||||
|
+ "xxx",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ device.borrow().add_tag("xxx", true);
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "TAG",
|
||||||
|
+ "",
|
||||||
|
+ "==",
|
||||||
|
+ "xxx",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "SUBSYSTEM",
|
||||||
|
+ "",
|
||||||
|
+ "==",
|
||||||
|
+ "net",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "TEST",
|
||||||
|
+ "444",
|
||||||
|
+ "==",
|
||||||
|
+ "[net/lo]ifindex",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "TEST",
|
||||||
|
+ "644",
|
||||||
|
+ "==",
|
||||||
|
+ "queues/*/rps_cpus",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "TEST",
|
||||||
|
+ "444",
|
||||||
|
+ "==",
|
||||||
|
+ "ifindex",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "TEST",
|
||||||
|
+ "",
|
||||||
|
+ "!=",
|
||||||
|
+ "asfsdfa",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(!mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "TEST",
|
||||||
|
+ "444",
|
||||||
|
+ "==",
|
||||||
|
+ "$attr",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ create_tmp_file(
|
||||||
|
+ "/tmp",
|
||||||
|
+ "property",
|
||||||
|
+ "HELLO=WORLD
|
||||||
|
+GOOD=LUCK",
|
||||||
|
+ true,
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "IMPORT",
|
||||||
|
+ "file",
|
||||||
|
+ "==",
|
||||||
|
+ "/tmp/property",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert_eq!(
|
||||||
|
+ &device.borrow().get_property_value("HELLO").unwrap(),
|
||||||
|
+ "WORLD"
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ assert_eq!(&device.borrow().get_property_value("GOOD").unwrap(), "LUCK");
|
||||||
|
+
|
||||||
|
+ remove_file("/tmp/property").unwrap();
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "IMPORT",
|
||||||
|
+ "program",
|
||||||
|
+ "==",
|
||||||
|
+ "echo WATER=FLOW",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+ assert_eq!(
|
||||||
|
+ &device.borrow().get_property_value("WATER").unwrap(),
|
||||||
|
+ "FLOW"
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ create_tmp_file(
|
||||||
|
+ "/tmp/devmaster/data",
|
||||||
|
+ &device.borrow().get_device_id().unwrap(),
|
||||||
|
+ "E:BLACK=PINK",
|
||||||
|
+ true,
|
||||||
|
+ );
|
||||||
|
+ mgr.current_unit
|
||||||
|
+ .borrow()
|
||||||
|
+ .as_ref()
|
||||||
|
+ .unwrap()
|
||||||
|
+ .clone_device_db()
|
||||||
|
+ .unwrap();
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "IMPORT",
|
||||||
|
+ "db",
|
||||||
|
+ "==",
|
||||||
|
+ "BLACK",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+ assert_eq!(
|
||||||
|
+ &device.borrow().get_property_value("BLACK").unwrap(),
|
||||||
|
+ "PINK"
|
||||||
|
+ );
|
||||||
|
+ remove_file(&format!(
|
||||||
|
+ "/tmp/devmaster/data/{}",
|
||||||
|
+ device.borrow().get_device_id().unwrap()
|
||||||
|
+ ))
|
||||||
|
+ .unwrap();
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "IMPORT",
|
||||||
|
+ "cmdline",
|
||||||
|
+ "==",
|
||||||
|
+ "root",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+ assert!(!device
|
||||||
|
+ .borrow()
|
||||||
|
+ .get_property_value("root")
|
||||||
|
+ .unwrap()
|
||||||
|
+ .is_empty());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "IMPORT",
|
||||||
|
+ "cmdline",
|
||||||
|
+ "!=",
|
||||||
|
+ "asdfasdf",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(!mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "PROGRAM",
|
||||||
|
+ "",
|
||||||
|
+ "==",
|
||||||
|
+ "echo $attr",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(!mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "PROGRAM",
|
||||||
|
+ "",
|
||||||
|
+ "==",
|
||||||
|
+ "cat /tmp/test_nonexist",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(!mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "PROGRAM",
|
||||||
|
+ "",
|
||||||
|
+ "==",
|
||||||
|
+ "asdfasdf",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "PROGRAM",
|
||||||
|
+ "",
|
||||||
|
+ "==",
|
||||||
|
+ "echo hello",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "RESULT",
|
||||||
|
+ "",
|
||||||
|
+ "==",
|
||||||
|
+ "hello",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "OPTIONS",
|
||||||
|
+ "",
|
||||||
|
+ "+=",
|
||||||
|
+ "string_escape=none",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "OPTIONS",
|
||||||
|
+ "",
|
||||||
|
+ "+=",
|
||||||
|
+ "string_escape=replace",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "OPTIONS",
|
||||||
|
+ "",
|
||||||
|
+ "+=",
|
||||||
|
+ "db_persist",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "OPTIONS",
|
||||||
|
+ "",
|
||||||
|
+ "+=",
|
||||||
|
+ "db_persist",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "OPTIONS",
|
||||||
|
+ "",
|
||||||
|
+ "+=",
|
||||||
|
+ "link_priority=1",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "OWNER",
|
||||||
|
+ "",
|
||||||
|
+ "=",
|
||||||
|
+ "0",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "GROUP",
|
||||||
|
+ "",
|
||||||
|
+ "=",
|
||||||
|
+ "0",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "MODE",
|
||||||
|
+ "",
|
||||||
|
+ "=",
|
||||||
|
+ "777",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ rules.write().unwrap().resolve_name_time = ResolveNameTime::Late;
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "OWNER",
|
||||||
|
+ "",
|
||||||
|
+ "=",
|
||||||
|
+ "root",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "GROUP",
|
||||||
|
+ "",
|
||||||
|
+ "=",
|
||||||
|
+ "root",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ mgr.test_apply_one_rule_token(
|
||||||
|
+ "ENV",
|
||||||
|
+ "mode",
|
||||||
|
+ "=",
|
||||||
|
+ "777",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap();
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "MODE",
|
||||||
|
+ "",
|
||||||
|
+ "=",
|
||||||
|
+ "$env{mode}",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+ rules.write().unwrap().resolve_name_time = ResolveNameTime::Early;
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "OWNER",
|
||||||
|
+ "",
|
||||||
|
+ ":=",
|
||||||
|
+ "0",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "GROUP",
|
||||||
|
+ "",
|
||||||
|
+ ":=",
|
||||||
|
+ "0",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "MODE",
|
||||||
|
+ "",
|
||||||
|
+ ":=",
|
||||||
|
+ "777",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "OWNER",
|
||||||
|
+ "",
|
||||||
|
+ "=",
|
||||||
|
+ "0",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "GROUP",
|
||||||
|
+ "",
|
||||||
|
+ "=",
|
||||||
|
+ "0",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "MODE",
|
||||||
|
+ "",
|
||||||
|
+ "=",
|
||||||
|
+ "777",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "ENV",
|
||||||
|
+ "BLACK",
|
||||||
|
+ "=",
|
||||||
|
+ "YELLOW",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+ assert_eq!(
|
||||||
|
+ &device.borrow().get_property_value("BLACK").unwrap(),
|
||||||
|
+ "YELLOW"
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "TAG",
|
||||||
|
+ "",
|
||||||
|
+ "+=",
|
||||||
|
+ "aaa",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+ assert!(device.borrow().has_tag("aaa").unwrap());
|
||||||
|
+ assert!(device.borrow().has_current_tag("aaa").unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "TAG",
|
||||||
|
+ "",
|
||||||
|
+ "-=",
|
||||||
|
+ "aaa",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+ assert!(device.borrow().has_tag("aaa").unwrap());
|
||||||
|
+ assert!(!device.borrow().has_current_tag("aaa").unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "TAG",
|
||||||
|
+ "",
|
||||||
|
+ "=",
|
||||||
|
+ "bbb",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+ assert!(!device.borrow().has_tag("aaa").unwrap());
|
||||||
|
+ assert!(!device.borrow().has_current_tag("aaa").unwrap());
|
||||||
|
+ assert!(device.borrow().has_tag("bbb").unwrap());
|
||||||
|
+ assert!(device.borrow().has_current_tag("bbb").unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "NAME",
|
||||||
|
+ "",
|
||||||
|
+ ":=",
|
||||||
|
+ "test",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "NAME",
|
||||||
|
+ "",
|
||||||
|
+ "=",
|
||||||
|
+ "test",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+ if mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "ATTR",
|
||||||
|
+ "ifalias",
|
||||||
|
+ "=",
|
||||||
|
+ "test",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .is_ok()
|
||||||
|
+ {
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "ATTR",
|
||||||
|
+ "ifalias",
|
||||||
|
+ "==",
|
||||||
|
+ "test",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "RUN",
|
||||||
|
+ "builtin",
|
||||||
|
+ "+=",
|
||||||
|
+ "path_id",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "ENV",
|
||||||
|
+ "PAPER",
|
||||||
|
+ "+=",
|
||||||
|
+ "",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "ENV",
|
||||||
|
+ "PAPER",
|
||||||
|
+ "==",
|
||||||
|
+ "",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "ENV",
|
||||||
|
+ "PAPER",
|
||||||
|
+ "=",
|
||||||
|
+ "",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "ENV",
|
||||||
|
+ "PAPER",
|
||||||
|
+ "==",
|
||||||
|
+ "",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "ENV",
|
||||||
|
+ "PAPER",
|
||||||
|
+ "+=",
|
||||||
|
+ "BOOK",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+ assert_eq!(
|
||||||
|
+ &device.borrow().get_property_value("PAPER").unwrap(),
|
||||||
|
+ "BOOK"
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ assert!(!mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "IMPORT",
|
||||||
|
+ "builtin",
|
||||||
|
+ "==",
|
||||||
|
+ "path_id $attr",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "TAG",
|
||||||
|
+ "",
|
||||||
|
+ "+=",
|
||||||
|
+ "$env",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "NAME",
|
||||||
|
+ "",
|
||||||
|
+ "=",
|
||||||
|
+ "$env",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "ATTR",
|
||||||
|
+ "ifalias",
|
||||||
|
+ "=",
|
||||||
|
+ "$env",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "RUN",
|
||||||
|
+ "",
|
||||||
|
+ "+=",
|
||||||
|
+ "$env",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ device,
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ // /* TODO rules */
|
||||||
|
+ // let rules_c = rules.clone();
|
||||||
|
+ // let rule_line_c = rule_line.clone();
|
||||||
|
+ // let device_c = device.clone();
|
||||||
|
+ // assert!(catch_unwind(move || {
|
||||||
|
+ // let _ = mgr.test_apply_one_rule_token(
|
||||||
|
+ // "CONST",
|
||||||
|
+ // "virt",
|
||||||
|
+ // "==",
|
||||||
|
+ // "xxx",
|
||||||
|
+ // rules_c,
|
||||||
|
+ // rule_line_c,
|
||||||
|
+ // device_c,
|
||||||
|
+ // );
|
||||||
|
+ // })
|
||||||
|
+ // .is_err());
|
||||||
|
+
|
||||||
|
+ match LoopDev::new("/tmp/test_apply_rules", 1024 * 1024 * 10) {
|
||||||
|
+ Ok(lo) => {
|
||||||
|
+ let devpath = lo.get_device_path().unwrap();
|
||||||
|
+ let dev = Rc::new(RefCell::new(
|
||||||
|
+ Device::from_path(devpath.to_str().unwrap()).unwrap(),
|
||||||
|
+ ));
|
||||||
|
+ dev.borrow().set_base_path("/tmp/devmaster");
|
||||||
|
+
|
||||||
|
+ dev.borrow().add_devlink("/dev/test").unwrap();
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "SYMLINK",
|
||||||
|
+ "",
|
||||||
|
+ "==",
|
||||||
|
+ "/dev/test",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ dev.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "SYMLINK",
|
||||||
|
+ "",
|
||||||
|
+ "!=",
|
||||||
|
+ "/dev/xxx",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ dev.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "SYMLINK",
|
||||||
|
+ "",
|
||||||
|
+ "+=",
|
||||||
|
+ "xxx",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ dev.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+ assert!(dev.borrow().has_devlink("/dev/xxx"));
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "OPTIONS",
|
||||||
|
+ "",
|
||||||
|
+ "+=",
|
||||||
|
+ "watch",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ dev.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token(
|
||||||
|
+ "OPTIONS",
|
||||||
|
+ "",
|
||||||
|
+ ":=",
|
||||||
|
+ "watch",
|
||||||
|
+ rules.clone(),
|
||||||
|
+ rule_line.clone(),
|
||||||
|
+ dev.clone(),
|
||||||
|
+ )
|
||||||
|
+ .unwrap());
|
||||||
|
+
|
||||||
|
+ assert!(mgr
|
||||||
|
+ .test_apply_one_rule_token("OPTIONS", "", "=", "watch", rules, rule_line, dev,)
|
||||||
|
+ .unwrap());
|
||||||
|
+ }
|
||||||
|
+ Err(e) => {
|
||||||
|
+ assert!(e.is_errno(nix::Error::EACCES) || e.is_errno(nix::Error::EBUSY));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
147
backport-test-devmaster-add-UT-for-rules-module.patch
Normal file
147
backport-test-devmaster-add-UT-for-rules-module.patch
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
From 124af0af5a9e28d70a362463a69a5daab3b70712 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Fri, 24 Nov 2023 15:08:07 +0800
|
||||||
|
Subject: [PATCH 085/103] test(devmaster): add UT for rules module
|
||||||
|
|
||||||
|
---
|
||||||
|
exts/devmaster/src/lib/rules/mod.rs | 105 ++++++++++++++++++++++++----
|
||||||
|
1 file changed, 90 insertions(+), 15 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/rules/mod.rs b/exts/devmaster/src/lib/rules/mod.rs
|
||||||
|
index a88a5f99..b5ee3c7d 100644
|
||||||
|
--- a/exts/devmaster/src/lib/rules/mod.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/rules/mod.rs
|
||||||
|
@@ -218,9 +218,12 @@ impl RuleToken {
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn get_token_content(&self) -> String {
|
||||||
|
if let Some(attribute) = self.get_token_attribute() {
|
||||||
|
- format!("{}{{{}}}{}{}", self.r#type, attribute, self.op, self.value)
|
||||||
|
+ format!(
|
||||||
|
+ "{}{{{}}}{}\"{}\"",
|
||||||
|
+ self.r#type, attribute, self.op, self.value
|
||||||
|
+ )
|
||||||
|
} else {
|
||||||
|
- format!("{}{}{}", self.r#type, self.op, self.value)
|
||||||
|
+ format!("{}{}\"{}\"", self.r#type, self.op, self.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -316,7 +319,7 @@ impl Display for TokenType {
|
||||||
|
Self::MatchParentsDriver => "DRIVERS",
|
||||||
|
Self::MatchParentsAttr => "ATTRS",
|
||||||
|
Self::MatchParentsTag => "TAGS",
|
||||||
|
- Self::MatchResult => "RESULTS",
|
||||||
|
+ Self::MatchResult => "RESULT",
|
||||||
|
Self::MatchTest => "TEST",
|
||||||
|
Self::MatchProgram => "PROGRAM",
|
||||||
|
Self::MatchImportFile
|
||||||
|
@@ -567,18 +570,6 @@ bitflags! {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-// bitflags! {
|
||||||
|
-// /// value matching type
|
||||||
|
-// pub(crate) struct MatchType: u8 {
|
||||||
|
-// /// match empty string
|
||||||
|
-// const EMPTY = 1<<0;
|
||||||
|
-// /// use shell glob parttern to match
|
||||||
|
-// const PATTERN = 1<<1;
|
||||||
|
-// /// match "subsystem", "bus", or "class"
|
||||||
|
-// const SUBSYSTEM = 1<<2;
|
||||||
|
-// }
|
||||||
|
-// }
|
||||||
|
-
|
||||||
|
/// match type
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
@@ -744,3 +735,87 @@ pub(crate) enum EscapeType {
|
||||||
|
None,
|
||||||
|
Replace,
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#[cfg(test)]
|
||||||
|
+mod test {
|
||||||
|
+ use log::{init_log, Level};
|
||||||
|
+
|
||||||
|
+ use super::*;
|
||||||
|
+ use crate::rules::rules_load::tests::create_tmp_file;
|
||||||
|
+
|
||||||
|
+ #[test]
|
||||||
|
+ fn test_rules_display() {
|
||||||
|
+ init_log(
|
||||||
|
+ "test_rules_display",
|
||||||
|
+ Level::Debug,
|
||||||
|
+ vec!["console"],
|
||||||
|
+ "",
|
||||||
|
+ 0,
|
||||||
|
+ 0,
|
||||||
|
+ false,
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ create_tmp_file(
|
||||||
|
+ "/tmp/test_rules_display/rules.d",
|
||||||
|
+ "00-test.rules",
|
||||||
|
+ "
|
||||||
|
+ACTION==\"change\"
|
||||||
|
+DEVPATH==\"xxx\"
|
||||||
|
+KERNEL==\"xxx\"
|
||||||
|
+SYMLINK==\"xxx\"
|
||||||
|
+SYMLINK+=\"xxx\"
|
||||||
|
+NAME==\"xxx\"
|
||||||
|
+NAME=\"x\"
|
||||||
|
+ENV{x}=\"x\"
|
||||||
|
+ENV{x}==\"x\"
|
||||||
|
+CONST{virt}==\"x\"
|
||||||
|
+TAG+=\"x\"
|
||||||
|
+TAG==\"x\"
|
||||||
|
+SUBSYSTEM==\"x\"
|
||||||
|
+DRIVER==\"x\"
|
||||||
|
+ATTR{x}==\"x\"
|
||||||
|
+ATTR{x}=\"x\"
|
||||||
|
+SYSCTL{x}==\"x\"
|
||||||
|
+SYSCTL{x}=\"x\"
|
||||||
|
+KERNELS==\"x\"
|
||||||
|
+SUBSYSTEMS==\"x\"
|
||||||
|
+DRIVERS==\"x\"
|
||||||
|
+ATTRS{x}==\"x\"
|
||||||
|
+TAGS==\"x\"
|
||||||
|
+RESULT==\"x\"
|
||||||
|
+TEST==\"x\"
|
||||||
|
+PROGRAM==\"x\"
|
||||||
|
+IMPORT{file}==\"x\"
|
||||||
|
+IMPORT{program}==\"echo hello\"
|
||||||
|
+IMPORT{builtin}==\"path_id\"
|
||||||
|
+IMPORT{db}==\"x\"
|
||||||
|
+IMPORT{cmdline}==\"x\"
|
||||||
|
+IMPORT{parent}==\"x\"
|
||||||
|
+OPTIONS+=\"string_escape=none\"
|
||||||
|
+OPTIONS+=\"string_escape=replace\"
|
||||||
|
+OPTIONS+=\"db_persist\"
|
||||||
|
+OPTIONS+=\"watch\"
|
||||||
|
+OPTIONS+=\"link_priority=10\"
|
||||||
|
+OPTIONS+=\"log_level=1\"
|
||||||
|
+OPTIONS+=\"static_node=/dev/sda\"
|
||||||
|
+SECLABEL{x}+=\"x\"
|
||||||
|
+RUN{builtin}+=\"path_id\"
|
||||||
|
+RUN{program}+=\"x\"
|
||||||
|
+GOTO=\"x\"
|
||||||
|
+LABEL=\"x\"
|
||||||
|
+",
|
||||||
|
+ true,
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ let rule = Arc::new(RwLock::new(Rules::new(
|
||||||
|
+ vec!["/tmp/test_rules_display/rules.d".to_string()],
|
||||||
|
+ ResolveNameTime::Late,
|
||||||
|
+ )));
|
||||||
|
+
|
||||||
|
+ Rules::parse_rules(rule.clone());
|
||||||
|
+
|
||||||
|
+ println!("{}", rule.read().unwrap());
|
||||||
|
+
|
||||||
|
+ std::fs::remove_dir_all("/tmp/test_rules_display").unwrap();
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,167 @@
|
|||||||
|
From 94a3a51db76f45f8941d8a6cb649da0624fde67b Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Thu, 16 Nov 2023 11:16:12 +0800
|
||||||
|
Subject: [PATCH 066/103] test(devmaster): optimize UT for testing framework
|
||||||
|
and add some new cases
|
||||||
|
|
||||||
|
---
|
||||||
|
exts/devmaster/src/bin/devctl/daemon/mod.rs | 7 ++
|
||||||
|
exts/devmaster/src/lib/framework/job_queue.rs | 85 ++++++++++++-------
|
||||||
|
.../src/lib/framework/worker_manager.rs | 1 +
|
||||||
|
3 files changed, 64 insertions(+), 29 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/bin/devctl/daemon/mod.rs b/exts/devmaster/src/bin/devctl/daemon/mod.rs
|
||||||
|
index 3e4bd96d..53931650 100644
|
||||||
|
--- a/exts/devmaster/src/bin/devctl/daemon/mod.rs
|
||||||
|
+++ b/exts/devmaster/src/bin/devctl/daemon/mod.rs
|
||||||
|
@@ -71,6 +71,13 @@ mod test {
|
||||||
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
|
|
||||||
|
let dev = Device::from_subsystem_sysname("net", "lo").unwrap();
|
||||||
|
+
|
||||||
|
+ /* Trigger more than the number of workers. */
|
||||||
|
+ dev.trigger(DeviceAction::Change).unwrap();
|
||||||
|
+ dev.trigger(DeviceAction::Change).unwrap();
|
||||||
|
+ dev.trigger(DeviceAction::Change).unwrap();
|
||||||
|
+ dev.trigger(DeviceAction::Change).unwrap();
|
||||||
|
+ dev.trigger(DeviceAction::Change).unwrap();
|
||||||
|
dev.trigger(DeviceAction::Change).unwrap();
|
||||||
|
|
||||||
|
/* Sleep more than 3 seconds to wait for the workers being recycled. */
|
||||||
|
diff --git a/exts/devmaster/src/lib/framework/job_queue.rs b/exts/devmaster/src/lib/framework/job_queue.rs
|
||||||
|
index 7c6d6a8d..e488f480 100644
|
||||||
|
--- a/exts/devmaster/src/lib/framework/job_queue.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/framework/job_queue.rs
|
||||||
|
@@ -22,7 +22,6 @@ use std::{
|
||||||
|
cell::RefCell,
|
||||||
|
cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd},
|
||||||
|
collections::VecDeque,
|
||||||
|
- fmt::{self, Display},
|
||||||
|
rc::{Rc, Weak},
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -37,20 +36,8 @@ pub enum JobState {
|
||||||
|
Running,
|
||||||
|
}
|
||||||
|
|
||||||
|
-impl Display for JobState {
|
||||||
|
- ///
|
||||||
|
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
- let state = match self {
|
||||||
|
- JobState::Undef => "Undef",
|
||||||
|
- JobState::Queued => "Queued",
|
||||||
|
- JobState::Running => "Running",
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- write!(f, "{}", state)
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
/// device job
|
||||||
|
+#[derive(Debug)]
|
||||||
|
pub struct DeviceJob {
|
||||||
|
/// internal device
|
||||||
|
pub device: Device,
|
||||||
|
@@ -168,8 +155,6 @@ impl JobQueue {
|
||||||
|
gc.close_killer(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
- // self.job_queue_show_state();
|
||||||
|
-
|
||||||
|
for job in self.jobs.borrow().iter() {
|
||||||
|
match job.get_state() {
|
||||||
|
JobState::Queued => {}
|
||||||
|
@@ -241,19 +226,6 @@ impl JobQueue {
|
||||||
|
log::debug!("Job Queue: insert job {}", seqnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
- // /// cleanup the job queue, if match_state is Undef, cleanup all jobs, otherwise just retain the unmatched jobs
|
||||||
|
- // pub(crate) fn job_queue_cleanup(&self, match_state: JobState) {
|
||||||
|
- // self.jobs.borrow_mut().retain_mut(|job| {
|
||||||
|
- // if match_state != JobState::Undef && match_state != job.get_state() {
|
||||||
|
- // return true;
|
||||||
|
- // }
|
||||||
|
-
|
||||||
|
- // false
|
||||||
|
- // });
|
||||||
|
-
|
||||||
|
- // log::debug!("Job Queue: cleanup");
|
||||||
|
- // }
|
||||||
|
-
|
||||||
|
/// free a job from job queue
|
||||||
|
pub(crate) fn job_free(&self, job: &Rc<DeviceJob>) {
|
||||||
|
job.job_free();
|
||||||
|
@@ -289,3 +261,58 @@ impl JobQueue {
|
||||||
|
self.jobs.borrow().is_empty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#[cfg(test)]
|
||||||
|
+mod test {
|
||||||
|
+ use super::*;
|
||||||
|
+ use std::sync::{Arc, RwLock};
|
||||||
|
+
|
||||||
|
+ #[test]
|
||||||
|
+ fn test_job_cmp() {
|
||||||
|
+ let j1 = DeviceJob::new(
|
||||||
|
+ Device::from_subsystem_sysname("net", "lo").unwrap(),
|
||||||
|
+ JobState::Queued,
|
||||||
|
+ 1000,
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ let j2 = DeviceJob::new(
|
||||||
|
+ Device::from_subsystem_sysname("net", "lo").unwrap(),
|
||||||
|
+ JobState::Queued,
|
||||||
|
+ 1000,
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ assert_eq!(j1, j2);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ #[test]
|
||||||
|
+ fn test_job_queue() {
|
||||||
|
+ let events = Rc::new(Events::new().unwrap());
|
||||||
|
+ let cache = Cache::new(vec![], vec![]);
|
||||||
|
+ let devmaster = Rc::new(RefCell::new(Devmaster {
|
||||||
|
+ events,
|
||||||
|
+ worker_manager: None,
|
||||||
|
+ control_manager: None,
|
||||||
|
+ monitor: None,
|
||||||
|
+ job_queue: None,
|
||||||
|
+ gc: None,
|
||||||
|
+ cache: Arc::new(RwLock::new(cache)),
|
||||||
|
+ }));
|
||||||
|
+
|
||||||
|
+ let job_queue = JobQueue::new(devmaster);
|
||||||
|
+
|
||||||
|
+ /* Test start job when the queue is empty. */
|
||||||
|
+ job_queue.job_queue_start(None);
|
||||||
|
+
|
||||||
|
+ let dev = Device::from_subsystem_sysname("net", "lo").unwrap();
|
||||||
|
+ job_queue.job_queue_insert(dev);
|
||||||
|
+
|
||||||
|
+ /* Test insert dulplicate jobs with the same seqnum. */
|
||||||
|
+ let dev = Device::from_subsystem_sysname("net", "lo").unwrap();
|
||||||
|
+ dev.set_seqnum_from_string("1000").unwrap();
|
||||||
|
+ job_queue.job_queue_insert(dev);
|
||||||
|
+
|
||||||
|
+ let dev = Device::from_subsystem_sysname("net", "lo").unwrap();
|
||||||
|
+ dev.set_seqnum_from_string("1000").unwrap();
|
||||||
|
+ job_queue.job_queue_insert(dev);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/exts/devmaster/src/lib/framework/worker_manager.rs b/exts/devmaster/src/lib/framework/worker_manager.rs
|
||||||
|
index 870f6779..bddc9deb 100644
|
||||||
|
--- a/exts/devmaster/src/lib/framework/worker_manager.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/framework/worker_manager.rs
|
||||||
|
@@ -64,6 +64,7 @@ pub struct WorkerManager {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// worker
|
||||||
|
+#[derive(Debug)]
|
||||||
|
pub struct Worker {
|
||||||
|
/// worker unique id
|
||||||
|
id: u32,
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
From d661f601e4bb2b3ffcbb1db5bd11a51c6cf8abc1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Fri, 17 Nov 2023 01:15:00 +0800
|
||||||
|
Subject: [PATCH 068/103] test(devmaster): test exception scenarios on parsing
|
||||||
|
rules
|
||||||
|
|
||||||
|
---
|
||||||
|
exts/devmaster/src/lib/rules/rules_load.rs | 38 ++++++++++++++++++++++
|
||||||
|
1 file changed, 38 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/rules/rules_load.rs b/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
index cd90c271..19b7aaa4 100644
|
||||||
|
--- a/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
@@ -1725,10 +1725,13 @@ impl RuleToken {
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::config::*;
|
||||||
|
+ use basic::fs_util::touch_file;
|
||||||
|
use log::init_log;
|
||||||
|
use log::Level;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
+ use std::fs::create_dir_all;
|
||||||
|
+ use std::fs::remove_dir_all;
|
||||||
|
use std::{fs, path::Path, thread::JoinHandle};
|
||||||
|
|
||||||
|
fn create_test_rules_dir(dir: &'static str) {
|
||||||
|
@@ -2099,4 +2102,39 @@ SYMLINK += \"test111111\"",
|
||||||
|
);
|
||||||
|
assert_eq!(token.read().unwrap().as_ref().unwrap().value, "0");
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ #[test]
|
||||||
|
+ fn test_parse_rules() {
|
||||||
|
+ create_dir_all("/tmp/devmaster/rules").unwrap();
|
||||||
|
+
|
||||||
|
+ /* Normal rule file. */
|
||||||
|
+ touch_file(
|
||||||
|
+ "/tmp/devmaster/rules/00-a.rules",
|
||||||
|
+ false,
|
||||||
|
+ Some(0o777),
|
||||||
|
+ None,
|
||||||
|
+ None,
|
||||||
|
+ )
|
||||||
|
+ .unwrap();
|
||||||
|
+ /* Skip parsing the file with invalid suffix. */
|
||||||
|
+ touch_file("/tmp/devmaster/rules/01-b", false, Some(0o777), None, None).unwrap();
|
||||||
|
+ /* Failed to parse the file as it is not readable. */
|
||||||
|
+ touch_file(
|
||||||
|
+ "/tmp/devmaster/rules/02-c.rules",
|
||||||
|
+ false,
|
||||||
|
+ Some(0o222),
|
||||||
|
+ None,
|
||||||
|
+ None,
|
||||||
|
+ )
|
||||||
|
+ .unwrap();
|
||||||
|
+
|
||||||
|
+ let rules = Rules::new(
|
||||||
|
+ vec!["/tmp/devmaster/rules".to_string()],
|
||||||
|
+ ResolveNameTime::Never,
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ Rules::parse_rules(Arc::new(RwLock::new(rules)));
|
||||||
|
+
|
||||||
|
+ remove_dir_all("/tmp/devmaster").unwrap();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
From e3056ffc97640c2791f73bc2aa24b0db07b9d60b Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Mon, 20 Nov 2023 14:47:22 +0800
|
||||||
|
Subject: [PATCH 074/103] test(devmaster): trigger add and remove uevent to
|
||||||
|
cover netif renaming procedure
|
||||||
|
|
||||||
|
The netif renaming procedure executes only when a add uevent of netif raised.
|
||||||
|
|
||||||
|
In addition, the remove process was not covered previously.
|
||||||
|
---
|
||||||
|
exts/devmaster/src/bin/devctl/daemon/mod.rs | 11 +++++++----
|
||||||
|
1 file changed, 7 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/bin/devctl/daemon/mod.rs b/exts/devmaster/src/bin/devctl/daemon/mod.rs
|
||||||
|
index 53931650..4aa957a4 100644
|
||||||
|
--- a/exts/devmaster/src/bin/devctl/daemon/mod.rs
|
||||||
|
+++ b/exts/devmaster/src/bin/devctl/daemon/mod.rs
|
||||||
|
@@ -61,7 +61,10 @@ mod test {
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_run_daemon() {
|
||||||
|
- /* Require root privilege, skip in ci environment. */
|
||||||
|
+ /* Require root privilege, skip in ci environment.
|
||||||
|
+ *
|
||||||
|
+ * In addition, this test case will fail when devmaster daemon is running.
|
||||||
|
+ */
|
||||||
|
let dev = Device::from_subsystem_sysname("net", "lo").unwrap();
|
||||||
|
if dev.trigger(DeviceAction::Change).is_err() {
|
||||||
|
return;
|
||||||
|
@@ -73,9 +76,9 @@ mod test {
|
||||||
|
let dev = Device::from_subsystem_sysname("net", "lo").unwrap();
|
||||||
|
|
||||||
|
/* Trigger more than the number of workers. */
|
||||||
|
- dev.trigger(DeviceAction::Change).unwrap();
|
||||||
|
- dev.trigger(DeviceAction::Change).unwrap();
|
||||||
|
- dev.trigger(DeviceAction::Change).unwrap();
|
||||||
|
+ dev.trigger(DeviceAction::Remove).unwrap();
|
||||||
|
+ dev.trigger(DeviceAction::Add).unwrap();
|
||||||
|
+ dev.trigger(DeviceAction::Add).unwrap();
|
||||||
|
dev.trigger(DeviceAction::Change).unwrap();
|
||||||
|
dev.trigger(DeviceAction::Change).unwrap();
|
||||||
|
dev.trigger(DeviceAction::Change).unwrap();
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
From b018bb63d87f7c25acfbfc1964102fb1af64ce94 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||||||
|
Date: Thu, 23 Nov 2023 20:14:43 +0800
|
||||||
|
Subject: [PATCH 083/103] test(devmaster): use unwrap instead of asserting is
|
||||||
|
ok
|
||||||
|
|
||||||
|
Use unwrap method to display more about error information.
|
||||||
|
---
|
||||||
|
exts/devmaster/src/lib/rules/rules_load.rs | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/exts/devmaster/src/lib/rules/rules_load.rs b/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
index b035f562..49da2d63 100644
|
||||||
|
--- a/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
+++ b/exts/devmaster/src/lib/rules/rules_load.rs
|
||||||
|
@@ -1737,10 +1737,10 @@ pub(crate) mod tests {
|
||||||
|
use std::{fs, path::Path};
|
||||||
|
|
||||||
|
pub(crate) fn create_tmp_file(dir: &'static str, file: &str, content: &str, truncate: bool) {
|
||||||
|
- assert!(fs::create_dir_all(dir).is_ok());
|
||||||
|
+ fs::create_dir_all(dir).unwrap();
|
||||||
|
let s = format!("{}/{}", dir, file);
|
||||||
|
let p = Path::new(&s);
|
||||||
|
- assert!(fs::write(p, content,).is_ok());
|
||||||
|
+ fs::write(p, content).unwrap();
|
||||||
|
let mut f = fs::OpenOptions::new()
|
||||||
|
.write(true)
|
||||||
|
.truncate(truncate)
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
Name: sysmaster
|
Name: sysmaster
|
||||||
Version: 0.5.1
|
Version: 0.5.1
|
||||||
Release: 3
|
Release: 5
|
||||||
Summary: redesign and reimplement process1.
|
Summary: redesign and reimplement process1.
|
||||||
|
|
||||||
License: Mulan PSL v2
|
License: Mulan PSL v2
|
||||||
@ -26,6 +26,49 @@ Source0: %{name}-%{version}.tar.xz
|
|||||||
Patch0: backport-fix-getty-generator-delelte-double-quote-in-the-conf.patch
|
Patch0: backport-fix-getty-generator-delelte-double-quote-in-the-conf.patch
|
||||||
Patch1: backport-fix-solve-two-sysmaster-problem-exit-after-do_execut.patch
|
Patch1: backport-fix-solve-two-sysmaster-problem-exit-after-do_execut.patch
|
||||||
Patch2: backport-fix-solve-reboot-time-consuming.patch
|
Patch2: backport-fix-solve-reboot-time-consuming.patch
|
||||||
|
Patch3: backport-feature-add-scsi_id.patch
|
||||||
|
Patch4: backport-feature-devctl-add-devctl-info.patch
|
||||||
|
Patch5: backport-fix-devmaster-keep-the-same-name-with-udev-control-s.patch
|
||||||
|
Patch6: backport-fix-devmaster-adjust-temporary-file-permissions.patch
|
||||||
|
Patch7: backport-fix-devmaster-append-zero-to-the-file-name.patch
|
||||||
|
Patch8: backport-fix-devmaster-fix-potential-integer-overflow-in-scsi.patch
|
||||||
|
Patch9: backport-fix-devmaster-fix-out-of-bounds-in-net_id.patch
|
||||||
|
Patch10: backport-fix-devmaster-fix-misspelt-sysattr-sas_address.patch
|
||||||
|
Patch11: backport-fix-devmaster-check-the-validity-of-kmod-context-dur.patch
|
||||||
|
Patch12: backport-feature-devmaster-Add-subcommands-for-devctl-trigger.patch
|
||||||
|
Patch13: backport-fix-return-Ok-when-the-.hwdb-and-hwdb.bin-files-cann.patch
|
||||||
|
Patch14: backport-fix-Failed-to-devctl-info-dev-or-sys.patch
|
||||||
|
Patch15: backport-fix-basic-complete-feature-dependencies.patch
|
||||||
|
Patch16: backport-fix-device-replenish-feature-dependency-of-uuid-on-b.patch
|
||||||
|
Patch17: backport-test-device-refactor-and-increase-test-line-coverage.patch
|
||||||
|
Patch18: backport-fix-basic-use-feature-to-control-procfs-compilation-.patch
|
||||||
|
Patch19: backport-test-device-compress-closures-and-add-some-unit-case.patch
|
||||||
|
Patch20: backport-fix-devmaster-drop-unnecessary-debug-trait-implement.patch
|
||||||
|
Patch21: backport-fix-device-fix-UT-privilege-error-in-ci.patch
|
||||||
|
Patch22: backport-fix-device-set-driver-subsystem-after-generating-dev.patch
|
||||||
|
Patch23: backport-fix-device-drop-unnecessary-error-throwing-out.patch
|
||||||
|
Patch24: backport-fix-device-cleanup-temporary-tag-files.patch
|
||||||
|
Patch25: backport-test-device-add-UT-for-device-enumerator.patch
|
||||||
|
Patch26: backport-test-device-add-UT-for-device-monitor.patch
|
||||||
|
Patch27: backport-feature-devmaster-add-devctl-control-subcommand-to-l.patch
|
||||||
|
Patch28: backport-refactor-devmaster-compress-unnecessary-code.patch
|
||||||
|
Patch29: backport-test-devmaster-optimize-UT-for-testing-framework-and.patch
|
||||||
|
Patch30: backport-test-devmaster-test-exception-scenarios-on-parsing-r.patch
|
||||||
|
Patch31: backport-fix-devmaster-cache-the-parsed-user-and-group.patch
|
||||||
|
Patch32: backport-fix-devmaster-drop-incorrect-preventation-on-removal.patch
|
||||||
|
Patch33: backport-fix-devmaster-CONST-can-only-take-arch-or-virt-as-at.patch
|
||||||
|
Patch34: backport-test-devmaster-add-UT-cases-for-rules-load.patch
|
||||||
|
Patch35: backport-test-devmaster-trigger-add-and-remove-uevent-to-cove.patch
|
||||||
|
Patch36: backport-fix-device-use-feature-to-avoid-loopdev-being-compil.patch
|
||||||
|
Patch37: backport-fix-devmaster-avoid-potential-test-case-failures.patch
|
||||||
|
Patch38: backport-refactor-devmaster-rename-the-create_tmp_rules-funct.patch
|
||||||
|
Patch39: backport-fix-device-keep-consistent-on-the-base-path-for-db-c.patch
|
||||||
|
Patch40: backport-test-devmaster-add-UT-for-rules-applying.patch
|
||||||
|
Patch41: backport-fix-device-avoid-panic-on-shallow-clone-when-subsyst.patch
|
||||||
|
Patch42: backport-test-devmaster-use-unwrap-instead-of-asserting-is-ok.patch
|
||||||
|
Patch43: backport-test-devmaster-add-UT-for-execute-unit.patch
|
||||||
|
Patch44: backport-test-devmaster-add-UT-for-rules-module.patch
|
||||||
|
Patch45: backport-test-devmaster-add-UT-for-node-and-modify-the-displa.patch
|
||||||
|
|
||||||
ExclusiveArch: x86_64 aarch64
|
ExclusiveArch: x86_64 aarch64
|
||||||
|
|
||||||
@ -40,6 +83,10 @@ Summary: %{summary}
|
|||||||
%package -n devmaster
|
%package -n devmaster
|
||||||
Summary: Infrastructure of device management in userspace.
|
Summary: Infrastructure of device management in userspace.
|
||||||
BuildRequires: util-linux-devel kmod-devel
|
BuildRequires: util-linux-devel kmod-devel
|
||||||
|
Requires: %{name}%{?_isa} = %{version}-%{release}
|
||||||
|
Requires(post): sysmaster
|
||||||
|
Requires(preun): sysmaster
|
||||||
|
Requires(postun): sysmaster
|
||||||
|
|
||||||
%description -n devmaster
|
%description -n devmaster
|
||||||
This package provides the infrastructure of device management in userspace.
|
This package provides the infrastructure of device management in userspace.
|
||||||
@ -173,16 +220,23 @@ ln -s /usr/lib/sysmaster/system/sshd.service %{buildroot}/etc/sysmaster/system/m
|
|||||||
/etc/sysmaster/system/sysinit.target.wants/devctl-trigger.service
|
/etc/sysmaster/system/sysinit.target.wants/devctl-trigger.service
|
||||||
|
|
||||||
%post -n devmaster
|
%post -n devmaster
|
||||||
test -f /etc/sysmaster/system/sysinit.target.wants/udevd.service && unlink /etc/sysmaster/system/sysinit.target.wants/udevd.service
|
test -f /etc/sysmaster/system/sysinit.target.wants/udevd.service && unlink /etc/sysmaster/system/sysinit.target.wants/udevd.service || :
|
||||||
test -f /etc/sysmaster/system/sysinit.target.wants/udev-trigger.service && unlink /etc/sysmaster/system/sysinit.target.wants/udev-trigger.service
|
test -f /etc/sysmaster/system/sysinit.target.wants/udev-trigger.service && unlink /etc/sysmaster/system/sysinit.target.wants/udev-trigger.service || :
|
||||||
|
|
||||||
%postun -n devmaster
|
%postun -n devmaster
|
||||||
test -f /usr/lib/sysmaster/system/udevd.service && ln -s /usr/lib/sysmaster/system/udevd.service /etc/sysmaster/system/sysinit.target.wants/udevd.service
|
test -f /usr/lib/sysmaster/system/udevd.service && ln -s /usr/lib/sysmaster/system/udevd.service /etc/sysmaster/system/sysinit.target.wants/udevd.service || :
|
||||||
test -f /usr/lib/sysmaster/system/udev-trigger.service && ln -s /usr/lib/sysmaster/system/udev-trigger.service /etc/sysmaster/system/sysinit.target.wants/udev-trigger.service
|
test -f /usr/lib/sysmaster/system/udev-trigger.service && ln -s /usr/lib/sysmaster/system/udev-trigger.service /etc/sysmaster/system/sysinit.target.wants/udev-trigger.service || :
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Dec 7 2023 chenjiayi<chenjiayi22@huawei.com> - 0.5.1-5
|
||||||
|
- complement dependency from devmaster to sysmaster and avoid
|
||||||
|
exit with failure in post and postun process
|
||||||
|
|
||||||
|
* Wed Dec 6 2023 chenjiayi<chenjiayi22@huawei.com> - 0.5.1-4
|
||||||
|
- sync patches from upstream
|
||||||
|
|
||||||
* Fri Nov 24 2023 zhangyao<zhangyao108@huawei.com> - 0.5.1-3
|
* Fri Nov 24 2023 zhangyao<zhangyao108@huawei.com> - 0.5.1-3
|
||||||
- sync patchs from upstream
|
- sync patches from upstream
|
||||||
|
|
||||||
* Mon Oct 30 2023 zhangyao<zhangyao108@huawei.com> - 0.5.1-2
|
* Mon Oct 30 2023 zhangyao<zhangyao108@huawei.com> - 0.5.1-2
|
||||||
- add simulate_udev.sh file
|
- add simulate_udev.sh file
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user