diff --git a/ABI_VERSION b/ABI_VERSION deleted file mode 100644 index d3827e75a5cadb9fe4a27e1cb9b6d192e7323120..0000000000000000000000000000000000000000 --- a/ABI_VERSION +++ /dev/null @@ -1 +0,0 @@ -1.0 diff --git a/libs/basic/Cargo.toml b/libs/basic/Cargo.toml deleted file mode 100644 index b704a44f3a79ed711f21311b5594005fcc9f0386..0000000000000000000000000000000000000000 --- a/libs/basic/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "basic" -version = "0.1.0" -authors = ["overweight "] -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -serde = "1.0.130" -libc = "0.2.140" -libmount = "0.1.15" -log = "0.4" -log4rs = "1.0" -snafu = "0.7" -procfs = "0.12.0" -nix = "0.24" -pathdiff = "0.2.1" -caps = "0.5.5" -lazy_static = "1.4.0" - -[features] -selinux = [] diff --git a/libs/basic/src/condition.rs b/libs/basic/src/condition.rs deleted file mode 100644 index c549dec1b80067f2f1167945a577408be3cb4269..0000000000000000000000000000000000000000 --- a/libs/basic/src/condition.rs +++ /dev/null @@ -1,541 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! the utils to test the conditions -use nix::{ - fcntl::{open, OFlag}, - sys::{ - stat, - statvfs::{fstatvfs, FsFlags}, - }, -}; - -use libc::{glob, glob_t, GLOB_NOSORT}; -#[cfg(not(target_env = "musl"))] -use libc::{statx, STATX_ATTR_MOUNT_ROOT}; - -use crate::{device::on_ac_power, fd_util, proc_cmdline, security, user_group_util}; -use std::{ - ffi::CString, - fs::File, - io::{BufRead, BufReader}, - path::Path, - str::FromStr, - string::String, -}; - -/// the type of the condition -#[derive(Eq, PartialEq)] -pub enum ConditionType { - /// check whether the service manager is running on AC Power. - ACPower, - /// check the capability - Capability, - /// check if the directory is empty - DirectoryNotEmpty, - /// check if the file is executable - FileIsExecutable, - /// check file is empty - FileNotEmpty, - /// conditionalize units on whether the system is booting up for the first time - FirstBoot, - /// check the kernel cmdline - KernelCommandLine, - /// check need update - NeedsUpdate, - /// check path exist - PathExists, - /// check if the path exists using glob pattern - PathExistsGlob, - /// check if the path is directory - PathIsDirectory, - /// check if the path is a mount point - PathIsMountPoint, - /// check path is readable and writable - PathIsReadWrite, - /// check if the path is symbolic link - PathIsSymbolicLink, - /// check the security - Security, - /// check whether the service manager is running as the given user. - User, -} - -/// check whether the condition is met. -/// if the condition start with '|', trigger it and as long as one condition is met, return ok. -/// if the condition start with '!', indicate reverse condition. -/// others indicate usual condition -pub struct Condition { - c_type: ConditionType, - trigger: i8, - revert: i8, - params: String, -} - -impl Condition { - /// create the condition instance - pub fn new(c_type: ConditionType, trigger: i8, revert: i8, params: String) -> Self { - Condition { - c_type, - trigger, - revert, - params, - } - } - - /// return the trigger - pub fn trigger(&self) -> i8 { - self.trigger - } - - /// return the revert - pub fn revert(&self) -> i8 { - self.revert - } - - /// running the condition test - pub fn test(&self) -> bool { - // empty self.params means that the condition is not set, so the test is successful - if self.params.is_empty() { - return true; - } - let result = match self.c_type { - /* The following functions will return a positive value if check pass. */ - ConditionType::ACPower => self.test_ac_power(), - ConditionType::Capability => self.test_capability(), - ConditionType::DirectoryNotEmpty => self.test_directory_not_empty(), - ConditionType::FileIsExecutable => self.test_file_is_executable(), - ConditionType::FileNotEmpty => self.test_file_not_empty(), - ConditionType::FirstBoot => self.test_first_boot(), - ConditionType::KernelCommandLine => self.test_kernel_command_line(), - ConditionType::NeedsUpdate => self.test_needs_update(), - ConditionType::PathExists => self.test_path_exists(), - ConditionType::PathExistsGlob => self.test_path_exists_glob(), - ConditionType::PathIsDirectory => self.test_path_is_directory(), - ConditionType::PathIsMountPoint => self.test_path_is_mount_point(), - ConditionType::PathIsReadWrite => self.test_path_is_read_write(), - ConditionType::PathIsSymbolicLink => self.test_path_is_symbolic_link(), - ConditionType::Security => self.test_security(), - ConditionType::User => self.test_user(), - }; - - (result > 0) ^ (self.revert() >= 1) - } - - fn test_ac_power(&self) -> i8 { - /* params is generated from bool.to_string(), so it should - * be exactly "true", not "yes"/"on" or other words. */ - let is_true = self.params.eq("true"); - !(is_true ^ on_ac_power()) as i8 - } - - fn test_capability(&self) -> i8 { - let values = match caps::Capability::from_str(&self.params) { - Err(_) => { - log::info!("Failed to parse ConditionCapability values: {}, assuming ConditionCapability check failed", self.params); - return 0; - } - Ok(v) => v, - }; - - let file = match File::open("/proc/self/status") { - Err(_) => { - log::info!( - "Failed to open /proc/self/status, assuming ConditionCapability check failed." - ); - return 0; - } - Ok(v) => v, - }; - let reader = BufReader::new(file); - let p = "CapBnd:"; - let mut cap_bitmask: u64 = 0; - for line in reader.lines() { - let line = match line { - Err(_) => { - log::info!("Failed to read /proc/self/status, assuming ConditionCapability check failed."); - return 0; - } - Ok(v) => v, - }; - if !line.starts_with(p) { - continue; - } - match u64::from_str_radix(line.trim_start_matches(p).trim_start(), 16) { - Err(_) => { - log::info!("Failed to parse CapBnd, assuming ConditionCapability check failed"); - return 0; - } - Ok(v) => { - cap_bitmask = v; - break; - } - }; - } - - let res = cap_bitmask & values.bitmask(); - (res != 0) as i8 - } - - fn test_directory_not_empty(&self) -> i8 { - let path = Path::new(&self.params); - if path.is_file() { - return 0; - } - let mut iter = match path.read_dir() { - Err(_) => { - return 0; - } - Ok(v) => v, - }; - iter.next().is_some() as i8 - } - - fn test_file_is_executable(&self) -> i8 { - let path = Path::new(&self.params); - if path.is_dir() { - return 0; - } - let s = match stat::stat(path) { - Err(_) => { - return 0; - } - Ok(v) => v, - }; - (fd_util::stat_is_reg(s.st_mode) && (s.st_mode & 111 > 0)) as i8 - } - - fn test_file_not_empty(&self) -> i8 { - let tmp_path = Path::new(&self.params); - let result = tmp_path - .metadata() - .map(|m| if m.is_file() { m.len() > 0 } else { false }) - .unwrap_or(false); - result as i8 - } - - fn test_first_boot(&self) -> i8 { - if let Ok(ret) = proc_cmdline::proc_cmdline_get_bool("sysmaster.condition-first-boot") { - if ret { - return ret as i8; - } - } - - let result = self.params.eq("true"); - - let existed = Path::new("/run/sysmaster/first-boot").exists(); - (result == existed) as i8 - } - - fn test_kernel_command_line(&self) -> i8 { - let has_equal = self.params.contains('='); - let search_value = if has_equal { - self.params.split_once('=').unwrap().0 - } else { - &self.params - }; - let value = match proc_cmdline::cmdline_get_item(search_value) { - Err(_) => { - log::info!("Failed to get cmdline content, assuming ConditionKernelCommandLine check failed."); - return 0; - } - Ok(v) => { - if v.is_none() { - log::info!( - "/proc/cmdline doesn't contain the given item: {}", - search_value - ); - return 0; - } - v.unwrap() - } - }; - log::debug!("Found kernel command line value: {value}"); - if has_equal { - /* has an equal, "crashkernel=512M matches crashkernel=512M" */ - self.params.eq(&value) as i8 - } else { - /* Check if the value has an equal */ - match value.split_once('=') { - /* doesn't has an equal, "rd matches rd" */ - None => self.params.eq(&value) as i8, - /* has an equal, "crashkernel matches crashkernel=512M" */ - Some(v) => self.params.eq(v.0) as i8, - } - } - } - - fn test_needs_update(&self) -> i8 { - 0 - } - - fn test_path_exists(&self) -> i8 { - let tmp_path = Path::new(&self.params); - let result = tmp_path.exists(); - result as i8 - } - - fn test_path_exists_glob(&self) -> i8 { - let pattern = CString::new(self.params.as_str()).unwrap(); - let mut pglob: glob_t = unsafe { std::mem::zeroed() }; - let status = unsafe { - /* use GLOB_NOSORT to speed up. */ - glob(pattern.as_ptr(), GLOB_NOSORT, None, &mut pglob) - }; - (status == 0) as i8 - } - - fn test_path_is_directory(&self) -> i8 { - Path::new(&self.params).is_dir() as i8 - } - - #[cfg(not(target_env = "musl"))] - fn test_path_is_mount_point(&self) -> i8 { - if self.params.eq("/") { - return 1; - } - /*let file = match File::open(Path::new(&self.params)) { - Err(_) => { - return 0; - } - Ok(v) => v, - }; - let fd = std::os::fd::AsRawFd::as_raw_fd(&file);*/ - let fd = 0; - let path_name = CString::new(self.params.as_str()).unwrap(); - let mut statxbuf: statx = unsafe { std::mem::zeroed() }; - unsafe { - /* statx was added to linux in kernel 4.11 per `stat(2)`, - * we can depend on it safely. So we only use statx to - * check if the path is a mount point, and chase the - * symlink unconditionally*/ - statx(fd, path_name.as_ptr(), 0, 0, &mut statxbuf); - /* The mask is supported and is set */ - i8::from( - statxbuf.stx_attributes_mask & (STATX_ATTR_MOUNT_ROOT as u64) != 0 - && statxbuf.stx_attributes & (STATX_ATTR_MOUNT_ROOT as u64) != 0, - ) - } - } - - #[cfg(target_env = "musl")] - /* musl can't use statx, check /proc/self/mountinfo. */ - fn test_path_is_mount_point(&self) -> i8 { - use libmount::mountinfo; - use std::io::Read; - - let mut mount_data = String::new(); - let mut file = match File::open("/proc/self/mountinfo") { - Err(_) => { - return 0; - } - Ok(v) => v, - }; - if file.read_to_string(&mut mount_data).is_err() { - return 0; - } - let parser = mountinfo::Parser::new(mount_data.as_bytes()); - for mount_result in parser { - if let Ok(mount) = mount_result { - let mount_point = match mount.mount_point.to_str() { - None => { - continue; - } - Some(v) => v, - }; - if self.params == mount_point { - return 1; - } - } - } - 0 - } - - fn test_path_is_read_write(&self) -> i8 { - let path = Path::new(&self.params); - if !path.exists() { - return 0; - } - let fd = match open(path, OFlag::O_CLOEXEC | OFlag::O_PATH, stat::Mode::empty()) { - Err(e) => { - log::error!( - "Failed to open {} for checking file system permission: {}", - self.params, - e - ); - return 0; - } - Ok(v) => v, - }; - if fd < 0 { - log::error!("Invalid file descriptor."); - return 0; - } - let flags = match fstatvfs(&fd) { - Err(e) => { - log::error!("Failed to get the stat of file system: {}", e); - return 0; - } - Ok(v) => v, - }; - (!flags.flags().contains(FsFlags::ST_RDONLY)) as i8 - } - - fn test_path_is_symbolic_link(&self) -> i8 { - Path::new(&self.params).is_symlink() as i8 - } - - fn test_security(&self) -> i8 { - let res = match self.params.as_str() { - "selinux" => security::selinux_enabled(), - "apparmor" => security::apparmor_enabled(), - "tomoyo" => security::tomoyo_enabled(), - "ima" => security::ima_enabled(), - "smack" => security::smack_enabled(), - "audit" => security::audit_enabled(), - "uefi-secureboot" => security::uefi_secureboot_enabled(), - "tpm2" => security::tpm2_enabled(), - _ => false, - }; - res as i8 - } - - fn test_user(&self) -> i8 { - // may be UID - if let Ok(user) = user_group_util::parse_uid(&self.params) { - return (user.uid == nix::unistd::getuid() || user.uid == nix::unistd::geteuid()) as i8; - } - - if self.params.eq("@system") { - return (user_group_util::uid_is_system(nix::unistd::getuid()) - || user_group_util::uid_is_system(nix::unistd::geteuid())) - as i8; - } - - // may be username - let result = match user_group_util::parse_name(&self.params) { - Ok(user) => user.uid == nix::unistd::getuid() || user.uid == nix::unistd::geteuid(), - _ => false, - }; - result as i8 - } -} - -#[cfg(test)] -mod test { - use crate::{logger, proc_cmdline}; - use libtests::get_project_root; - use std::path::Path; - - use super::{Condition, ConditionType}; - - #[test] - fn test_condition_test() { - logger::init_log_to_console("test_init_lookup_paths", log::LevelFilter::Debug); - let project_root = get_project_root().unwrap(); - let cond_path_not_exists = - Condition::new(ConditionType::PathExists, 0, 0, "/home/test".to_string()); - let f_result = cond_path_not_exists.test(); - assert!(!f_result); - log::debug!("project root {:?}", project_root); - let cond_path_exists = Condition::new( - ConditionType::PathExists, - 0, - 0, - project_root.to_str().unwrap().to_string(), - ); - let t_result = cond_path_exists.test(); - assert!(t_result, "condition_path exists is not true"); - let cond_path_exists_revert = Condition::new( - ConditionType::PathExists, - 0, - 1, - project_root.to_str().unwrap().to_string(), - ); - let f_result = cond_path_exists_revert.test(); - assert!(!f_result, "condition test path exist revert error"); - let cond_file_not_empty = Condition::new( - ConditionType::FileNotEmpty, - 0, - 0, - project_root.to_str().unwrap().to_string() + "/Cargo.lock", - ); - assert!(cond_file_not_empty.test(), "cond test file not empty"); - - let cond_file_empty = Condition::new( - ConditionType::FileNotEmpty, - 0, - 0, - project_root.to_str().unwrap().to_string(), - ); - assert!(!cond_file_empty.test(), "cond test file empty"); - } - - #[test] - fn test_condition_user() { - if nix::unistd::getuid() != nix::unistd::Uid::from_raw(0) { - return; - } - - let root_user = "root"; - let cond_user_root_username = - Condition::new(ConditionType::User, 0, 0, root_user.to_string()); - assert!(cond_user_root_username.test(), "cond root username"); - - let root_user_num = "0"; - let cond_user_root_username_num = - Condition::new(ConditionType::User, 0, 0, root_user_num.to_string()); - assert!(cond_user_root_username_num.test(), "cond root username"); - - let fake_user = "fake"; - let cond_user_fake_username = - Condition::new(ConditionType::User, 0, 0, fake_user.to_string()); - assert!(!cond_user_fake_username.test(), "cond fake username"); - - let fake_user_num = "1234"; - let cond_user_fake_username_num = - Condition::new(ConditionType::User, 0, 0, fake_user_num.to_string()); - assert!(!cond_user_fake_username_num.test(), "cond fake username"); - - let system_str = "@system"; - let cond_user_system_str = - Condition::new(ConditionType::User, 0, 0, system_str.to_string()); - assert!(cond_user_system_str.test(), "cond system username"); - } - - #[test] - fn test_condition_first_boot() { - if let Ok(ret) = proc_cmdline::proc_cmdline_get_bool("sysmaster.condition-first-boot") { - if ret { - println!( - "this test cannot be tested because we cannot modify the kernel parameters" - ); - return; - } - } - - let existed = Path::new("/run/sysmaster/first-boot").exists(); - let cond_first_boot_true = - Condition::new(ConditionType::FirstBoot, 0, 0, String::from("true")); - let cond_first_boot_false = - Condition::new(ConditionType::FirstBoot, 0, 0, String::from("false")); - if existed { - println!("file is existed"); - assert!(cond_first_boot_true.test(), "file should be existed"); - assert!(!cond_first_boot_false.test(), "file should be existed"); - } else { - println!("file is no existed"); - assert!(!cond_first_boot_true.test(), "file should not be existed"); - assert!(cond_first_boot_false.test(), "file should not be existed"); - } - } -} diff --git a/libs/basic/src/conf_parser.rs b/libs/basic/src/conf_parser.rs deleted file mode 100644 index dd733ac47616141eb23eaf9019b7599973fdc381..0000000000000000000000000000000000000000 --- a/libs/basic/src/conf_parser.rs +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! the utils can be used to parse unit conf file -use crate::error::*; - -/// the base that will be translate from str -#[derive(Debug, Eq, PartialEq)] -pub enum Base { - /// binary number - Binary, - /// Decimal number - Decimal, -} - -/// return true if item is 1, yes, y, true, t or on -/// return false if item is 0, no, n, false, f, or off -pub fn parse_boolean(item: &str) -> Result { - match &item.to_lowercase() as &str { - "1" | "yes" | "y" | "true" | "t" | "on" => Ok(true), - "0" | "no" | "n" | "false" | "f" | "off" => Ok(false), - _ => Err(Error::Parse { - source: "wrong boolean value".into(), - }), - } -} - -/// parse the item from string to u64 -/// the item can be end with E, P, T, G, M, K and B -pub fn parse_size(item: &str, base: Base) -> Result { - let item = item.trim(); - if item.is_empty() { - return Err(Error::Parse { - source: "empty string".into(), - }); - } - - if item.starts_with('-') { - return Err(Error::Parse { - source: "invalue string".into(), - }); - } - - let binary_table = [ - ( - 'E', - 1024u64 * 1024u64 * 1024u64 * 1024u64 * 1024u64 * 1024u64, - ), - ('P', 1024u64 * 1024u64 * 1024u64 * 1024u64 * 1024u64), - ('T', 1024u64 * 1024u64 * 1024u64 * 1024u64), - ('G', 1024u64 * 1024u64 * 1024u64), - ('M', 1024u64 * 1024u64), - ('K', 1024u64), - ('B', 1u64), - (' ', 1u64), - ]; - - let decimal_table = [ - ( - 'E', - 1000u64 * 1000u64 * 1000u64 * 1000u64 * 1000u64 * 1000u64, - ), - ('P', 1000u64 * 1000u64 * 1000u64 * 1000u64 * 1000u64), - ('T', 1000u64 * 1000u64 * 1000u64 * 1000u64), - ('G', 1000u64 * 1000u64 * 1000u64), - ('M', 1000u64 * 1000u64), - ('K', 1000u64), - ('B', 1u64), - (' ', 1u64), - ]; - - let table = if base == Base::Binary { - binary_table - } else { - decimal_table - }; - - if let Ok(v) = item.parse::() { - return Ok(v as u64); - } - - let mut ret: u64 = 0; - let mut start: usize = usize::MAX; - - for (i, v) in item.as_bytes().iter().enumerate() { - if char::from(*v) == ' ' || char::from(*v) == '.' { - continue; - }; - - if char::from(*v).is_ascii_digit() { - continue; - } - - for (index, (key, _factor)) in table.iter().enumerate() { - if *key == char::from(*v) { - start = index; - break; - } - } - - if start == usize::MAX { - return Err(Error::Parse { - source: "invalid unit".into(), - }); - } - - let cur = item[..i].to_string().parse::()?; - - if cur > (u64::MAX / table[start].1) as f64 { - return Err(Error::Parse { - source: "value is out of range".into(), - }); - } - - ret = (cur * table[start].1 as f64) as u64; - } - - Ok(ret) -} - -#[cfg(test)] -mod test { - - #[test] - fn test_parse_size() { - use crate::conf_parser::{parse_size, Base}; - let ret1 = parse_size("", Base::Binary); - assert!(ret1.is_err()); - - let ret1 = parse_size("100G", Base::Binary).unwrap(); - assert_eq!(ret1, 100 * 1024 * 1024 * 1024); - - let ret1 = parse_size("99", Base::Binary).unwrap(); - assert_eq!(ret1, 99); - - let ret1 = parse_size("99.4", Base::Binary).unwrap(); - assert_eq!(ret1, 99); - - let ret1 = parse_size("4.5K", Base::Binary).unwrap(); - assert_eq!(ret1, 4 * 1024 + 512); - - let ret1 = parse_size("15E", Base::Binary).unwrap(); - assert_eq!( - ret1, - 15 * 1024u64 * 1024u64 * 1024u64 * 1024u64 * 1024u64 * 1024u64 - ); - - let ret1 = parse_size("4.5C", Base::Binary); - assert!(ret1.is_err()); - } - - #[test] - fn test_parse_boolean() { - use crate::conf_parser::parse_boolean; - - assert!(parse_boolean("1").unwrap()); - assert!(parse_boolean("y").unwrap()); - assert!(parse_boolean("Y").unwrap()); - assert!(parse_boolean("yes").unwrap()); - assert!(parse_boolean("YES").unwrap()); - assert!(parse_boolean("true").unwrap()); - assert!(parse_boolean("TRUE").unwrap()); - assert!(parse_boolean("on").unwrap()); - assert!(parse_boolean("ON").unwrap()); - - assert!(!parse_boolean("0").unwrap()); - assert!(!parse_boolean("n").unwrap()); - assert!(!parse_boolean("N").unwrap()); - assert!(!parse_boolean("no").unwrap()); - assert!(!parse_boolean("NO").unwrap()); - assert!(!parse_boolean("false").unwrap()); - assert!(!parse_boolean("FALSE").unwrap()); - assert!(!parse_boolean("off").unwrap()); - assert!(!parse_boolean("OFF").unwrap()); - - assert!(parse_boolean("process").is_err()); - assert!(parse_boolean("in").is_err()); - } -} diff --git a/libs/basic/src/device.rs b/libs/basic/src/device.rs deleted file mode 100644 index 264e973f87b774c7ef46507c33e4fea0cb377360..0000000000000000000000000000000000000000 --- a/libs/basic/src/device.rs +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! Common used device functions - -use std::path::Path; - -/// check if the system is running on AC Power -pub fn on_ac_power() -> bool { - /* 1 for true or failure, 0 for false. */ - let path = Path::new("/sys/class/power_supply"); - if !path.exists() || !path.is_dir() { - return true; - } - let des = match path.read_dir() { - Err(e) => { - log::info!("Failed to walk /sys/class/power_supply: {}, ignoring", e); - return true; - } - Ok(v) => v, - }; - let mut found_online = false; - let mut found_offline = false; - for de in des { - /* We only check the "type" file and "online" file in - * each directory, and skip whenever failed. */ - let de = match de { - Err(_) => { - continue; - } - Ok(v) => v, - }; - let de_path = path.join(de.file_name()); - // 1. The content of "type" file should be "Mains". - let contents = match std::fs::read(de_path.join("type")) { - Err(_) => { - continue; - } - Ok(v) => v, - }; - if !"Mains\n".to_string().into_bytes().eq(&contents) { - continue; - } - // 2. The content of "online" file should be "0" or "1". - let contents = match std::fs::read(de_path.join("online")) { - Err(_) => { - continue; - } - Ok(v) => v, - }; - if contents.len() != 2 || contents[1] != b'\n' { - continue; - } - if contents[0] == b'1' { - found_online = true; - break; - } else if contents[0] == b'0' { - found_offline = true; - } else { - continue; - } - } - found_online || !found_offline -} diff --git a/libs/basic/src/env_cargo.rs b/libs/basic/src/env_cargo.rs deleted file mode 100644 index 6ee8206d4a79d246f2efa8f49307b1ee3a154eec..0000000000000000000000000000000000000000 --- a/libs/basic/src/env_cargo.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! -use crate::error::*; -use std::env; - -/// -pub fn env_path() -> Result { - let path = env::var("OUT_DIR") - .or_else(|_| env::var("LD_LIBRARY_PATH")) - .context(VarSnafu)?; - - let out_dir = path.split(':').collect::>()[0] - .split("target") - .collect::>()[0] - .to_string(); - let tmp_str: Vec<_> = out_dir.split("build").collect(); - if tmp_str.is_empty() { - return Err(Error::Other { - msg: "not running with cargo".to_string(), - }); - } - - Ok(tmp_str[0].to_string()) -} diff --git a/libs/basic/src/errno_util.rs b/libs/basic/src/errno_util.rs deleted file mode 100644 index 0e5a6c3f29a88eefc7bd603d22aa1d2e95d3a670..0000000000000000000000000000000000000000 --- a/libs/basic/src/errno_util.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! utility for checking errno -//! - -use nix::errno::Errno; - -/// seven errno for "operation, system call, ioctl or socket feature not supported" -pub fn errno_is_not_supported(source: Errno) -> bool { - matches!( - source, - Errno::EOPNOTSUPP - | Errno::ENOTTY - | Errno::ENOSYS - | Errno::EAFNOSUPPORT - | Errno::EPFNOSUPPORT - | Errno::EPROTONOSUPPORT - | Errno::ESOCKTNOSUPPORT - ) -} - -/// two errno for access problems -pub fn errno_is_privilege(source: Errno) -> bool { - matches!(source, Errno::EACCES | Errno::EPERM) -} diff --git a/libs/basic/src/error.rs b/libs/basic/src/error.rs deleted file mode 100644 index b30bf1347018d01ccf6d00a128f879562e5602a6..0000000000000000000000000000000000000000 --- a/libs/basic/src/error.rs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! error definitions -use snafu::prelude::*; -#[allow(unused_imports)] -pub use snafu::ResultExt; - -#[allow(missing_docs)] -#[derive(Debug, Snafu)] -#[snafu(visibility(pub))] -#[non_exhaustive] -pub enum Error { - #[snafu(display( - "Got an error: (ret={}, errno={}) for syscall: {}", - ret, - errno, - syscall - ))] - Syscall { - syscall: &'static str, - ret: i32, - errno: i32, - }, - - #[snafu(display("Io"))] - Io { source: std::io::Error }, - - #[snafu(display("Errno"))] - Nix { source: nix::Error }, - - #[snafu(display("Var"))] - Var { source: std::env::VarError }, - - #[snafu(display("procfs"))] - Proc { source: procfs::ProcError }, - - #[snafu(display("Error parsing from string: {}", source))] - Parse { - source: Box, - }, - - #[snafu(display("Not exist): '{}'.", what))] - NotExisted { what: String }, - - #[snafu(display("Invalid: '{}'.", what))] - Invalid { what: String }, - - #[snafu(display("OtherError): '{}'.", msg))] - Other { msg: String }, -} - -#[allow(unused_macros)] -macro_rules! errfrom { - ($($st:ty),* => $variant:ident) => ( - $( - impl From<$st> for Error { - fn from(e: $st) -> Error { - Error::$variant { source: e.into() } - } - } - )* - ) -} - -errfrom!(std::num::ParseIntError, std::string::ParseError, std::num::ParseFloatError, std::str::ParseBoolError, std::string::FromUtf8Error => Parse); - -/// -pub type Result = std::result::Result; diff --git a/libs/basic/src/fd_util.rs b/libs/basic/src/fd_util.rs deleted file mode 100644 index 010602a6f007629846530a246c264de11021f55d..0000000000000000000000000000000000000000 --- a/libs/basic/src/fd_util.rs +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! -use crate::error::*; -use nix::{ - errno::Errno, - fcntl::{FcntlArg, FdFlag, OFlag}, - ioctl_read, - sys::stat::SFlag, -}; - -/// check if the given stat.st_mode is regular file -pub fn stat_is_reg(st_mode: u32) -> bool { - st_mode & SFlag::S_IFMT.bits() & SFlag::S_IFREG.bits() > 0 -} - -/// check if the given stat.st_mode is char device -pub fn stat_is_char(st_mode: u32) -> bool { - st_mode & SFlag::S_IFMT.bits() & SFlag::S_IFCHR.bits() > 0 -} - -/// -pub fn fd_nonblock(fd: i32, nonblock: bool) -> Result<()> { - assert!(fd >= 0); - - let flags = nix::fcntl::fcntl(fd, FcntlArg::F_GETFL).context(NixSnafu)?; - let fd_flag = unsafe { OFlag::from_bits_unchecked(flags) }; - - let nflag = match nonblock { - true => fd_flag | OFlag::O_NONBLOCK, - false => fd_flag & !OFlag::O_NONBLOCK, - }; - - if nflag == fd_flag { - return Ok(()); - } - - nix::fcntl::fcntl(fd, FcntlArg::F_SETFL(nflag)).context(NixSnafu)?; - - Ok(()) -} - -/// -pub fn fd_cloexec(fd: i32, cloexec: bool) -> Result<()> { - assert!(fd >= 0); - - let flags = nix::fcntl::fcntl(fd, FcntlArg::F_GETFD).context(NixSnafu)?; - - let fd_flag = unsafe { FdFlag::from_bits_unchecked(flags) }; - - let nflag = match cloexec { - true => fd_flag | FdFlag::FD_CLOEXEC, - false => fd_flag & !FdFlag::FD_CLOEXEC, - }; - - nix::fcntl::fcntl(fd, FcntlArg::F_SETFD(nflag)).context(NixSnafu)?; - - Ok(()) -} - -/// -pub fn fd_is_cloexec(fd: i32) -> bool { - assert!(fd >= 0); - - let flags = nix::fcntl::fcntl(fd, FcntlArg::F_GETFD).unwrap_or(0); - let fd_flag = FdFlag::from_bits(flags).unwrap(); - fd_flag.contains(FdFlag::FD_CLOEXEC) -} - -/// -pub fn close(fd: i32) { - if let Err(e) = nix::unistd::close(fd) { - log::warn!("close fd {} failed, errno: {}", fd, e); - } -} - -/// reopen the specified fd with new flags to convert an O_PATH fd into -/// regular one, or to turn O_RDWR fds into O_RDONLY fds -/// -/// this function can not work on sockets, as they can not be opened -/// -/// note that this function implicitly reset the read index to zero -pub fn fd_reopen(fd: i32, oflags: OFlag) -> Result { - if oflags.intersects(OFlag::O_DIRECTORY) { - let new_fd = nix::fcntl::openat(fd, ".", oflags, nix::sys::stat::Mode::empty()) - .map_err(|e| Error::Nix { source: e })?; - - return Ok(new_fd); - } - - match nix::fcntl::open( - format!("/proc/self/fd/{}", fd).as_str(), - oflags, - nix::sys::stat::Mode::empty(), - ) { - Ok(n) => Ok(n), - Err(e) => { - if e != Errno::ENOENT { - return Err(Error::Nix { source: e }); - } - - if !crate::stat_util::proc_mounted().map_err(|_| Error::Nix { - source: Errno::ENOENT, - })? { - // if /proc/ is not mounted, this function can not work - Err(Error::Nix { - source: Errno::ENOSYS, - }) - } else { - // if /proc/ is mounted, means this fd is not valid - Err(Error::Nix { - source: Errno::EBADF, - }) - } - } - } -} - -const BLK_DISKSEQ_MAGIC: u8 = 18; -const BLK_GET_DISKSEQ: u8 = 128; -ioctl_read!( - /// get the diskseq from block - blk_get_diskseq, - BLK_DISKSEQ_MAGIC, - BLK_GET_DISKSEQ, - u64 -); - -/// get the diskseq according to fd -pub fn fd_get_diskseq(fd: i32) -> Result { - let mut diskseq: u64 = 0; - let ptr: *mut u64 = &mut diskseq; - unsafe { - match blk_get_diskseq(fd, ptr) { - Ok(_) => {} - Err(e) => { - if !crate::errno_util::errno_is_not_supported(e) && e != Errno::EINVAL { - return Err(Error::Nix { source: e }); - } - - return Err(Error::Nix { - source: Errno::EOPNOTSUPP, - }); - } - } - } - Ok(diskseq) -} - -#[cfg(test)] -mod tests { - use crate::fd_util::{stat_is_char, stat_is_reg}; - use nix::sys::stat::fstat; - use std::{fs::File, os::fd::AsRawFd, path::Path}; - - #[test] - fn test_stats() { - let fd_reg_file = File::open(Path::new("/bin/true")).unwrap(); - assert!(fd_reg_file.as_raw_fd() >= 0); - let st = fstat(fd_reg_file.as_raw_fd()).unwrap(); - assert!(stat_is_reg(st.st_mode)); - - let fd_non_reg_file = File::open(Path::new("/proc/1")).unwrap(); - assert!(fd_non_reg_file.as_raw_fd() >= 0); - let st = fstat(fd_non_reg_file.as_raw_fd()).unwrap(); - assert!(!stat_is_reg(st.st_mode)); - - let fd_char_file = File::open(Path::new("/dev/zero")).unwrap(); - assert!(fd_char_file.as_raw_fd() >= 0); - let st = fstat(fd_char_file.as_raw_fd()).unwrap(); - assert!(stat_is_char(st.st_mode)); - - let fd_non_char_file = File::open(Path::new("/proc/1")).unwrap(); - assert!(fd_non_char_file.as_raw_fd() >= 0); - let st = fstat(fd_non_char_file.as_raw_fd()).unwrap(); - assert!(!stat_is_char(st.st_mode)); - } -} diff --git a/libs/basic/src/file_util.rs b/libs/basic/src/file_util.rs deleted file mode 100644 index 2f9d78918ac0c922c775432960efc8709d47389d..0000000000000000000000000000000000000000 --- a/libs/basic/src/file_util.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! the utils of the file operation -//! -use crate::error::*; -use std::io::BufRead; -use std::io::BufReader; -use std::path::Path; - -/// read first line from a file -pub fn read_first_line(path: &Path) -> Result { - let file = std::fs::File::open(path).context(IoSnafu)?; - - let mut buffer = BufReader::new(file); - let mut first_line = String::with_capacity(1024); - let _ = buffer.read_line(&mut first_line); - - Ok(first_line) -} diff --git a/libs/basic/src/fs_util.rs b/libs/basic/src/fs_util.rs deleted file mode 100644 index a854f1d25f7b35d818c0da9f05dce76c4fa7198b..0000000000000000000000000000000000000000 --- a/libs/basic/src/fs_util.rs +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! the utils of the file operation -//! -use crate::error::*; -use nix::{fcntl::OFlag, sys::stat::Mode}; -use pathdiff::diff_paths; -use std::path::Path; - -/// open the parent directory of path -pub fn open_parent(path: &Path, flags: OFlag, mode: Mode) -> Result { - let parent = path.parent().ok_or(Error::Nix { - source: nix::errno::Errno::EINVAL, - })?; - - nix::fcntl::open(parent, flags, mode).context(NixSnafu) -} - -/// create symlink link_name -> target -pub fn symlink(target: &str, link: &str, relative: bool) -> Result<()> { - let link_path = Path::new(&link); - let target_path = Path::new(&target); - - let (target_path, fd) = if relative { - let link_path_parent = link_path.parent().ok_or(Error::NotExisted { - what: format!("{}'s parent", link_path.to_string_lossy()), - })?; - - let rel_path = diff_paths(target_path, link_path_parent).unwrap(); - let fd = nix::fcntl::open(&rel_path, OFlag::O_DIRECT, Mode::from_bits(0).unwrap()) - .context(NixSnafu)?; - (rel_path, Some(fd)) - } else { - (target_path.to_path_buf(), None) - }; - - nix::unistd::symlinkat(target_path.as_path(), fd, link_path).map_err(|e| { - log::debug!("Failed to create symlink: {} -> {}", link, target); - Error::Nix { source: e } - }) -} - -#[cfg(test)] -mod tests { - use crate::fs_util::symlink; - use nix::unistd; - - #[test] - fn test_symlink() { - // use a complicated long name to make sure we don't have this file - // before running this testcase. - let link_name_path = std::path::Path::new("/tmp/test_link_name_39285b"); - if link_name_path.exists() { - return; - } - - let ret = symlink("/dev/null", "/tmp/test_link_name_39285b", false); - assert!(ret.is_ok()); - - let ret = unistd::unlinkat( - None, - link_name_path.to_str().unwrap(), - unistd::UnlinkatFlags::NoRemoveDir, - ); - assert!(ret.is_ok()); - } -} diff --git a/libs/basic/src/io_util.rs b/libs/basic/src/io_util.rs deleted file mode 100644 index b90d3a9b65cd76bbc14cfa573ce62138f5e72762..0000000000000000000000000000000000000000 --- a/libs/basic/src/io_util.rs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! -use crate::error::*; -use nix::{ - libc, - poll::{self, PollFd, PollFlags}, - sys::{signal::SigSet, time::TimeSpec}, -}; -use std::os::unix::prelude::RawFd; - -fn ppoll_timeout(fds: &mut [PollFd], timeout: Option) -> Result { - if fds.is_empty() { - return Ok(0); - } - - let ret = poll::ppoll(fds, timeout, SigSet::empty()).context(NixSnafu)?; - - if ret == 0 { - return Ok(0); - } - - for item in fds { - if item.revents().is_none() { - continue; - } - - if item.revents().unwrap().eq(&PollFlags::POLLNVAL) { - return Err(Error::Nix { - source: nix::errno::Errno::EBADF, - }); - } - } - - Ok(ret) -} - -/// -pub fn wait_for_events(fd: RawFd, event: PollFlags, time_out: i64) -> Result { - let poll_fd = PollFd::new(fd, event); - let time_spec = TimeSpec::from_timespec(libc::timespec { - tv_sec: time_out, - tv_nsec: 0, - }); - let mut fds = [poll_fd]; - - let ret = ppoll_timeout(&mut fds, Some(time_spec))?; - - Ok(ret) -} diff --git a/libs/basic/src/lib.rs b/libs/basic/src/lib.rs deleted file mode 100644 index 7f7b934d10c9c7fabe7e8fd0c0d66f2224e2dead..0000000000000000000000000000000000000000 --- a/libs/basic/src/lib.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! -pub mod conf_parser; -pub mod device; -pub mod env_cargo; -pub mod errno_util; -pub mod error; -pub mod fd_util; -pub mod file_util; -pub mod fs_util; -pub mod io_util; -pub mod logger; -pub mod macros; -pub mod mount_util; -pub mod parse_util; -pub mod path_lookup; -pub mod path_util; -pub mod proc_cmdline; -pub mod rlimit_util; -pub mod security; -pub mod show_table; -pub mod socket_util; -pub mod special; -pub mod stat_util; -pub mod string; -pub mod time_util; -pub mod user_group_util; -pub mod virtualize; -pub use error::*; diff --git a/libs/basic/src/logger.rs b/libs/basic/src/logger.rs deleted file mode 100644 index 2f24d257d840c2214ec4e4f24d1cdfbae6f65136..0000000000000000000000000000000000000000 --- a/libs/basic/src/logger.rs +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! -use log::{LevelFilter, Log}; -use log4rs::{ - append::{ - console::{ConsoleAppender, Target}, - file::FileAppender, - Append, - }, - config::{Appender, Config, Logger, Root}, - encode::pattern::PatternEncoder, -}; -use nix::libc; - -/// sysmaster log parttern: -/// -/// ```rust,ignore -/// {d(%Y-%m-%d %H:%M:%S)} {h({l}):<5} {M} {m}{n} -/// {d(%Y-%m-%d %H:%M:%S)}: log time, i.e. `2023-03-24 11:00:23` -/// {h({l}:<5)}: log level, 5 bytes -/// {M}: the method name where the logging request was issued -/// {m}: log message -/// {n}: separator character, '\n' in linux. -/// ``` -pub const LOG_PATTERN: &str = "{d(%Y-%m-%d %H:%M:%S)} {h({l}):<5} {M} {m}{n}"; - -struct LogPlugin(log4rs::Logger); - -impl log::Log for LogPlugin { - fn enabled(&self, metadata: &log::Metadata) -> bool { - self.0.enabled(metadata) - } - - fn log(&self, record: &log::Record) { - self.0.log(record); - } - - fn flush(&self) { - Log::flush(&self.0); - } -} - -struct SysLogger; - -/* This is an extremely simple implementation, and only - * supports the very basic log function. */ -impl log::Log for SysLogger { - fn enabled(&self, _metadata: &log::Metadata) -> bool { - true - } - - fn log(&self, record: &log::Record) { - let msg = record.args().to_string(); - let level = match record.level() { - log::Level::Error => libc::LOG_ERR, - log::Level::Warn => libc::LOG_WARNING, - log::Level::Info => libc::LOG_INFO, - log::Level::Debug => libc::LOG_DEBUG, - /* The highest libc log level is LOG_DEBUG */ - log::Level::Trace => libc::LOG_DEBUG, - }; - unsafe { - libc::syslog(level, msg.as_ptr() as *const libc::c_char); - } - } - - fn flush(&self) {} -} - -fn append_log(app_name: &str, level: LevelFilter, target: &str, file_path: Option<&str>) { - if target == "syslog" { - let _ = log::set_boxed_logger(Box::new(SysLogger)); - log::set_max_level(level); - return; - } - let config = build_log_config(app_name, level, target, file_path); - let logger = log4rs::Logger::new(config); - log::set_max_level(level); - let _ = log::set_boxed_logger(Box::new(LogPlugin(logger))); -} - -/// Init and set the sub unit manager's log -/// -/// [`app_name`]: which app output the log -/// -/// level: maximum log level -/// -/// target: log target -/// -/// file_path: file path if the target is set to file -pub fn init_log_for_subum(app_name: &str, level: LevelFilter, target: &str, file: &str) { - let file = if file.is_empty() { None } else { Some(file) }; - /* We should avoid calling init_log here, or we will get many "attempted - * to set a logger after the logging system was already initialized" error - * message. */ - append_log(app_name, level, target, file); -} - -/// Init and set the log target to console -/// -/// [`app_name`]: which app output the log -/// -/// level: maximum log level -pub fn init_log_to_console(app_name: &str, level: LevelFilter) { - init_log(app_name, level, "console", None); -} - -/// Init and set the log target to file -/// -/// [`app_name`]: which app output the log -/// -/// level: maximum log level -/// -/// file_path: log to which file -pub fn init_log_to_file(app_name: &str, level: LevelFilter, file_path: &str) { - init_log(app_name, level, "file", Some(file_path)); -} - -/// Init and set the logger -/// -/// [`app_name`]: which app output the log -/// -/// level: maximum log level -/// -/// target: log target -/// -/// file_path: file path if the target is set to file -pub fn init_log(app_name: &str, level: LevelFilter, target: &str, file_path: Option<&str>) { - if target == "syslog" { - let _ = log::set_boxed_logger(Box::new(SysLogger)); - log::set_max_level(level); - return; - } - let config = build_log_config(app_name, level, target, file_path); - let r = log4rs::init_config(config); - if let Err(e) = r { - println!("{e}"); - } -} - -fn build_log_config( - app_name: &str, - level: LevelFilter, - target: &str, - file: Option<&str>, -) -> Config { - let mut target = target; - /* If the file is configured to None, use console forcely. */ - if file.is_none() && target == "file" { - println!("LogTarget is configured to `file`, but LogFile is not configured, changing the LogTarget to `console`"); - target = "console"; - } - let encoder = Box::new(PatternEncoder::new(LOG_PATTERN)); - let appender: Box = match target { - "console" => Box::new( - ConsoleAppender::builder() - .encoder(encoder) - .target(Target::Stdout) - .build(), - ), - "file" => Box::new( - FileAppender::builder() - .encoder(encoder) - .build(file.unwrap()) - .unwrap(), - ), - _ => Box::new( - ConsoleAppender::builder() - .encoder(encoder) - .target(Target::Stdout) - .build(), - ), - }; - let logger = Logger::builder().build(app_name, level); - let root = Root::builder().appender(target).build(level); - Config::builder() - .appender(Appender::builder().build(target, appender)) - .logger(logger) - .build(root) - .unwrap() -} - -#[cfg(test)] - -mod tests { - use super::*; - use log; - #[test] - fn test_init_log_to_console() { - init_log_to_console("test", LevelFilter::Debug); - // assert_eq!((), ()); - log::info!("test for logger info"); - log::error!("test for logger error"); - log::warn!("test for logger warn"); - log::debug!("test for logger debug"); - log::trace!("test for logger trace"); - } -} diff --git a/libs/basic/src/macros.rs b/libs/basic/src/macros.rs deleted file mode 100644 index 2bb9ef7963d104b249df743f88b4df35a5b6be9e..0000000000000000000000000000000000000000 --- a/libs/basic/src/macros.rs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! macros - -/// syscall -#[macro_export] -macro_rules! syscall { - ($fn: ident ( $($arg: expr),* $(,)* ) ) => {{ - let res = unsafe { libc::$fn($($arg, )*) }; - if res < 0 { - basic::Result::Err(basic::Error::Syscall { syscall: stringify!($fn), errno: unsafe { *libc::__errno_location() }, ret: res }) - } else { - basic::Result::Ok(res) - } - }}; -} - -/// IN_SET -#[macro_export] -macro_rules! IN_SET { - ($ov:expr, $($nv:expr),+) => { - { - let mut found = false; - $( - if $ov == $nv { - found = true; - } - )+ - - found - } - }; -} diff --git a/libs/basic/src/mount_util.rs b/libs/basic/src/mount_util.rs deleted file mode 100644 index 3b041d379454be8d914bcdc94417c4f13413b6e4..0000000000000000000000000000000000000000 --- a/libs/basic/src/mount_util.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! -use crate::error::*; -use nix::{ - fcntl::AtFlags, - sys::stat::{fstatat, SFlag}, -}; - -/// -pub fn mount_point_fd_valid(fd: i32, file_name: &str, flags: AtFlags) -> Result { - assert!(fd >= 0); - - let flags = if flags.contains(AtFlags::AT_SYMLINK_FOLLOW) { - flags & !AtFlags::AT_SYMLINK_FOLLOW - } else { - flags | AtFlags::AT_SYMLINK_FOLLOW - }; - - let f_stat = fstatat(fd, file_name, flags).context(NixSnafu)?; - if SFlag::S_IFLNK.bits() & f_stat.st_mode == SFlag::S_IFLNK.bits() { - return Ok(false); - } - - let d_stat = fstatat(fd, "", AtFlags::AT_EMPTY_PATH).context(NixSnafu)?; - - if f_stat.st_dev == d_stat.st_dev && f_stat.st_ino == d_stat.st_ino { - return Ok(true); - } - - Ok(f_stat.st_dev != d_stat.st_dev) -} diff --git a/libs/basic/src/parse_util.rs b/libs/basic/src/parse_util.rs deleted file mode 100644 index 57a836c3d9de561d6437bcc8e72efb185ada77ec..0000000000000000000000000000000000000000 --- a/libs/basic/src/parse_util.rs +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! the utils can be used to deal with devnum -use crate::error::*; -use nix::{ - libc::{mode_t, S_IFBLK, S_IFCHR}, - sys::stat::makedev, -}; -use std::path::Path; - -/// given a device path, extract its mode and devnum -/// e.g. input /dev/block/8:0, output (S_IFBLK, makedev(8,0)) -pub fn device_path_parse_devnum(path: String) -> Result<(mode_t, u64)> { - let mode = if path.starts_with("/dev/block/") { - S_IFBLK - } else if path.starts_with("/dev/char/") { - S_IFCHR - } else { - return Err(Error::Nix { - source: nix::errno::Errno::ENODEV, - }); - }; - - let filename = match Path::new(&path).file_name() { - Some(s) => s.to_string_lossy().to_string(), - None => { - return Err(Error::Invalid { - what: format!("invalid path {}", path), - }) - } - }; - - Ok((mode, parse_devnum(filename)?)) -} - -/// parse the major:minor like string, and return the devnum -pub fn parse_devnum(s: String) -> Result { - let tokens: Vec<&str> = s.split(':').collect(); - if tokens.len() != 2 { - return Err(Error::Invalid { - what: format!("incorrect number of tokens: {}", s), - }); - } - - let (major, minor) = ( - tokens[0].parse::().map_err(|_| Error::Invalid { - what: format!("invalid major: {}", tokens[0]), - })?, - tokens[1].parse::().map_err(|_| Error::Invalid { - what: format!("invalid minor: {}", tokens[1]), - })?, - ); - - Ok(makedev(major, minor)) -} - -/// parse the numeric like string into ifindex number -pub fn parse_ifindex(s: String) -> Result { - s.parse::().map_err(|_| Error::Nix { - source: nix::errno::Errno::EINVAL, - }) -} - -/// parse the string into mode_t -pub fn parse_mode(mode: &str) -> Result { - match mode.parse::() { - Ok(v) => { - if v > 7777 { - return Err(Error::Nix { - source: nix::errno::Errno::ERANGE, - }); - } - - Ok(v) - } - Err(e) => Err(Error::Parse { - source: Box::new(e), - }), - } -} diff --git a/libs/basic/src/path_lookup.rs b/libs/basic/src/path_lookup.rs deleted file mode 100644 index c71130500592dcab5a5176605f6b21ef2f567555..0000000000000000000000000000000000000000 --- a/libs/basic/src/path_lookup.rs +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! the management of the unit file lookup path -use std::env; - -/// unit lookup path in /etc -pub const ETC_SYSTEM_PATH: &str = "/etc/sysmaster"; -/// unit lookup path in /run -pub const RUN_SYSTEM_PATH: &str = "/run/sysmaster"; -/// unit lookup path in /usr/lib -pub const LIB_SYSTEM_PATH: &str = "/usr/lib/sysmaster"; - -/// struct LookupPaths -#[derive(Debug, Clone)] -pub struct LookupPaths { - /// Used to search fragment, dropin, updated - pub search_path: Vec, - /// Used to search preset file - pub preset_path: Vec, - /// generator paths - pub generator: String, - /// generator early paths - pub generator_early: String, - /// generator late paths - pub generator_late: String, - /// transient paths - pub transient: String, - /// transient paths - pub persistent_path: String, -} - -impl LookupPaths { - /// new - pub fn new() -> Self { - LookupPaths { - generator: String::from(""), - generator_early: String::from(""), - generator_late: String::from(""), - transient: String::from(""), - search_path: Vec::new(), - persistent_path: String::from(""), - preset_path: Vec::new(), - } - } - - /// init lookup paths - pub fn init_lookup_paths(&mut self) { - let devel_path = || { - let out_dir = env::var("OUT_DIR").unwrap_or_else(|_x| { - let _tmp_str: Option<&'static str> = option_env!("OUT_DIR"); - _tmp_str.unwrap_or("").to_string() - }); - if out_dir.is_empty() { - env::var("LD_LIBRARY_PATH").map_or("".to_string(), |_v| { - let _tmp = _v.split(':').collect::>()[0]; - let _tmp_path = _tmp.split("target").collect::>()[0]; - _tmp_path.to_string() - }) - } else { - out_dir - } - }; - - let out_dir = devel_path(); - if !out_dir.is_empty() && out_dir.contains("build") { - let tmp_str: Vec<_> = out_dir.split("build").collect(); - self.search_path.push(tmp_str[0].to_string()); - self.preset_path.push(tmp_str[0].to_string()); - } - self.search_path.push(LIB_SYSTEM_PATH.to_string()); - self.search_path.push(RUN_SYSTEM_PATH.to_string()); - self.search_path.push(ETC_SYSTEM_PATH.to_string()); - - self.preset_path - .push(format!("{}/{}", ETC_SYSTEM_PATH, "system-preset")); - self.preset_path - .push(format!("{}/{}", LIB_SYSTEM_PATH, "system-preset")); - - self.persistent_path = ETC_SYSTEM_PATH.to_string(); - } -} - -impl Default for LookupPaths { - fn default() -> Self { - Self::new() - } -} - -#[cfg(test)] -mod tests { - - use std::env; - - use crate::logger; - - use super::LookupPaths; - #[test] - fn test_init_lookup_paths() { - logger::init_log_to_console("test_init_lookup_paths", log::LevelFilter::Trace); - let mut _lp = LookupPaths::default(); - _lp.init_lookup_paths(); - for item in _lp.search_path.iter() { - log::info!("lookup path is{:?}", item); - } - let tmp_dir = env::var("OUT_DIR"); - if tmp_dir.is_err() { - return; - } - let tmp = tmp_dir.unwrap(); - let tmp_dir_v: Vec<_> = tmp.split("build").collect(); - assert_eq!( - _lp.search_path.first().unwrap().to_string(), - tmp_dir_v[0].to_string() - ); - } -} diff --git a/libs/basic/src/path_util.rs b/libs/basic/src/path_util.rs deleted file mode 100644 index 4ac9de9bb3308c1f81d57075f0f35762302a5ff6..0000000000000000000000000000000000000000 --- a/libs/basic/src/path_util.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! the utils of the path operation -//! -use std::path::Path; - -/// return true if the path of a and b equaled. -pub fn path_equal(a: &str, b: &str) -> bool { - let p_a = Path::new(a); - let p_b = Path::new(b); - p_a == p_b -} - -#[cfg(test)] -mod tests { - use crate::path_util::path_equal; - - #[test] - fn test_path_equal() { - assert!(path_equal("/etc", "/etc")); - assert!(path_equal("//etc", "/etc")); - assert!(path_equal("/etc//", "/etc")); - assert!(!path_equal("/etc", "./etc")); - assert!(path_equal("/x/./y", "/x/y")); - assert!(path_equal("/x/././y", "/x/y/./.")); - assert!(!path_equal("/etc", "/var")); - } -} diff --git a/libs/basic/src/proc_cmdline.rs b/libs/basic/src/proc_cmdline.rs deleted file mode 100644 index 9628e09a5113e7806485f6738a6835cf2897b034..0000000000000000000000000000000000000000 --- a/libs/basic/src/proc_cmdline.rs +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! -use crate::conf_parser; -use crate::error::*; -use nix::unistd::Pid; -use std::fs::File; -use std::io::{BufReader, Read}; -use std::path::Path; - -fn cmdline_content() -> Result { - let mut file = File::open("/proc/cmdline").context(IoSnafu)?; - - let mut buf = String::new(); - match file.read_to_string(&mut buf) { - Ok(s) => s, - Err(e) => { - return Err(Error::Io { source: e }); - } - }; - Ok(buf) -} - -/// read the content from /proc/cmdline and return the value depend the key -pub fn cmdline_get_value(key: &str) -> Result, Error> { - let buf = cmdline_content()?; - - let cmdline: Vec<&str> = buf.split_whitespace().collect(); - - for cmd in cmdline.iter() { - if let Some(k_val) = cmd.split_once('=') { - if k_val.0 == key { - return Ok(Some(k_val.1.to_string())); - } - } - } - - Ok(None) -} - -/// read the content from /proc/cmdline and return specified item -///- -/// take `crashkernel=512M ro` for example, given `crashkernel` will -/// return `crashkernel=512M`, given `ro` will return `ro`, given -/// `foo` will return None. -pub fn cmdline_get_item(item: &str) -> Result, Error> { - let buf = cmdline_content()?; - let pair_item = item.to_string() + "="; - let cmdline: Vec<&str> = buf.split_whitespace().collect(); - - for cmd in cmdline.iter() { - if cmd.starts_with(&pair_item) || cmd.eq(&item) { - return Ok(Some(cmd.to_string())); - } - } - - Ok(None) -} - -/// read the content from /proc/cmdline and return the bool value depend the key -pub fn proc_cmdline_get_bool(key: &str) -> Result { - let val = cmdline_get_value(key)?; - - if val.is_none() { - return Ok(false); - } - - let r = conf_parser::parse_boolean(&val.unwrap())?; - - Ok(r) -} - -/// read /proc/PID/cmdline and return -pub fn get_process_cmdline(pid: &Pid) -> String { - let pid_str = pid.to_string(); - let cmdline_path = Path::new("/proc").join(pid_str).join("cmdline"); - let file = match File::open(cmdline_path) { - Ok(file) => file, - Err(_) => { - return String::from(""); - } - }; - let buf_reader = BufReader::new(file); - let mut cmdline_content = String::new(); - for byte in buf_reader.bytes() { - let b = match byte { - Ok(b) => b, - Err(_) => break, - }; - let b = if b != 0 { b as char } else { ' ' }; - cmdline_content += &b.to_string(); - } - cmdline_content -} diff --git a/libs/basic/src/process_util.rs b/libs/basic/src/process_util.rs deleted file mode 100644 index aeb6e880d3228119afb9b896ae553e7eff97852b..0000000000000000000000000000000000000000 --- a/libs/basic/src/process_util.rs +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! -use crate::error::*; -use crate::file_util; -use nix::errno::errno; -use nix::errno::Errno; -use nix::libc::{kill, ESRCH}; -use nix::sys::signal::Signal; -use nix::sys::wait::{waitpid, WaitPidFlag}; -use nix::unistd::Pid; -use procfs::process::Stat; -use std::collections::HashSet; -use std::fs::{read_dir, File}; -use std::path::{Path, PathBuf}; -use std::thread::sleep; -use std::time::{Duration, SystemTime}; - -/// -pub fn process_state(pid: Pid) -> Result { - if pid == Pid::from_raw(0) || pid == nix::unistd::getpid() { - return Ok('R'); - } - - let proc_file = format!("/proc/{:?}/stat", pid.as_raw()); - let stat_path = Path::new(&proc_file); - let first_line = file_util::read_first_line(stat_path)?; - let stat: Vec = first_line - .split_whitespace() - .map(|s| s.to_string()) - .collect(); - - if stat.len() < 3 { - return Err(Error::Invalid { - what: "process stat format".to_string(), - }); - } - - let p_stat: Vec = stat[3].trim().chars().collect(); - - if p_stat.is_empty() { - return Err(Error::Invalid { - what: "process state".to_string(), - }); - } - Ok(p_stat[0]) -} - -/// -pub fn alive(pid: Pid) -> bool { - if pid < Pid::from_raw(0) { - return false; - } - - if pid <= Pid::from_raw(1) { - return true; - } - - if pid == nix::unistd::getpid() { - return true; - } - - let ret = process_state(pid); - if ret.is_err() { - return false; - } - if ret.unwrap() == 'Z' { - return false; - } - - true -} - -/// -pub fn valid_pid(pid: Pid) -> bool { - if pid <= Pid::from_raw(0) { - return false; - } - - true -} - -/// -pub fn kill_all_pids(signal: i32) -> HashSet { - let mut pids: HashSet = HashSet::new(); - let proc_path = Path::new("/proc"); - let read_dir = read_dir(proc_path).unwrap(); - for entry in read_dir.flatten() { - // Skip files. - if let Ok(file_type) = entry.file_type() { - if file_type.is_file() { - continue; - } - } - let file_name = String::from(entry.file_name().to_str().unwrap()); - // Check pid directory. - if let Ok(pid_raw) = file_name.parse::() { - unsafe { - log::debug!("killing pid: {} by signal {}", pid_raw, signal); - kill(pid_raw, signal); - pids.insert(pid_raw); - } - } else { - continue; - } - } - // return PIDs we want to kill - pids -} - -/// -pub fn wait_pids(mut pids: HashSet, timeout: u64) -> HashSet { - let now = SystemTime::now(); - let until = now + Duration::from_micros(timeout); - - // remove PID1, we shouldn't wait our self and init. - pids.remove(&1); - pids.remove(&nix::unistd::getpid().into()); - - loop { - // 1. Find killed process by kernel. - while let Ok(wait_status) = waitpid(Pid::from_raw(-1), Some(WaitPidFlag::WNOHANG)) { - if let Some(pid) = wait_status.pid() { - log::debug!("successfully killed pid: {} found by kernel.", pid.as_raw()); - pids.remove(&pid.as_raw()); - } else { - break; - } - } - // 2. Find killed process by sending sig: 0. - let mut removed_pids: HashSet = HashSet::new(); - for pid in &pids { - unsafe { - let res = kill(*pid, 0); - if res == 0 || errno() != ESRCH { - continue; - } - removed_pids.insert(*pid); - } - } - for pid in removed_pids { - log::debug!("successfully killed pid: {} found by ourself.", pid); - pids.remove(&pid); - } - // 3. Sleep 1s to wait pid exits. - sleep(Duration::from_secs(1)); - // 4. Wait or give up. - if pids.is_empty() { - break; - } - if SystemTime::now() >= until { - log::info!("some pids haven't been killed yet, stop waiting."); - break; - } - } - pids -} - -/// get the parent pid of the reference pid -fn get_ppid(pid: Pid) -> Result { - if pid == Pid::from_raw(0) || pid == nix::unistd::getpid() { - return Ok(nix::unistd::getppid()); - } - - let path = PathBuf::from(format!("/proc/{pid}/stat")); - - let stat = Stat::from_reader(File::open(path).context(IoSnafu)?).context(ProcSnafu)?; - - Ok(Pid::from_raw(stat.ppid)) -} - -/// return true if the pid is the child of calling process, other false. -pub fn my_child(pid: Pid) -> bool { - if pid.as_raw() <= 1 { - return false; - } - - let ppid = get_ppid(pid); - - if let Ok(p) = ppid { - return p == nix::unistd::getpid(); - } - - false -} - -/// send signal to pid, send SIGCONT if the signal is not SIGCONT or SIGKILL -pub fn kill_and_cont(pid: Pid, sig: Signal) -> Result<(), Errno> { - match nix::sys::signal::kill(pid, sig) { - Ok(_) => { - if sig != Signal::SIGCONT && sig != Signal::SIGKILL { - _ = nix::sys::signal::kill(pid, Signal::SIGCONT); - } - Ok(()) - } - Err(e) => Err(e), - } -} - -#[cfg(test)] -mod tests { - use nix::libc::kill; - use std::collections::HashSet; - use std::process::Command; - use std::thread; - - use crate::process_util::wait_pids; - #[test] - fn test_wait_pids() { - let mut pids: HashSet = HashSet::new(); - for i in 100..109 { - let str_i = i.to_string(); - let child = Command::new("/usr/bin/sleep") - .args([str_i.as_str()]) - .spawn() - .expect("Failed to fork /usr/bin/sleep"); - pids.insert(child.id() as i32); - } - - let pids_spawn = pids.clone(); - thread::spawn(move || { - for pid in pids_spawn { - unsafe { - kill(pid, 15); - } - } - }); - - let res = wait_pids(pids, 10000000); - assert_eq!(res.len(), 0); - } -} diff --git a/libs/basic/src/rlimit_util.rs b/libs/basic/src/rlimit_util.rs deleted file mode 100644 index 93ca8b6f4bd7c2288a292085fb6411190b1eac3f..0000000000000000000000000000000000000000 --- a/libs/basic/src/rlimit_util.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! the utils of the rlimit operation -//! - -use libc; -use std::io::Error; -use std::mem; - -/// indicate no limit -pub const INFINITY: u64 = libc::RLIM_INFINITY; - -/// get the rlimit value -pub fn getrlimit(resource: u8) -> Result<(u64, u64), Error> { - let mut rlimit = unsafe { mem::zeroed() }; - - let ret = unsafe { libc::getrlimit(resource as _, &mut rlimit) }; - - if ret == 0 { - return Ok((rlimit.rlim_cur, rlimit.rlim_max)); - } - - Err(Error::last_os_error()) -} - -/// set resource limit -pub fn setrlimit(resource: u8, soft: u64, hard: u64) -> Result<(), Error> { - let rlimit = libc::rlimit { - rlim_cur: soft as _, - rlim_max: hard as _, - }; - - let ret = unsafe { libc::setrlimit(resource as _, &rlimit) }; - if ret == 0 { - Ok(()) - } else { - Err(Error::last_os_error()) - } -} diff --git a/libs/basic/src/security.rs b/libs/basic/src/security.rs deleted file mode 100644 index bff0b4e8f75e296336b94a64f6cb4a1d67b04650..0000000000000000000000000000000000000000 --- a/libs/basic/src/security.rs +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! some common used security functions - -#[allow(unused_imports)] -use std::{ - fs::File, - io::{BufReader, Read}, - os::{raw::c_int, unix::prelude::AsRawFd}, - path::Path, -}; - -use nix::{ - errno::Errno, - sys::{ - socket::{socket, AddressFamily, SockFlag, SockProtocol, SockType}, - stat::fstat, - }, -}; - -#[cfg(feature = "selinux")] -#[link(name = "selinux")] -extern "C" { - fn is_selinux_enabled() -> c_int; -} - -#[cfg(feature = "selinux")] -/// check if selinux is enabled -pub fn selinux_enabled() -> bool { - let res = unsafe { is_selinux_enabled() }; - res > 0 -} - -#[cfg(not(feature = "selinux"))] -/// check if selinux is enabled -pub fn selinux_enabled() -> bool { - false -} - -/// check if smack is enabled -pub fn smack_enabled() -> bool { - Path::new("/sys/fs/smackfs").exists() -} - -/// check if apparmor is enabled -pub fn apparmor_enabled() -> bool { - let mut file = match File::open("/sys/module/apparmor/parameters/enabled") { - Err(_) => { - return false; - } - Ok(v) => v, - }; - let mut buf = [0u8; 2]; - let _ = file.read_exact(&mut buf); - buf == [b'Y', b'\n'] -} - -/// check if audit is enabled -pub fn audit_enabled() -> bool { - match socket( - AddressFamily::Netlink, - SockType::Raw, - SockFlag::SOCK_CLOEXEC | SockFlag::SOCK_NONBLOCK, - SockProtocol::NetlinkAudit, - ) { - Ok(fd) => fd > 0, - Err(Errno::EAFNOSUPPORT) | Err(Errno::ENOTSUP) | Err(Errno::EPERM) => false, - Err(_) => true, - } -} - -/// check if ima is enabled -pub fn ima_enabled() -> bool { - Path::new("/sys/kernel/security/ima/").exists() -} - -/// check if the tomoyo is enabled -pub fn tomoyo_enabled() -> bool { - Path::new("/sys/kernel/security/tomoyo/version").exists() -} - -/// check if the uefi-secureboot is enabled -pub fn uefi_secureboot_enabled() -> bool { - /* mokutil check 3 files to tell if the system is secure boot enabled, - * while systemd only checks one file, we decide to copy the logic of - * systemd. The 128-bit id is a magic number, See: - * https://uefi.org/sites/default/files/resources/UEFI_Spec_Errata_Only.pdf */ - let uefi_file_path = - "/sys/firmware/efi/efivars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c"; - let file = match File::open(uefi_file_path) { - Err(_) => { - return false; - } - Ok(v) => v, - }; - let stat = match fstat(file.as_raw_fd()) { - Err(_) => return false, - Ok(v) => v, - }; - - /* file too small or too large. */ - if stat.st_size < 4 || stat.st_size > 4 * 1024 * 1024 + 4 { - return false; - } - - let mut reader = BufReader::new(file); - /* The file should be 5 bytes, the first 4 bytes is attribute, - * the following 1 byte is value, we only care the last 1 byte - * here. */ - let mut buf = [0_u8; 5]; - if reader.read_exact(&mut buf).is_err() { - return false; - } - let value = *buf.get(4).unwrap(); - - value > 0 -} - -/// check if the tpm2 is enabled -pub fn tpm2_enabled() -> bool { - Path::new("/sys/class/tpmrm").exists() -} diff --git a/libs/basic/src/show_table.rs b/libs/basic/src/show_table.rs deleted file mode 100644 index 76133f8d801961b23f6a891ad4a43ec01354550a..0000000000000000000000000000000000000000 --- a/libs/basic/src/show_table.rs +++ /dev/null @@ -1,505 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! ShowTable can be used to display contents in a table format -//! ```rust,ignore -//! This is called column -//! | -//! v -//! Cell(0,0) Cell(0,1) Cell(0,2) -> This is called Line, or row -//! Cell(1,0) Cell(1,1) Cell(1,2) -//! Cell(2,0) ... ... -//! ``` -use std::fmt::Display; - -/// The alignment of one cell -#[derive(Clone, Copy, PartialEq, Eq)] -pub enum CellAlign { - /// - Left, - /// - Right, - /// - Center, -} - -/// The color of one cell -#[derive(Clone, Copy, PartialEq, Eq)] -pub enum CellColor { - /// - Empty, - /// - Grey, - /// - Red, - /// - Green, - /// - Yellow, - /// - Blue, - /// - Purple, -} - -impl From for String { - /// Change the CellColor to the magic string - fn from(cell_color: CellColor) -> Self { - match cell_color { - CellColor::Empty => "[37m".to_string(), - CellColor::Grey => "[30m".to_string(), - CellColor::Red => "[31m".to_string(), - CellColor::Green => "[32m".to_string(), - CellColor::Yellow => "[33m".to_string(), - CellColor::Blue => "[34m".to_string(), - CellColor::Purple => "[35m".to_string(), - } - } -} - -/// Table Cell -pub struct Cell { - color: CellColor, - align: CellAlign, - underline: bool, - left_space: bool, - right_space: bool, - /* this cell's width, don't consider cells in other lines */ - width: usize, - x_index: usize, - split_content: Vec, -} - -impl Cell { - /// Create a new cell - pub fn new(ori_content: Option<&str>, x_index: usize) -> Self { - let mut width = 0; - let mut split_content: Vec = Vec::new(); - match ori_content { - None => { - width = 0; - split_content.push(String::new()); - } - Some(ori_content) => { - for cell_line in ori_content.split('\n') { - width = std::cmp::max(width, cell_line.len()); - split_content.push(cell_line.to_string()); - } - } - } - - Cell { - color: CellColor::Empty, - underline: false, - align: CellAlign::Left, - left_space: true, - right_space: true, - width, - x_index, - split_content, - } - } - - /// Set the color of one cell - pub fn set_color(&mut self, color: CellColor) { - self.color = color; - } - - /// Set the alignment of one cell - pub fn set_align(&mut self, align: CellAlign) { - self.align = align; - } - - /// Set the cell's content underlined - pub fn set_underline(&mut self, use_underline: bool) { - self.underline = use_underline; - } - - /// Set if keep the cell's left space - pub fn set_left_space(&mut self, use_space: bool) { - self.left_space = use_space; - } - - /// Set if keep the cell's right space - pub fn set_right_space(&mut self, use_space: bool) { - self.right_space = use_space; - } - - /// Print one line of a cell out - /// - /// * i: print which line - /// - /// * width: the cell's width - /// - /// * height: the cell's height - pub fn format_cell_line(&self, i: usize, width: usize, height: usize) -> String { - let mut res = String::new(); - if i >= self.split_content.len() { - res += &" ".repeat(width); - } else { - res += &self.split_content[i]; - } - if self.align == CellAlign::Left && width > res.len() { - res += &" ".repeat(width - res.len()); - } else if self.align == CellAlign::Right && width > res.len() { - res = " ".repeat(width - res.len()) + &res; - } else if self.align == CellAlign::Center && width > res.len() { - let left_size = (width - res.len()) / 2; - res = " ".repeat(left_size) + &res; - res += &" ".repeat(width - res.len()); - } - if self.left_space { - res = " ".to_string() + &res; - } - if self.right_space { - res += " "; - } - let mut prefix = String::new(); - if self.color != CellColor::Empty { - prefix = "\x1b".to_string() + &String::from(self.color); - } - if i == height - 1 && self.underline { - prefix += "\x1b[4m"; - } - if !prefix.is_empty() { - res = prefix + &res + "\x1b[0m"; - } - res - } -} - -/// Table Line -pub struct Line { - /// Height of this total line - height: usize, - /// Width of this line, don't consider other lines - per_widths: Vec, - /// Cells of this line - cells: Vec, -} - -impl Line { - /// Create an empty line - pub fn empty() -> Self { - Self { - per_widths: Vec::new(), - height: 0, - cells: Vec::new(), - } - } - /// Create a new line by a Vec<&str> - pub fn new(ori_contents: Vec<&str>) -> Self { - let mut per_widths = Vec::new(); - let mut height = 0; - let mut cells = Vec::new(); - for (x_index, ori_content) in ori_contents.into_iter().enumerate() { - let cell = Cell::new(Some(ori_content), x_index); - height = std::cmp::max(cell.split_content.len(), height); - per_widths.push(cell.width); - cells.push(cell); - } - Self { - height, - per_widths, - cells, - } - } -} - -/// ShowTable -pub struct ShowTable { - /* width of the table, don't consider left_space or right_space. */ - global_widths: Vec, - lines: Vec, -} - -impl ShowTable { - /// Create a new empty ShowTable - pub fn new() -> Self { - Self { - global_widths: Vec::new(), - lines: Vec::new(), - } - } - - /// Add a ShowTableLine to ShowTable - pub fn add_show_table_item(&mut self, show_table_line: &impl ShowTableLine) { - let line = show_table_line.to_vec(); - self.add_line(line); - } - - /// Add a single line to ShowTable - pub fn add_line(&mut self, ori_contents: Vec<&str>) { - let line = Line::new(ori_contents); - /* The table is empty. */ - if self.global_widths.is_empty() { - for v in &line.per_widths { - self.global_widths.push(*v); - } - } else { - if line.per_widths.len() != self.global_widths.len() { - log::error!("Can not add this line to ShowTable, their lengths are different."); - return; - } - for i in 0..line.per_widths.len() { - self.global_widths[i] = std::cmp::max(self.global_widths[i], line.per_widths[i]); - } - } - self.lines.push(line); - } - /// Set all cells's alignment to left - pub fn set_all_cell_align_left(&mut self) { - for i in 0..self.lines.len() { - for j in 0..self.lines[i].cells.len() { - self.lines[i].cells[j].align = CellAlign::Left; - } - } - } - /// Set all cell's alignment to right - pub fn set_all_cell_align_right(&mut self) { - for i in 0..self.lines.len() { - for j in 0..self.lines[i].cells.len() { - self.lines[i].cells[j].align = CellAlign::Right; - } - } - } - /// Set all cells' alignment to center - pub fn set_all_cell_align_center(&mut self) { - for i in 0..self.lines.len() { - for j in 0..self.lines[i].cells.len() { - self.lines[i].cells[j].align = CellAlign::Center; - } - } - } - /// Set a certain row's alignment - pub fn set_one_row_align(&mut self, i: usize, align: CellAlign) { - for j in 0..self.lines[i].cells.len() { - self.lines[i].cells[j].align = align; - } - } - /// Set current row's alignment - /// - /// This is useful when one add a new line, and wants to change its format immediately. - pub fn set_current_row_align(&mut self, align: CellAlign) { - let total_line = self.lines.len(); - if total_line < 1 { - log::info!("Failed to set current row's align."); - return; - } - for j in 0..self.lines[total_line - 1].cells.len() { - self.lines[total_line - 1].cells[j].align = align; - } - } - /// Set a certain column's alignment - pub fn set_one_col_align(&mut self, j: usize, align: CellAlign) { - for i in 0..self.lines.len() { - self.lines[i].cells[j].align = align; - } - } - /// Set a cell's alignment - pub fn set_one_cell_align(&mut self, i: usize, j: usize, align: CellAlign) { - self.lines[i].cells[j].align = align; - } - /// Set all cells' split space - pub fn set_all_cell_space(&mut self, left_space: bool, right_space: bool) { - for i in 0..self.lines.len() { - for j in 0..self.lines[i].cells.len() { - self.lines[i].cells[j].left_space = left_space; - self.lines[i].cells[j].right_space = right_space; - } - } - } - /// Set one row's split space - pub fn set_one_row_space(&mut self, i: usize, left_space: bool, right_space: bool) { - for j in 0..self.lines[i].cells.len() { - self.lines[i].cells[j].left_space = left_space; - self.lines[i].cells[j].right_space = right_space; - } - } - /// Set one column's split space - pub fn set_one_col_space(&mut self, j: usize, left_space: bool, right_space: bool) { - for i in 0..self.lines.len() { - self.lines[i].cells[j].left_space = left_space; - self.lines[i].cells[j].right_space = right_space; - } - } - /// Set one cell's split space - pub fn set_one_cell_space(&mut self, i: usize, j: usize, left_space: bool, right_space: bool) { - self.lines[i].cells[j].left_space = left_space; - self.lines[i].cells[j].right_space = right_space; - } - /// Set all cells' underline - pub fn set_all_cell_underline(&mut self, use_underline: bool) { - for i in 0..self.lines.len() { - for j in 0..self.lines[i].cells.len() { - self.lines[i].cells[j].underline = use_underline; - } - } - } - /// Set one row's underline - pub fn set_one_row_underline(&mut self, i: usize, use_underline: bool) { - for j in 0..self.lines[i].cells.len() { - self.lines[i].cells[j].underline = use_underline; - } - } - /// Set the current row's underline - pub fn set_current_row_underline(&mut self, use_underline: bool) { - let total_line = self.lines.len(); - if total_line < 1 { - log::info!("Failed to set current row's underline."); - return; - } - for j in 0..self.lines[total_line - 1].cells.len() { - self.lines[total_line - 1].cells[j].underline = use_underline; - } - } - /// Set one column's underline - pub fn set_one_col_underline(&mut self, j: usize, use_underline: bool) { - for i in 0..self.lines.len() { - self.lines[i].cells[j].underline = use_underline; - } - } - /// Set one cell's underline - pub fn set_one_cell_underline(&mut self, i: usize, j: usize, use_underline: bool) { - self.lines[i].cells[j].underline = use_underline; - } - /// Set all cells' color - pub fn set_all_cell_color(&mut self, color: CellColor) { - for i in 0..self.lines.len() { - for j in 0..self.lines[i].cells.len() { - self.lines[i].cells[j].color = color; - } - } - } - /// Set one row's color - pub fn set_one_row_color(&mut self, i: usize, color: CellColor) { - for j in 0..self.lines[i].cells.len() { - self.lines[i].cells[j].color = color; - } - } - /// Set current row's color - pub fn set_current_row_color(&mut self, color: CellColor) { - let total_line = self.lines.len(); - if total_line < 1 { - log::info!("Failed to set current row's color."); - return; - } - for j in 0..self.lines[total_line - 1].cells.len() { - self.lines[total_line - 1].cells[j].color = color; - } - } - /// Set one column's color - pub fn set_one_col_color(&mut self, j: usize, color: CellColor) { - for i in 0..self.lines.len() { - self.lines[i].cells[j].color = color; - } - } - /// Set one cell's color - pub fn set_one_cell_color(&mut self, i: usize, j: usize, color: CellColor) { - self.lines[i].cells[j].color = color; - } -} - -impl Default for ShowTable { - fn default() -> Self { - Self::new() - } -} - -impl Display for ShowTable { - /// Print the whole ShowTable out - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let mut res = String::new(); - /* print one line */ - for line in &self.lines { - /* The cell can be multi-cell_line, print one by one */ - for i in 0..line.height { - for cell in &line.cells { - res += &cell.format_cell_line(i, self.global_widths[cell.x_index], line.height); - } - res += "\n"; - } - } - write!(f, "{}", res.trim_end()) - } -} - -/// Struct can implement this trait to display in ShowTable -pub trait ShowTableLine { - /// change the struct to the string vector - fn to_vec(&self) -> Vec<&str> { - todo!() - } -} - -mod tests { - use super::ShowTableLine; - - struct TestItem { - value1: String, - value2: String, - value3: String, - } - - impl ShowTableLine for TestItem { - fn to_vec(&self) -> Vec<&str> { - vec![&self.value1, &self.value2, &self.value3] - } - } - - #[test] - fn run_test() { - use super::ShowTable; - let mut table1 = ShowTable::new(); - table1.add_line(vec!["AAA", "BBBB", "CCCCCCCCCC"]); - table1.add_line(vec!["12345", "123", "123"]); - assert_eq!( - table1.to_string(), - " AAA BBBB CCCCCCCCCC \n 12345 123 123" - ); - table1.set_all_cell_align_right(); - assert_eq!( - table1.to_string(), - " AAA BBBB CCCCCCCCCC \n 12345 123 123" - ); - table1.set_all_cell_align_left(); - table1.set_one_row_align(0, crate::show_table::CellAlign::Right); - assert_eq!( - table1.to_string(), - " AAA BBBB CCCCCCCCCC \n 12345 123 123" - ); - table1.set_all_cell_align_right(); - table1.set_one_col_align(0, crate::show_table::CellAlign::Left); - assert_eq!( - table1.to_string(), - " AAA BBBB CCCCCCCCCC \n 12345 123 123" - ); - - let test_item1 = TestItem { - value1: "AAA".to_string(), - value2: "BBBB".to_string(), - value3: "CCCCCCCCCC".to_string(), - }; - let test_item2 = TestItem { - value1: "12345".to_string(), - value2: "123".to_string(), - value3: "123".to_string(), - }; - let mut table2 = ShowTable::new(); - table2.add_show_table_item(&test_item1); - table2.add_show_table_item(&test_item2); - assert_eq!( - table2.to_string(), - " AAA BBBB CCCCCCCCCC \n 12345 123 123" - ); - } -} diff --git a/libs/basic/src/socket_util.rs b/libs/basic/src/socket_util.rs deleted file mode 100644 index c2fd2f8bf92623c3629196ad880287d0041244d3..0000000000000000000000000000000000000000 --- a/libs/basic/src/socket_util.rs +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! -use crate::error::*; -use nix::{ - errno::Errno, - sys::socket::{self, sockopt, AddressFamily}, -}; -use std::{os::unix::prelude::RawFd, path::Path}; - -/// -pub fn ipv6_is_supported() -> bool { - let inet6 = Path::new("/proc/net/if_inet6"); - - if inet6.exists() { - return true; - } - - false -} - -/// -pub fn set_pkginfo(fd: RawFd, family: AddressFamily, v: bool) -> Result<()> { - match family { - socket::AddressFamily::Inet => { - socket::setsockopt(fd as RawFd, sockopt::Ipv4PacketInfo, &v).context(NixSnafu) - } - socket::AddressFamily::Inet6 => { - socket::setsockopt(fd as RawFd, sockopt::Ipv6RecvPacketInfo, &v).context(NixSnafu) - } - _ => Err(Error::Nix { - source: Errno::EAFNOSUPPORT, - }), - } -} - -/// -pub fn set_pass_cred(fd: RawFd, v: bool) -> Result<()> { - socket::setsockopt(fd, sockopt::PassCred, &v).context(NixSnafu) -} - -/// -pub fn set_receive_buffer(fd: RawFd, v: usize) -> Result<()> { - socket::setsockopt(fd, sockopt::RcvBuf, &v).context(NixSnafu) -} - -/// -pub fn set_send_buffer(fd: RawFd, v: usize) -> Result<()> { - socket::setsockopt(fd, sockopt::SndBuf, &v).context(NixSnafu) -} - -/// Require specific privileges to ignore the kernel limit -pub fn set_receive_buffer_force(fd: RawFd, v: usize) -> Result<()> { - socket::setsockopt(fd, sockopt::RcvBufForce, &v).context(NixSnafu) -} - -/// Set keepalive properties -pub fn set_keepalive_state(fd: RawFd, v: bool) -> Result<()> { - socket::setsockopt(fd, sockopt::KeepAlive, &v).context(NixSnafu) -} - -/// Set the interval between the last data packet sent and the first keepalive probe -pub fn set_keepalive_timesec(fd: RawFd, v: u32) -> Result<()> { - socket::setsockopt(fd, sockopt::TcpKeepIdle, &v).context(NixSnafu) -} - -/// Set the interval between subsequential keepalive probes -pub fn set_keepalive_intervalsec(fd: RawFd, v: u32) -> Result<()> { - socket::setsockopt(fd, sockopt::TcpKeepInterval, &v).context(NixSnafu) -} - -/// Set the number of unacknowledged probes to send -pub fn set_keepalive_probes(fd: RawFd, v: u32) -> Result<()> { - socket::setsockopt(fd, sockopt::TcpKeepCount, &v).context(NixSnafu) -} - -/// Set Broadcast state -pub fn set_broadcast_state(fd: RawFd, v: bool) -> Result<()> { - socket::setsockopt(fd, sockopt::Broadcast, &v).context(NixSnafu) -} diff --git a/libs/basic/src/special.rs b/libs/basic/src/special.rs deleted file mode 100644 index 0266af3a6e6b47508a9631741bf1fc055fc106a6..0000000000000000000000000000000000000000 --- a/libs/basic/src/special.rs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! the special name of the system unit - -/// default startup target -pub const DEFAULT_TARGET: &str = "default.target"; -/// the shutdown target -pub const SHUTDOWN_TARGET: &str = "shutdown.target"; -/// the socketc target -pub const SOCKETS_TARGET: &str = "sockets.target"; - -/// early boot targets -pub const SYSINIT_TARGET: &str = "sysinit.target"; -/// the basic start target -pub const BASIC_TARGET: &str = "basic.target"; - -/// Special user boot targets */ -pub const MULTI_USER_TARGET: &str = "multi-user.target"; - -/// the init scope -pub const INIT_SCOPE: &str = "init.scope"; -/// sysmaster service slice -pub const SYSMASTER_SLICE: &str = "system.slice"; - -/// the unit store sysmaster itself -pub const CGROUP_SYSMASTER: &str = "sysmaster"; - -/// the default running time directory of sysmaster -pub const EXEC_RUNTIME_PREFIX: &str = "/run"; diff --git a/libs/basic/src/stat_util.rs b/libs/basic/src/stat_util.rs deleted file mode 100644 index 9d4bb0f27ee31f918d21a231d2558d6aa5969ff3..0000000000000000000000000000000000000000 --- a/libs/basic/src/stat_util.rs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! utility for stat -//! - -use super::{Error, Result}; -use nix::{ - errno::Errno, - sys::statfs::{self, FsType}, -}; - -#[cfg(any( - all(target_os = "linux", not(target_env = "musl")), - target_os = "android" -))] -use nix::sys::statfs::PROC_SUPER_MAGIC; - -/// check whether a path is specific file system type -pub fn path_is_fs_type(path: &str, magic: FsType) -> Result { - let s = statfs::statfs(path).map_err(|e| Error::Nix { source: e })?; - - Ok(s.filesystem_type() == magic) -} - -/// check whether /proc is mounted -pub fn proc_mounted() -> Result { - #[cfg(any( - all(target_os = "linux", not(target_env = "musl")), - target_os = "android" - ))] - match path_is_fs_type("/proc/", PROC_SUPER_MAGIC) { - Ok(r) => return Ok(r), - Err(e) => match e { - Error::Nix { - source: Errno::ENOENT, - } => {} - _ => return Err(e), - }, - } - - Ok(false) -} diff --git a/libs/basic/src/string.rs b/libs/basic/src/string.rs deleted file mode 100644 index cac318979a457e10c3439b8a56ba754f329250a0..0000000000000000000000000000000000000000 --- a/libs/basic/src/string.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! Common used string functions - -/// Add "\n" to s. -/// This can be used when generating a multi-line string. -/// Use this function before you write a new line. -pub fn new_line_break(s: &mut String) { - if !s.is_empty() { - *s += "\n"; - } -} diff --git a/libs/basic/src/time_util.rs b/libs/basic/src/time_util.rs deleted file mode 100644 index 45a12af1633871af88287070760d366e099261f2..0000000000000000000000000000000000000000 --- a/libs/basic/src/time_util.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! -use std::time::SystemTime; - -const USEC_INFINITY: u128 = u128::MAX; - -/// usec per sec -pub const USEC_PER_SEC: u64 = 1000000; - -/// -pub fn timespec_load(systime: SystemTime) -> u128 { - match systime.duration_since(SystemTime::UNIX_EPOCH) { - Ok(d) => d.as_micros(), - Err(_) => USEC_INFINITY, - } -} diff --git a/libs/basic/src/user_group_util.rs b/libs/basic/src/user_group_util.rs deleted file mode 100644 index bd9e4b27e0078ec4781996a18b3d618939b9a6de..0000000000000000000000000000000000000000 --- a/libs/basic/src/user_group_util.rs +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! Common used functions to parse user and group - -use crate::error::*; -use nix::libc::uid_t; -use nix::unistd::{Gid, Group, Uid, User}; - -/// Parse a string as UID -pub fn parse_uid(uid_str: &String) -> Result { - if uid_str.is_empty() { - return Err(Error::Invalid { - what: "UID is empty".to_string(), - }); - } - - if uid_str.eq("0") { - // This shouldn't fail. - return Ok(User::from_uid(Uid::from_raw(0)).unwrap().unwrap()); - } - - let mut first = true; - for c in uid_str.bytes() { - // uid must only contains 0-9 - if !first && c.is_ascii_digit() { - continue; - } - // uid must starts with 1-9 - if first && (b'1'..=b'9').contains(&c) { - first = false; - continue; - } - return Err(Error::Invalid { - what: "UID must only contains 0-9 and shouldn't starts with 0".to_string(), - }); - } - - let uid = match uid_str.parse::() { - Err(e) => { - return Err(e.into()); - } - Ok(v) => v, - }; - - let user = match User::from_uid(Uid::from_raw(uid)) { - Err(e) => { - return Err(Error::Nix { source: e }); - } - Ok(v) => v, - }; - - match user { - None => Err(Error::Invalid { - what: "No matched UID".to_string(), - }), - Some(v) => Ok(v), - } -} - -/// Parse a string as UID -pub fn parse_gid(gid_str: &String) -> Result { - // Same logic as parse_uid() - if gid_str.is_empty() { - return Err(Error::Invalid { - what: "GID is empty".to_string(), - }); - } - - if gid_str.eq("0") { - return Ok(Group::from_gid(Gid::from_raw(0)).unwrap().unwrap()); - } - - let mut first = true; - for c in gid_str.bytes() { - if !first && c.is_ascii_digit() { - continue; - } - if first && (b'1'..=b'9').contains(&c) { - first = false; - continue; - } - return Err(Error::Invalid { - what: "GID must only contains 0-9 and shouldn't starts with 0".to_string(), - }); - } - - let gid = match gid_str.parse::() { - Err(e) => { - return Err(e.into()); - } - Ok(v) => v, - }; - - let group = match Group::from_gid(Gid::from_raw(gid)) { - Err(e) => { - return Err(Error::Nix { source: e }); - } - Ok(v) => v, - }; - - match group { - None => Err(Error::Invalid { - what: "No matched GID".to_string(), - }), - Some(v) => Ok(v), - } -} - -/// Parse a string as Username -pub fn parse_name(name_str: &String) -> Result { - if name_str.is_empty() { - return Err(Error::Invalid { - what: "Username is empty".to_string(), - }); - } - - let user = match User::from_name(name_str).context(NixSnafu) { - Err(e) => { - return Err(e); - } - Ok(v) => v, - }; - match user { - None => Err(Error::Invalid { - what: "No matched username".to_string(), - }), - Some(v) => Ok(v), - } -} - -/// check if the user id is within the system user range -pub fn uid_is_system(uid: Uid) -> bool { - const SYSTEM_UID_MAX: uid_t = 999; - uid.as_raw() <= SYSTEM_UID_MAX -} - -/// get user creds -pub fn get_user_creds(user: &String) -> Result { - if let Ok(u) = parse_uid(user) { - return Ok(u); - } - if let Ok(Some(u)) = User::from_name(user) { - return Ok(u); - } - Err(Error::Invalid { - what: "invalid user name".to_string(), - }) -} - -/// get group creds -pub fn get_group_creds(group: &String) -> Result { - if let Ok(g) = parse_gid(group) { - return Ok(g); - } - if let Ok(Some(g)) = Group::from_name(group) { - return Ok(g); - } - Err(Error::Invalid { - what: "invalid group name".to_string(), - }) -} diff --git a/libs/basic/src/virtualize.rs b/libs/basic/src/virtualize.rs deleted file mode 100644 index a3d32d76002dfc06044aec056f5fe4fa7514c553..0000000000000000000000000000000000000000 --- a/libs/basic/src/virtualize.rs +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2022 Huawei Technologies Co.,Ltd. All rights reserved. -// -// sysMaster is licensed under Mulan PSL v2. -// You can use this software according to the terms and conditions of the Mulan -// PSL v2. -// You may obtain a copy of Mulan PSL v2 at: -// http://license.coscl.org.cn/MulanPSL2 -// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -// See the Mulan PSL v2 for more details. - -//! -use nix::unistd::AccessFlags; -use std::env; - -/// Virtualization system -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub enum Virtualization { - /// not virtualization - None = 0, - /// docker virtualization - Docker, - /// lxc virtualization - Lxc, - /// podman virtualization - Podman, - /// podman virtualization - Containerd, - /// not supported virtualization - NotSupported, -} - -impl From for Virtualization { - fn from(action: String) -> Self { - match action.as_ref() { - "podman" => Virtualization::Podman, - "lxc" => Virtualization::Lxc, - "docker" => Virtualization::Docker, - "containerd" => Virtualization::Containerd, - _ => Virtualization::NotSupported, - } - } -} - -/// if running in container return true, others return false -pub fn detect_container() -> Virtualization { - if let Ok(v) = env::var("container") { - if v.is_empty() { - return Virtualization::None; - } - return Virtualization::from(v); - } - - detect_container_files() -} - -fn detect_container_files() -> Virtualization { - match nix::unistd::access("/run/.containerenv", AccessFlags::F_OK) { - Ok(_) => return Virtualization::Podman, - Err(e) => { - log::debug!("access /run/.cantainerenv error: {}", e); - } - } - - match nix::unistd::access("/.dockerenv", AccessFlags::F_OK) { - Ok(_) => return Virtualization::Docker, - Err(e) => { - log::debug!("access /.dockerenv error: {}", e); - } - } - - Virtualization::None -} diff --git a/meson.build b/meson.build index 7a3c6e16045f05f4aacfc612c2c1d3893e0a5f2a..a6d553a37ea97539ecb37e0561a50fe1b9a21c91 100644 --- a/meson.build +++ b/meson.build @@ -17,7 +17,6 @@ cc = meson.get_compiler('c') si_source_root = meson.current_source_dir() si_build_root = meson.current_build_dir() si_static_libraries = [] -abi_version_file = files('ABI_VERSION') if host_machine.cpu_family().startswith('x86') arch_subdir = 'x86' diff --git a/devops-env.sh b/scripts/devops-env.sh similarity index 62% rename from devops-env.sh rename to scripts/devops-env.sh index a5f914f802378182a57b8d5a71c2e9542d3e3551..06f89fad36a601c3a7a849e0472b6c517e5e9024 100644 --- a/devops-env.sh +++ b/scripts/devops-env.sh @@ -4,5 +4,8 @@ set -x # compat openEuler 22.03 LTS # update pkg >= kernel-5.10.0-60.99.0.123.oe2203 -# install tools +# build dependencies sudo yum install -y gcc make meson cargo xz-devel kernel kernel-devel ncurses-devel + +# rpm-build dependencies +sudo yum install -y rpm-build native-turbo-devel rust-packaging diff --git a/sysboost.service b/scripts/sysboost.service similarity index 100% rename from sysboost.service rename to scripts/sysboost.service diff --git a/sysboostd_exec_stop.sh b/scripts/sysboostd_exec_stop.sh similarity index 100% rename from sysboostd_exec_stop.sh rename to scripts/sysboostd_exec_stop.sh diff --git a/src/elf_check_elf.c b/src/elfmerge/elf_check_elf.c similarity index 100% rename from src/elf_check_elf.c rename to src/elfmerge/elf_check_elf.c diff --git a/src/elf_check_elf.h b/src/elfmerge/elf_check_elf.h similarity index 100% rename from src/elf_check_elf.h rename to src/elfmerge/elf_check_elf.h diff --git a/src/elf_ext.h b/src/elfmerge/elf_ext.h similarity index 100% rename from src/elf_ext.h rename to src/elfmerge/elf_ext.h diff --git a/src/elf_hugepage.c b/src/elfmerge/elf_hugepage.c similarity index 100% rename from src/elf_hugepage.c rename to src/elfmerge/elf_hugepage.c diff --git a/src/elf_hugepage.h b/src/elfmerge/elf_hugepage.h similarity index 100% rename from src/elf_hugepage.h rename to src/elfmerge/elf_hugepage.h diff --git a/src/elf_instruction.c b/src/elfmerge/elf_instruction.c similarity index 100% rename from src/elf_instruction.c rename to src/elfmerge/elf_instruction.c diff --git a/src/elf_instruction.h b/src/elfmerge/elf_instruction.h similarity index 100% rename from src/elf_instruction.h rename to src/elfmerge/elf_instruction.h diff --git a/src/elf_link_common.c b/src/elfmerge/elf_link_common.c similarity index 100% rename from src/elf_link_common.c rename to src/elfmerge/elf_link_common.c diff --git a/src/elf_link_common.h b/src/elfmerge/elf_link_common.h similarity index 100% rename from src/elf_link_common.h rename to src/elfmerge/elf_link_common.h diff --git a/src/elf_link_elf.c b/src/elfmerge/elf_link_elf.c similarity index 100% rename from src/elf_link_elf.c rename to src/elfmerge/elf_link_elf.c diff --git a/src/elf_link_elf.h b/src/elfmerge/elf_link_elf.h similarity index 100% rename from src/elf_link_elf.h rename to src/elfmerge/elf_link_elf.h diff --git a/src/elf_read_elf.c b/src/elfmerge/elf_read_elf.c similarity index 100% rename from src/elf_read_elf.c rename to src/elfmerge/elf_read_elf.c diff --git a/src/elf_read_elf.h b/src/elfmerge/elf_read_elf.h similarity index 100% rename from src/elf_read_elf.h rename to src/elfmerge/elf_read_elf.h diff --git a/src/elf_read_elf_xz.c b/src/elfmerge/elf_read_elf_xz.c similarity index 100% rename from src/elf_read_elf_xz.c rename to src/elfmerge/elf_read_elf_xz.c diff --git a/src/elf_relocation.c b/src/elfmerge/elf_relocation.c similarity index 100% rename from src/elf_relocation.c rename to src/elfmerge/elf_relocation.c diff --git a/src/elf_relocation.h b/src/elfmerge/elf_relocation.h similarity index 100% rename from src/elf_relocation.h rename to src/elfmerge/elf_relocation.h diff --git a/src/elf_relocation_aarch64.c b/src/elfmerge/elf_relocation_aarch64.c similarity index 100% rename from src/elf_relocation_aarch64.c rename to src/elfmerge/elf_relocation_aarch64.c diff --git a/src/elf_relocation_x86_64.c b/src/elfmerge/elf_relocation_x86_64.c similarity index 100% rename from src/elf_relocation_x86_64.c rename to src/elfmerge/elf_relocation_x86_64.c diff --git a/src/elf_write_elf.c b/src/elfmerge/elf_write_elf.c similarity index 100% rename from src/elf_write_elf.c rename to src/elfmerge/elf_write_elf.c diff --git a/src/elf_write_elf.h b/src/elfmerge/elf_write_elf.h similarity index 100% rename from src/elf_write_elf.h rename to src/elfmerge/elf_write_elf.h diff --git a/src/main.c b/src/elfmerge/main.c similarity index 100% rename from src/main.c rename to src/elfmerge/main.c diff --git a/src/elfmerge/meson.build b/src/elfmerge/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..1e0d0a973a70b4f593c770eb42d5389391ea7fc3 --- /dev/null +++ b/src/elfmerge/meson.build @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0 + +core_sources = files( + [ + 'main.c', + 'elf_link_elf.c', + 'elf_read_elf.c', + 'elf_read_elf_xz.c', + 'elf_hugepage.c', + 'elf_link_common.c', + 'elf_relocation.c', + 'elf_relocation_' + cpu_arch + '.c', + 'elf_check_elf.c', + 'elf_write_elf.c', + 'elf_instruction.c', + ] +) + +cflags += ['-fpic', '-pie'] + +executable( + 'elfmerge', core_sources, + install: true, + install_dir: '/usr/bin', + c_args: default_cflags, + link_args: default_ldflags, + dependencies: deps, + include_directories: includes +) \ No newline at end of file diff --git a/src/meson.build b/src/meson.build index 316e0e99ab34a586dd6df95ebb597494bba50d69..607f2be6c2fdd28ff6aa542c7103f5e10ad0814c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,4 +1,4 @@ -# SPDX-License-Identifier: GPL-2.0 +# SPDX-License-Identifier: MulanPSL-2.0 if arch_subdir == 'x86' cpu_arch = 'x86_64' @@ -6,11 +6,6 @@ elif arch_subdir == 'arm' cpu_arch = 'aarch64' endif -tools = [ - 'static_template', - 'libhook' -] - default_cflags = machine_args + ['-Wno-pointer-arith', '-Wno-pedantic'] default_ldflags = lk_args @@ -31,6 +26,16 @@ if cc.has_argument('-Wno-format-truncation') default_cflags += '-Wno-format-truncation' endif +tools = [ + 'static_template', + 'libhook', + 'elfmerge', +] + +default_ldflags += ['-Wl,--whole-archive', '/usr/lib64/libsi_sys.a'] +default_ldflags += ['-Wl,--whole-archive', '/usr/lib64/libsi_array.a'] +default_ldflags += ['-Wl,--whole-archive', '/usr/lib64/liblzma.a', '-Wl,--no-whole-archive'] + foreach tool:tools name = tool sources = [] @@ -41,30 +46,3 @@ foreach tool:tools subdir(name) endforeach -default_ldflags += ['-Wl,--whole-archive', '/usr/lib64/libsi_sys.a'] -default_ldflags += ['-Wl,--whole-archive', '/usr/lib64/libsi_array.a'] -default_ldflags += ['-Wl,--whole-archive', '/usr/lib64/liblzma.a', '-Wl,--no-whole-archive'] - -core_sources = files([ - 'main.c', - 'elf_link_elf.c', - 'elf_read_elf.c', - 'elf_read_elf_xz.c', - 'elf_hugepage.c', - 'elf_link_common.c', - 'elf_relocation.c', - 'elf_relocation_' + cpu_arch + '.c', - 'elf_check_elf.c', - 'elf_write_elf.c', - 'elf_instruction.c', - ]) - -cflags += ['-fpic', '-pie'] - -executable('sysboost', core_sources, - install: true, - install_dir: '/usr/bin', - c_args: default_cflags, - link_args: default_ldflags, - dependencies: deps, - include_directories: includes) \ No newline at end of file diff --git a/src/binfmt_rto/.gitignore b/src/sysboost_loader/.gitignore similarity index 100% rename from src/binfmt_rto/.gitignore rename to src/sysboost_loader/.gitignore diff --git a/src/binfmt_rto/Makefile b/src/sysboost_loader/Makefile similarity index 100% rename from src/binfmt_rto/Makefile rename to src/sysboost_loader/Makefile diff --git a/src/binfmt_rto/binfmt_rto.c b/src/sysboost_loader/binfmt_rto.c similarity index 100% rename from src/binfmt_rto/binfmt_rto.c rename to src/sysboost_loader/binfmt_rto.c diff --git a/src/binfmt_rto/binfmt_rto.h b/src/sysboost_loader/binfmt_rto.h similarity index 100% rename from src/binfmt_rto/binfmt_rto.h rename to src/sysboost_loader/binfmt_rto.h diff --git a/src/binfmt_rto/binfmt_rto_604.c b/src/sysboost_loader/binfmt_rto_604.c similarity index 99% rename from src/binfmt_rto/binfmt_rto_604.c rename to src/sysboost_loader/binfmt_rto_604.c index 03f43045aa8bf2900d900a6e7b1b7363a38cc047..1fcfb3e54152d6fa418de4f525ba6e743229efd7 100644 --- a/src/binfmt_rto/binfmt_rto_604.c +++ b/src/sysboost_loader/binfmt_rto_604.c @@ -59,7 +59,7 @@ #ifdef CONFIG_ELF_SYSBOOST #include -#include "../elf_ext.h" +#include "../elfmerge/elf_ext.h" #define AT_RSEQ_FEATURE_SIZE 27 /* rseq supported feature size */ #define AT_RSEQ_ALIGN 28 /* rseq allocation alignment */ diff --git a/src/binfmt_rto/loader_device.c b/src/sysboost_loader/loader_device.c similarity index 100% rename from src/binfmt_rto/loader_device.c rename to src/sysboost_loader/loader_device.c diff --git a/src/binfmt_rto/loader_device.h b/src/sysboost_loader/loader_device.h similarity index 100% rename from src/binfmt_rto/loader_device.h rename to src/sysboost_loader/loader_device.h diff --git a/src/binfmt_rto/main.c b/src/sysboost_loader/main.c similarity index 100% rename from src/binfmt_rto/main.c rename to src/sysboost_loader/main.c diff --git a/src/binfmt_rto/main.h b/src/sysboost_loader/main.h similarity index 100% rename from src/binfmt_rto/main.h rename to src/sysboost_loader/main.h diff --git a/src/binfmt_rto/rto_populate.c b/src/sysboost_loader/rto_populate.c similarity index 100% rename from src/binfmt_rto/rto_populate.c rename to src/sysboost_loader/rto_populate.c diff --git a/src/binfmt_rto/rto_populate_604.c b/src/sysboost_loader/rto_populate_604.c similarity index 100% rename from src/binfmt_rto/rto_populate_604.c rename to src/sysboost_loader/rto_populate_604.c diff --git a/Cargo.toml b/src/sysboostd/Cargo.toml similarity index 89% rename from Cargo.toml rename to src/sysboostd/Cargo.toml index 097c7e8076bb3bcbcb6202aeae61f69867abcc7e..9bf0131a541c78ad7b38584257e06c06f506f7de 100644 --- a/Cargo.toml +++ b/src/sysboostd/Cargo.toml @@ -8,10 +8,10 @@ default-run = "sysboostd" [[bin]] name ="sysboostd" -path = "bin/main.rs" +path = "main.rs" [target.'cfg(not(windows))'.dependencies] -basic = { path = "libs/basic" } +basic = { path = "../../libs/rustlib" } daemonize = "0.x" lazy_static = "1.4.0" procfs = "0.6.0" diff --git a/bin/aot.rs b/src/sysboostd/aot.rs similarity index 100% rename from bin/aot.rs rename to src/sysboostd/aot.rs diff --git a/bin/bolt.rs b/src/sysboostd/bolt.rs similarity index 100% rename from bin/bolt.rs rename to src/sysboostd/bolt.rs diff --git a/bin/common.rs b/src/sysboostd/common.rs similarity index 100% rename from bin/common.rs rename to src/sysboostd/common.rs diff --git a/bin/config.rs b/src/sysboostd/config.rs similarity index 100% rename from bin/config.rs rename to src/sysboostd/config.rs diff --git a/bin/coredump_monitor.rs b/src/sysboostd/coredump_monitor.rs similarity index 100% rename from bin/coredump_monitor.rs rename to src/sysboostd/coredump_monitor.rs diff --git a/bin/daemon.rs b/src/sysboostd/daemon.rs similarity index 100% rename from bin/daemon.rs rename to src/sysboostd/daemon.rs diff --git a/bin/kmod_util.rs b/src/sysboostd/kmod_util.rs similarity index 100% rename from bin/kmod_util.rs rename to src/sysboostd/kmod_util.rs diff --git a/bin/lib/fs_ext.rs b/src/sysboostd/lib/fs_ext.rs similarity index 100% rename from bin/lib/fs_ext.rs rename to src/sysboostd/lib/fs_ext.rs diff --git a/bin/lib/mod.rs b/src/sysboostd/lib/mod.rs similarity index 100% rename from bin/lib/mod.rs rename to src/sysboostd/lib/mod.rs diff --git a/bin/lib/process_ext.rs b/src/sysboostd/lib/process_ext.rs similarity index 100% rename from bin/lib/process_ext.rs rename to src/sysboostd/lib/process_ext.rs diff --git a/bin/main.rs b/src/sysboostd/main.rs similarity index 100% rename from bin/main.rs rename to src/sysboostd/main.rs