From 8a3a4d74f5907347fb0f29f12db82b3bef73e5cc Mon Sep 17 00:00:00 2001 From: yangpan Date: Mon, 8 Jan 2024 11:27:10 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E9=87=8D=E6=9E=84=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sysboostd/aot.rs | 50 +++----- src/sysboostd/bolt.rs | 19 ++- src/sysboostd/common.rs | 1 - src/sysboostd/config.rs | 135 +++++++++++++-------- src/sysboostd/coredump_monitor.rs | 84 +++++++++++--- src/sysboostd/daemon.rs | 187 +++++++----------------------- src/sysboostd/main.rs | 15 ++- 7 files changed, 235 insertions(+), 256 deletions(-) diff --git a/src/sysboostd/aot.rs b/src/sysboostd/aot.rs index b31b745..1d18ef1 100644 --- a/src/sysboostd/aot.rs +++ b/src/sysboostd/aot.rs @@ -9,7 +9,7 @@ // See the Mulan PSL v2 for more details. // Create: 2023-8-26 -use crate::common::SYSBOOST_PATH; +use crate::{common::SYSBOOST_PATH, daemon::db_add_link}; use crate::config::RtoConfig; use crate::lib::fs_ext; use crate::lib::process_ext::run_child; @@ -91,46 +91,28 @@ pub fn find_libs(conf: &RtoConfig, elf: &Elf) -> Vec { pub fn set_app_link_flag(path: &String, is_set: bool) -> i32 { let mut args: Vec = Vec::new(); + if is_set { args.push("--set".to_string()); } else { args.push("--unset".to_string()); } - - // 回滚场景, 路径是软链接要转换为真实路径 - let real_path = match fs::canonicalize(path) { - Ok(p) => p, - Err(e) => { - log::error!("get realpath failed: {}", e); - return -1; - } - }; - - args.push(format!("{}", real_path.to_string_lossy())); + args.push(path.to_string()); let ret = run_child(SYSBOOST_PATH, &args); - return ret; + ret } pub fn set_rto_link_flag(path: &String, is_set: bool) -> i32 { let mut args: Vec = Vec::new(); + if is_set { args.push("--set-rto".to_string()); } else { args.push("--unset-rto".to_string()); } - - // 回滚场景, 路径是软链接要转换为真实路径 - let real_path = match fs::canonicalize(path) { - Ok(p) => p, - Err(e) => { - log::error!("get realpath failed: {}", e); - return -1; - } - }; - - args.push(format!("{}", real_path.to_string_lossy())); + args.push(path.to_string()); let ret = run_child(SYSBOOST_PATH, &args); - return ret; + ret } // 生成rto文件 @@ -158,11 +140,9 @@ pub fn gen_app_rto(conf: &RtoConfig) -> i32 { if ret != 0 { return ret; } - let mut set: Vec = Vec::new(); - set.push("--set-rto".to_string()); - set.push(format!("{}.rto", conf.elf_path)); - ret = run_child(SYSBOOST_PATH, &set); + ret = set_rto_link_flag(&format!("{}.rto", conf.elf_path), true); if ret != 0 { + log::error!("Error: set rto link flag fail."); return ret; } let mut set_mod: Vec = Vec::new(); @@ -172,9 +152,15 @@ pub fn gen_app_rto(conf: &RtoConfig) -> i32 { if ret != 0 { return ret; } - - // 设置链接标志位 ret = set_app_link_flag(&conf.elf_path, true); - + if ret != 0 { + log::error!("Error: set app link flag fail."); + return ret; + } + ret = db_add_link(&conf); + if ret != 0 { + log::error!("Error: db add link fault."); + return ret; + } return ret; } diff --git a/src/sysboostd/bolt.rs b/src/sysboostd/bolt.rs index 784a695..d1efc3d 100644 --- a/src/sysboostd/bolt.rs +++ b/src/sysboostd/bolt.rs @@ -10,9 +10,8 @@ // Create: 2023-8-28 use crate::common::is_arch_x86_64; -use crate::config::RtoConfig; +use crate::config::{RtoConfig, INIT_CONF}; use crate::lib::process_ext::run_child; -use crate::config::get_config; use crate::aot::set_rto_link_flag; use std::fs; @@ -191,16 +190,13 @@ fn gen_app_profile(name: &str, elf_path: &String, timeout: u32) -> i32 { // profile文件与ELF文件不配套的时候, 影响BOLT优化性能 pub fn gen_profile(name: &str, timeout: u32) -> i32 { // 获得app路径 - let conf_e = get_config(name); - let conf = match conf_e { - Some(conf) => conf, - None => { - println!("get {} config fail", name); - return -1; + let conf_reader = INIT_CONF.read().unwrap(); + for conf in conf_reader.elfsections.iter() { + if conf.name == name.to_string(){ + return gen_app_profile(name, &conf.elf_path, timeout); } - }; - - return gen_app_profile(name, &conf.elf_path, timeout); + } + -1 } #[cfg(test)] @@ -213,6 +209,7 @@ mod tests { #[test] fn test_get_profile_path() { let conf = RtoConfig { + name :"mysqld".to_string(), elf_path: "/usr/bin/mysqld".to_string(), mode: "static".to_string(), libs: Vec::new(), diff --git a/src/sysboostd/common.rs b/src/sysboostd/common.rs index 59b28ec..2562113 100644 --- a/src/sysboostd/common.rs +++ b/src/sysboostd/common.rs @@ -12,7 +12,6 @@ use crate::lib::process_ext::run_child; pub const SYSBOOST_PATH: &str = "/usr/bin/sysboost"; -pub const SYSBOOST_CONFIG_PATH: &str = "/etc/sysboost.d"; // echo always > /sys/kernel/mm/transparent_hugepage/enabled pub fn set_thp() -> i32 { diff --git a/src/sysboostd/config.rs b/src/sysboostd/config.rs index f90bff6..1f0e2f7 100644 --- a/src/sysboostd/config.rs +++ b/src/sysboostd/config.rs @@ -10,16 +10,20 @@ // Create: 2023-8-28 use crate::common::SYSBOOST_PATH; -use crate::common::SYSBOOST_CONFIG_PATH; +use ini::Properties; use serde::Deserialize; -use std::fs; -use std::path::PathBuf; -use std::str::FromStr; +use ini::Ini; +use lazy_static::lazy_static; +use std::sync::RwLock; + +pub const SYSBOOST_CONFIG_PATH: &str = "/etc/sysboost.d/sysboost.ini"; +// only 10 program can use boost +const MAX_BOOST_PROGRAM: u32 = 10; -// 选型toml格式作为配置文件格式, toml格式可读性最佳 #[derive(Debug, Deserialize)] pub struct RtoConfig { + pub name: String, // 目标程序的全路径 pub elf_path: String, // 优化模式 @@ -36,55 +40,94 @@ pub struct RtoConfig { pub watch_paths: Vec, } -impl FromStr for RtoConfig { - type Err = toml::de::Error; - fn from_str(s: &str) -> Result { - toml::from_str(s) - } +pub struct GeneralSection { + pub coredump_monitor_flag: bool, } -// elf_path = "/usr/bin/bash" -// mode = "static" -// libs = "/usr/lib64/libtinfo.so.6" -fn parse_config(contents: String) -> Option { - let conf_e = contents.parse::(); - match conf_e { - Ok(ref c) => log::info!("parse config: {:?}", c), - Err(e) => { - log::error!("parse config fail: {}", e); - return None; - } - }; +// INI格式配置文件 +// [general] +// coredump_monitor_flag = false +// +// [/usr/bin/bash] +// mode = static +// libs = /usr/lib64/libtinfo.so.6, xxxx +pub struct InitConfig { + pub general: GeneralSection, // use inner value to get mutable access + pub elfsections: Vec +} - let conf = conf_e.unwrap(); - if conf.mode != "static" && conf.mode != "static-nolibc" && conf.mode != "share" && conf.mode != "bolt" { - return None; - } - if conf.elf_path == SYSBOOST_PATH { - // the tool can not renew self code - return None; +// 考虑内部可变性和线程安全 +// 可使用Mutex和RwLock +// 性能:sysboost只在全局配置文件解析写,其余都只读 +lazy_static! { + pub static ref INIT_CONF: RwLock = RwLock::new( + InitConfig { + general: GeneralSection{coredump_monitor_flag: true}, + elfsections: Vec::new() + } + ); +} + +pub fn parse_sysinit_config() { + let conf_file = Ini::load_from_file(SYSBOOST_CONFIG_PATH).unwrap(); + let mut i = 0; + for (sec, prop) in &conf_file { + if i >= MAX_BOOST_PROGRAM { + log::error!("too many boost program"); + break; + } + match sec { + Some("general") => { + parse_general(prop); + }, + Some(elf_section) => { + parse_rto_config(elf_section.to_string(), prop); + i += 1; + log::info!("parse elf section config {}", i); + }, + None => continue + } } +} - return Some(conf); +fn parse_general(prop: &Properties) { + match prop.get("coredump_monitor_flag") { + Some("false") => { + INIT_CONF.write().unwrap().general.coredump_monitor_flag = false; + }, + _ => {} + } } -pub fn read_config(path: &PathBuf) -> Option { - let ext = path.extension(); - if ext == None || ext.unwrap() != "toml" { - return None; +fn is_mode_invalid(mode: String) -> bool { + if mode != "static" && mode != "static-nolibc" && mode != "share" && mode != "bolt" { + true + } + else { + false } +} - let contents = match fs::read_to_string(path) { - Ok(c) => c, - Err(e) => { - log::error!("reading file fail {}", e); - return None; - } +fn parse_rto_config(sec: String, prop: &Properties) { + let sec_name:Vec<&str> = sec.as_str().split("/").collect(); + let mut rtoconf = RtoConfig { + name: sec_name[sec_name.len()-1].to_string(), + elf_path: sec.clone(), + mode: prop.get("mode").unwrap().to_string(), + libs: prop.get("libs").unwrap().split(",").map(|s| s.to_string()).collect(), + profile_path: prop.get("profile_path").map(|s| s.to_string()), + path: prop.get("path").map(|s| s.to_string()), + watch_paths: Vec::new(), }; - return parse_config(contents); -} -pub fn get_config(name: &str) -> Option { - let conf_path = format!("{}/{}.toml", SYSBOOST_CONFIG_PATH, name); - return read_config(&PathBuf::from(conf_path)); -} + if rtoconf.elf_path == SYSBOOST_PATH || is_mode_invalid(rtoconf.mode.clone()){ + log::error!("invalid config in {}", sec); + return; + } + // add elf file to watch list + rtoconf.watch_paths.push(rtoconf.elf_path.clone()); + for lib in rtoconf.libs.iter() { + rtoconf.watch_paths.push(lib.split_whitespace().collect()); + } + INIT_CONF.write().unwrap().elfsections.push(rtoconf); +} \ No newline at end of file diff --git a/src/sysboostd/coredump_monitor.rs b/src/sysboostd/coredump_monitor.rs index 7a16209..211583b 100644 --- a/src/sysboostd/coredump_monitor.rs +++ b/src/sysboostd/coredump_monitor.rs @@ -12,13 +12,77 @@ use std::path::Path; use log::{self}; use std::fs; +use lazy_static::lazy_static; +use std::sync::RwLock; +use std::fs::OpenOptions; +use std::io::{Write, Read}; use crate::netlink_client::{open_netlink, read_event}; use crate::aot::set_app_link_flag; use crate::daemon; +use crate::daemon::SYSBOOST_DB_PATH; -const SYSBOOST_DB_PATH: &str = "/var/lib/sysboost/"; -const SYSBOOST_TOML_PATH: &str = "/etc/sysboost.d/"; +pub const SYSBOOST_LOG_PATH: &str = "/etc/sysboost.d/log.ini"; + +lazy_static! { + pub static ref CRASH_PATH: RwLock> = RwLock::new( + Vec::new() + ); +} + +pub fn parse_crashed_log() { + let file_name = Path::new(&SYSBOOST_LOG_PATH); + let mut file = match std::fs::File::open(file_name) { + Ok(f) => {f} + Err(e) => { + log::error!("open log.ini failed {}", e); + return; + } + }; + let mut contents = String::new(); + file.read_to_string(&mut contents).unwrap(); + let mut writer = CRASH_PATH.write().unwrap(); + *writer = contents.split("\n").map(|s| s.to_string()).collect(); + +} +pub fn is_app_crashed(path: String) -> bool { + for cpath in CRASH_PATH.read().unwrap().iter() { + if cpath.to_string() == path { + log::info!("{} has crashed, ingnore", path); + return true; + } + } + false +} + +fn record_crashed_path(path: String) { + let exist = Path::new(&SYSBOOST_LOG_PATH).exists(); + if !exist { + std::fs::File::create(SYSBOOST_LOG_PATH.to_string()).expect("log.ini create failed"); + } + let file_name = Path::new(&SYSBOOST_LOG_PATH); + let mut file = match OpenOptions::new().append(true).open(file_name) { + Ok(f) => {f} + Err(e) => { + log::error!("open log.ini failed {}", e); + return; + } + }; + match file.write_all(path.as_bytes()) { + Ok(_) => {} + Err(e) => { + log::error!("write log.ini failed {}", e); + return; + } + } + match file.write_all("\n".as_bytes()) { + Ok(_) => {} + Err(e) => { + log::error!("write log.ini failed {}", e); + return; + } + } +} fn do_rollback(path: &String) -> i32 { let paths: Vec<&str> = path.split(".rto").collect(); @@ -49,20 +113,8 @@ fn do_rollback(path: &String) -> i32 { } } } - - // rename .toml - let toml_path = format!("{}{}.toml", SYSBOOST_TOML_PATH, binary_name); - let exist = Path::new(&toml_path).exists(); - if exist { - let toml = Path::new(&toml_path); - let toml_err = toml.with_extension("toml.err"); - match fs::rename(&toml, &toml_err) { - Ok(_) => {} - Err(e) => { - log::error!("Mv toml failed: {}", e); - } - } - } + // 添加路径记录,防止再次优化 + record_crashed_path(file_path.to_string()); 0 } diff --git a/src/sysboostd/daemon.rs b/src/sysboostd/daemon.rs index e95f879..302f45d 100644 --- a/src/sysboostd/daemon.rs +++ b/src/sysboostd/daemon.rs @@ -9,13 +9,13 @@ // See the Mulan PSL v2 for more details. // Create: 2023-4-20 -use crate::aot::find_libs; use crate::aot::gen_app_rto; -use crate::aot::parse_elf_file; use crate::aot::set_app_link_flag; use crate::bolt::bolt_optimize; -use crate::config::read_config; +use crate::config::SYSBOOST_CONFIG_PATH; +use crate::config::INIT_CONF; use crate::config::RtoConfig; +use crate::coredump_monitor::is_app_crashed; use crate::kmod_util::insmod_sysboost_ko; use crate::kmod_util::set_hpage_rto_flag; use crate::kmod_util::set_ko_rto_flag; @@ -26,166 +26,65 @@ use inotify::{EventMask, Inotify, WatchMask}; use log::{self}; use std::fs; use std::os::unix::fs as UnixFs; -use std::path::{Path, PathBuf}; +use std::path::{Path}; use std::thread; use std::time::Duration; -const SYSBOOST_DB_PATH: &str = "/var/lib/sysboost/"; +pub const SYSBOOST_DB_PATH: &str = "/var/lib/sysboost/"; //const LDSO: &str = "ld-"; //const LIBCSO: &str = "libc.so"; // sleep some time wait for next event const MIN_SLEEP_TIME: u64 = 10000; -// only 10 program can use boost -const MAX_BOOST_PROGRAM: u32 = 10; - -fn db_add_link(conf: &RtoConfig) -> i32 { +pub fn db_add_link(conf: &RtoConfig) -> i32 { // symlink app.link to app, different modes correspond to different directories let file_name = Path::new(&conf.elf_path).file_name().unwrap().to_str().unwrap(); let link_path = format!("{}{}.link", SYSBOOST_DB_PATH, file_name); let ret_e = UnixFs::symlink(&conf.elf_path, &link_path); match ret_e { - Ok(_) => {} + Ok(_) => log::info!("symlink sucess {}", link_path), Err(_) => { log::error!("symlink fail {}", link_path); return -1; } }; - - return 0; + 0 } pub fn db_remove_link(path: &String) { let ret = fs::remove_file(&path); match ret { - Ok(_) => return, - Err(e) => { - log::error!("remove link fail: {}", e); - } + Ok(_) => log::info!("remove link {} success", path), + Err(e) => log::error!("remove link fail: {}", e), }; } // TODO: use bolt to optimize dynamic library and then merge them fn sysboost_core_process(conf: &RtoConfig) -> i32 { + let mut ret= 0; match conf.mode.as_str() { "bolt" => { - let ret = bolt_optimize(&conf); + ret = bolt_optimize(&conf); if ret != 0 { log::error!("Error: bolt mode start fault."); return ret; } } "static" | "static-nolibc" | "share" => { - let ret = gen_app_rto(&conf); + ret = gen_app_rto(&conf); if ret != 0 { log::error!("Error: generate rto start fault."); return ret; } + log::info!("generate {} rto success.",&conf.name); } _ => { log::info!("Warning: read elf file fault, please check config."); // handle other cases } } - - let ret = db_add_link(&conf); - if ret != 0 { - log::error!("Error: db add link fault."); - return ret; - } - - let ret = set_app_link_flag(&conf.elf_path, true); - if ret != 0 { - log::error!("Error: set app link flag fail."); - return ret; - } - return ret; -} - -fn process_config(path: PathBuf) -> Option { - let conf_e = read_config(&path); - let mut conf = match conf_e { - Some(conf) => conf, - None => return None, - }; - - // let elf = match parse_elf_file(&conf.elf_path) { - // Some(elf) => elf, - // None => return None, - // }; - - // auto get lib path - // In static-nolibc mode, ld and libc need to be deleted after detection. - // In share mode, no detection is performed based on libs. - if conf.mode == "static" { - // let libs = find_libs(&conf, &elf); - // conf.libs = libs; - } else if conf.mode == "static-nolibc" { - //let mut libs = find_libs(&conf, &elf); - //libs.retain(|s| !s.contains(LDSO)); - //libs.retain(|s| !s.contains(LIBCSO)); - //conf.libs = libs; - } - - // add elf file to watch list - conf.watch_paths.push(conf.elf_path.clone()); - for lib in conf.libs.iter() { - conf.watch_paths.push(lib.split_whitespace().collect()); - } - - // add config file to watch list - let path_str = path.clone().into_os_string().into_string().unwrap(); - conf.watch_paths.push(path_str); - - let ret = sysboost_core_process(&conf); - if ret != 0 { - log::error!("Error: db add link fault."); - return None; - } - - return Some(conf); -} - -fn refresh_all_config(rto_configs: &mut Vec) { - // read configs /etc/sysboost.d, like bash.toml - let dir_e = fs::read_dir(&Path::new("/etc/sysboost.d")); - let dir = match dir_e { - Ok(dir) => dir, - Err(e) => { - log::error!("{}", e); - return; - } - }; - - let mut i = 0; - for entry in dir { - let entry = entry.ok().unwrap(); - let path = entry.path(); - if path.is_dir() { - continue; - } - if path.file_name() == None { - continue; - } - - if i == MAX_BOOST_PROGRAM { - log::error!("too many boost program"); - break; - } - let ret = process_config(path); - match ret { - Some(conf) => rto_configs.push(conf), - None => {} - } - log::info!("refresh all config {}", i); - i += 1; - } - - if rto_configs.len() > 0 { - set_ko_rto_flag(true); - set_hpage_rto_flag(true); - } + ret } fn clean_last_rto() { @@ -213,16 +112,21 @@ fn clean_last_rto() { } let file_name = path.file_name().unwrap(); let p = format!("{}{}", SYSBOOST_DB_PATH, file_name.to_string_lossy()); - set_app_link_flag(&p, false); + // 回滚场景, 路径是软链接要转换为真实路径 + let real_path = match fs::canonicalize(&p) { + Ok(p) => p, + Err(e) => { + log::error!("get realpath failed: {}", e); + continue; + } + }; + set_app_link_flag(&format!("{}",real_path.to_string_lossy()), false); db_remove_link(&p); - } - let ret = fs::remove_file("/usr/bin/bash.rto"); - match ret { - Ok(_) => return, - Err(e) => { - log::info!("remove bash.rto failed: {}", e); + match fs::remove_file(format!("{}.rto", real_path.to_string_lossy())) { + Ok(_) => log::info!("remove {} success", format!("{}.rto", real_path.to_string_lossy())), + Err(e) => log::info!("remove {} failed: {}", format!("{}.rto", real_path.to_string_lossy()), e), } - }; + } } fn watch_old_files_perapp(conf: &RtoConfig, inotify: &mut Inotify) { @@ -267,40 +171,33 @@ fn check_files_modify(inotify: &mut Inotify) -> bool { } fn start_service() { + let conf_reader = INIT_CONF.read().unwrap(); + set_ko_rto_flag(true); set_hpage_rto_flag(true); clean_last_rto(); - let mut rto_configs: Vec = Vec::new(); - refresh_all_config(&mut rto_configs); - let mut inotify = Inotify::init().unwrap(); - let mut try_again = true; - // TODO: 为什么写死路径? 这些代码都要重写; - match inotify.add_watch("/etc/sysboost.d/bash.toml", WatchMask::MODIFY) { - Ok(_) => { - try_again = false; + for conf in conf_reader.elfsections.iter() { + log::info!("parse config: {:?}", conf); + if is_app_crashed(conf.elf_path.clone()) { + continue; } + sysboost_core_process(conf); + } + log::info!("parse all config"); + let mut inotify = Inotify::init().unwrap(); + match inotify.add_watch(SYSBOOST_CONFIG_PATH, WatchMask::MODIFY) { Err(e) => { - log::info!("init watch bash.toml failed {}", e); + log::info!("watch init file failed {}", e); } + _ => {} }; let mut buffer = [0; 1024]; - - let mut file_inotify = watch_old_files(&rto_configs); + let mut file_inotify = watch_old_files(&conf_reader.elfsections); loop { // wait some time thread::sleep(Duration::from_secs(MIN_SLEEP_TIME)); - if try_again { - match inotify.add_watch("/etc/sysboost.d/bash.toml", WatchMask::MODIFY) { - Ok(_) => { - return; - } - Err(e) => { - log::info!("init watch bash.toml failed {}", e); - } - }; - } // do not support config dynamic modify, need restart service let events = inotify.read_events(&mut buffer).unwrap(); for event in events { diff --git a/src/sysboostd/main.rs b/src/sysboostd/main.rs index 69e72a4..c6a77cc 100644 --- a/src/sysboostd/main.rs +++ b/src/sysboostd/main.rs @@ -19,10 +19,13 @@ mod kmod_util; mod lib; mod netlink_client; +use crate::config::parse_sysinit_config; use crate::coredump_monitor::coredump_monitor_loop; +use crate::coredump_monitor::parse_crashed_log; use crate::daemon::daemon_loop; use crate::kmod_util::test_kmod; use crate::bolt::gen_profile; +use crate::config::INIT_CONF; use basic::logger::{self}; use daemonize::Daemonize; @@ -80,7 +83,9 @@ fn main() { } } } - + // 配置文件解析 + parse_sysinit_config(); + parse_crashed_log(); if is_gen_porfile { logger::init_log_to_console(APP_NAME, log::LevelFilter::Debug); std::process::exit(gen_profile(name, timeout)); @@ -105,12 +110,12 @@ fn main() { } // start up coredump monitor - let _coredump_monitor_handle = thread::spawn(||{ + if INIT_CONF.read().unwrap().general.coredump_monitor_flag { + let _coredump_monitor_handle = thread::spawn(||{ coredump_monitor_loop(); - }); + }); + } // daemon service gen rto ELF with config daemon_loop(); - - _coredump_monitor_handle.join().unwrap() } -- Gitee From 2dedf056b3907f032471414bdd23933861db7a60 Mon Sep 17 00:00:00 2001 From: yangpan Date: Wed, 10 Jan 2024 15:06:36 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=9D=83=E9=99=90=E6=A3=80=E6=9F=A5=E4=BB=A5=E5=8F=8A=E7=BB=86?= =?UTF-8?q?=E8=8A=82=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sysboostd/common.rs | 2 +- src/sysboostd/coredump_monitor.rs | 54 ++++++++++++++++++++----------- src/sysboostd/daemon.rs | 1 + src/sysboostd/lib/process_ext.rs | 2 +- src/sysboostd/main.rs | 12 ++++--- 5 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/sysboostd/common.rs b/src/sysboostd/common.rs index 2562113..32cc164 100644 --- a/src/sysboostd/common.rs +++ b/src/sysboostd/common.rs @@ -11,7 +11,7 @@ use crate::lib::process_ext::run_child; -pub const SYSBOOST_PATH: &str = "/usr/bin/sysboost"; +pub const SYSBOOST_PATH: &str = "/usr/bin/elfmerge"; // echo always > /sys/kernel/mm/transparent_hugepage/enabled pub fn set_thp() -> i32 { diff --git a/src/sysboostd/coredump_monitor.rs b/src/sysboostd/coredump_monitor.rs index 211583b..c96bda7 100644 --- a/src/sysboostd/coredump_monitor.rs +++ b/src/sysboostd/coredump_monitor.rs @@ -14,15 +14,21 @@ use log::{self}; use std::fs; use lazy_static::lazy_static; use std::sync::RwLock; -use std::fs::OpenOptions; use std::io::{Write, Read}; +use std::fs::OpenOptions; +use std::os::linux::fs::MetadataExt; +use crate::lib::process_ext::run_child; use crate::netlink_client::{open_netlink, read_event}; use crate::aot::set_app_link_flag; use crate::daemon; use crate::daemon::SYSBOOST_DB_PATH; -pub const SYSBOOST_LOG_PATH: &str = "/etc/sysboost.d/log.ini"; + +const SYSBOOST_LOG_NAME: &str = ".sysboost.err"; +pub const SYSBOOST_LOG_PATH: &str = "/etc/sysboost.d/.sysboost.err"; +const LOG_FILE_ST_MODE: u32 = 0o100644; + lazy_static! { pub static ref CRASH_PATH: RwLock> = RwLock::new( @@ -30,15 +36,33 @@ lazy_static! { ); } +// 设置SYSBOOST_LOG_PATH的权限仅root可写 +fn set_mode() { + let mut set_mod: Vec = Vec::new(); + set_mod.push("644".to_string()); + set_mod.push(SYSBOOST_LOG_PATH.to_string()); + let _ = run_child("/usr/bin/chmod", &set_mod); +} + +// 确保SYSBOOST_LOG_PATH的权限仅root可写 +fn check_mode() -> bool { + let meta = fs::metadata(SYSBOOST_LOG_PATH.to_string()).unwrap(); + if meta.st_mode() != LOG_FILE_ST_MODE { + return false; + } + true +} + pub fn parse_crashed_log() { let file_name = Path::new(&SYSBOOST_LOG_PATH); let mut file = match std::fs::File::open(file_name) { Ok(f) => {f} - Err(e) => { - log::error!("open log.ini failed {}", e); - return; - } + Err(_) => return }; + if !check_mode() { + log::warn!("file {} may has changed!", SYSBOOST_LOG_NAME); + return; + } let mut contents = String::new(); file.read_to_string(&mut contents).unwrap(); let mut writer = CRASH_PATH.write().unwrap(); @@ -48,7 +72,6 @@ pub fn parse_crashed_log() { pub fn is_app_crashed(path: String) -> bool { for cpath in CRASH_PATH.read().unwrap().iter() { if cpath.to_string() == path { - log::info!("{} has crashed, ingnore", path); return true; } } @@ -58,30 +81,25 @@ pub fn is_app_crashed(path: String) -> bool { fn record_crashed_path(path: String) { let exist = Path::new(&SYSBOOST_LOG_PATH).exists(); if !exist { - std::fs::File::create(SYSBOOST_LOG_PATH.to_string()).expect("log.ini create failed"); + let _ = std::fs::File::create(SYSBOOST_LOG_PATH.to_string()); + set_mode(); } let file_name = Path::new(&SYSBOOST_LOG_PATH); let mut file = match OpenOptions::new().append(true).open(file_name) { Ok(f) => {f} Err(e) => { - log::error!("open log.ini failed {}", e); + log::error!("open {} failed: {}", SYSBOOST_LOG_NAME, e); return; } }; - match file.write_all(path.as_bytes()) { + let content = format!("{}\n", path); + match file.write_all(content.as_bytes()) { Ok(_) => {} Err(e) => { - log::error!("write log.ini failed {}", e); + log::error!("write {} failed: {}", SYSBOOST_LOG_NAME, e); return; } } - match file.write_all("\n".as_bytes()) { - Ok(_) => {} - Err(e) => { - log::error!("write log.ini failed {}", e); - return; - } - } } fn do_rollback(path: &String) -> i32 { diff --git a/src/sysboostd/daemon.rs b/src/sysboostd/daemon.rs index 302f45d..06a138b 100644 --- a/src/sysboostd/daemon.rs +++ b/src/sysboostd/daemon.rs @@ -180,6 +180,7 @@ fn start_service() { for conf in conf_reader.elfsections.iter() { log::info!("parse config: {:?}", conf); if is_app_crashed(conf.elf_path.clone()) { + log::info!("{} has crashed, ingnore", &conf.elf_path); continue; } sysboost_core_process(conf); diff --git a/src/sysboostd/lib/process_ext.rs b/src/sysboostd/lib/process_ext.rs index 315ce05..0e518ce 100644 --- a/src/sysboostd/lib/process_ext.rs +++ b/src/sysboostd/lib/process_ext.rs @@ -52,7 +52,7 @@ pub fn run_child(cmd: &str, args: &Vec) -> i32 { }; if exit_code != 0 { - log::error!("Command exited with code: {}", exit_code); + log::warn!("Command exited with code: {}", exit_code); } exit_code diff --git a/src/sysboostd/main.rs b/src/sysboostd/main.rs index c6a77cc..91fbdb8 100644 --- a/src/sysboostd/main.rs +++ b/src/sysboostd/main.rs @@ -83,6 +83,13 @@ fn main() { } } } + + if is_debug { + logger::init_log_to_console(APP_NAME, log::LevelFilter::Debug); + } else { + logger::init_log(APP_NAME, log::LevelFilter::Info, "syslog", None); + } + // 配置文件解析 parse_sysinit_config(); parse_crashed_log(); @@ -91,11 +98,6 @@ fn main() { std::process::exit(gen_profile(name, timeout)); } - if is_debug { - logger::init_log_to_console(APP_NAME, log::LevelFilter::Debug); - } else { - logger::init_log(APP_NAME, log::LevelFilter::Info, "syslog", None); - } log::info!("{} running", APP_NAME); if is_daemon { -- Gitee From 0931fc5183fa7812cff1dd85efb3801db708343e Mon Sep 17 00:00:00 2001 From: yangpan Date: Wed, 10 Jan 2024 17:08:23 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E4=B9=B1=E7=A0=81=E5=92=8Csysboost=5Floader=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libs/rustlib/src/logger.rs | 2 +- src/sysboost_loader/loader_device.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/rustlib/src/logger.rs b/libs/rustlib/src/logger.rs index 2f24d25..86118d6 100644 --- a/libs/rustlib/src/logger.rs +++ b/libs/rustlib/src/logger.rs @@ -61,7 +61,7 @@ impl log::Log for SysLogger { } fn log(&self, record: &log::Record) { - let msg = record.args().to_string(); + let msg = record.args().to_string() + "\0"; let level = match record.level() { log::Level::Error => libc::LOG_ERR, log::Level::Warn => libc::LOG_WARNING, diff --git a/src/sysboost_loader/loader_device.c b/src/sysboost_loader/loader_device.c index eb43270..ee389d0 100644 --- a/src/sysboost_loader/loader_device.c +++ b/src/sysboost_loader/loader_device.c @@ -179,7 +179,7 @@ static int preload_rto(struct file *file) return -ENOENT; } if (debug) - pr_info("loading file %s\n", FILE_TO_NAME(rto_file)) + pr_info("loading file %s\n", FILE_TO_NAME(rto_file)); loaded_rto = loaded_rto_alloc(inode); if (!loaded_rto) { -- Gitee From 5f12f4f95818ddcaa42728d3b97398b2b8a013c5 Mon Sep 17 00:00:00 2001 From: yangpan Date: Thu, 11 Jan 2024 14:33:45 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E9=9C=80=E8=A6=81?= =?UTF-8?q?=E7=9A=84Cargo.lock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- vendor/rust-ini/Cargo.lock | 130 ++++++++++++++++++++++++++++++++++ vendor/tiny-keccak/Cargo.lock | 16 +++++ 3 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 vendor/rust-ini/Cargo.lock create mode 100644 vendor/tiny-keccak/Cargo.lock diff --git a/.gitignore b/.gitignore index ce20f3e..0aceca4 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ target *.pyc ~* .idea/ -Cargo.lock +src/sysboostd/Cargo.lock *.rto # readelf/objdump diff --git a/vendor/rust-ini/Cargo.lock b/vendor/rust-ini/Cargo.lock new file mode 100644 index 0000000..2ebd715 --- /dev/null +++ b/vendor/rust-ini/Cargo.lock @@ -0,0 +1,130 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-random" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368a7a772ead6ce7e1de82bfb04c485f3db8ec744f72925af5735e29a22cc18e" +dependencies = [ + "const-random-macro", + "proc-macro-hack", +] + +[[package]] +name = "const-random-macro" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d7d6ab3c3a2282db210df5f02c4dab6e0a7057af0fb7ebd4070f30fe05c0ddb" +dependencies = [ + "getrandom", + "once_cell", + "proc-macro-hack", + "tiny-keccak", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "dlv-list" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d529fd73d344663edfd598ccb3f344e46034db51ebd103518eae34338248ad73" +dependencies = [ + "const-random", +] + +[[package]] +name = "getrandom" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hashbrown" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" + +[[package]] +name = "libc" +version = "0.2.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "ordered-multimap" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4d6a8c22fc714f0c2373e6091bf6f5e9b37b1bc0b1184874b7e0a4e303d318f" +dependencies = [ + "dlv-list", + "hashbrown", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "rust-ini" +version = "0.20.0" +dependencies = [ + "cfg-if", + "ordered-multimap", + "unicase", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/vendor/tiny-keccak/Cargo.lock b/vendor/tiny-keccak/Cargo.lock new file mode 100644 index 0000000..05cff9f --- /dev/null +++ b/vendor/tiny-keccak/Cargo.lock @@ -0,0 +1,16 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +dependencies = [ + "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[metadata] +"checksum crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" -- Gitee From 64a066935f59de6001f50c9b3ee6a5a8e075379e Mon Sep 17 00:00:00 2001 From: yangpan Date: Thu, 11 Jan 2024 15:23:07 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sysboostd/config.rs | 8 +++++++- src/sysboostd/lib/process_ext.rs | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/sysboostd/config.rs b/src/sysboostd/config.rs index 1f0e2f7..17b1af3 100644 --- a/src/sysboostd/config.rs +++ b/src/sysboostd/config.rs @@ -69,7 +69,13 @@ lazy_static! { } pub fn parse_sysinit_config() { - let conf_file = Ini::load_from_file(SYSBOOST_CONFIG_PATH).unwrap(); + let conf_file = match Ini::load_from_file(SYSBOOST_CONFIG_PATH){ + Ok(c) => {c} + Err(e) => { + log::info!("load file {} error: {}",SYSBOOST_CONFIG_PATH, e); + return; + } + }; let mut i = 0; for (sec, prop) in &conf_file { if i >= MAX_BOOST_PROGRAM { diff --git a/src/sysboostd/lib/process_ext.rs b/src/sysboostd/lib/process_ext.rs index 0e518ce..830b348 100644 --- a/src/sysboostd/lib/process_ext.rs +++ b/src/sysboostd/lib/process_ext.rs @@ -52,7 +52,7 @@ pub fn run_child(cmd: &str, args: &Vec) -> i32 { }; if exit_code != 0 { - log::warn!("Command exited with code: {}", exit_code); + log::debug!("Command exited with code: {}", exit_code); } exit_code -- Gitee From d1d7f95a4d1c9488d0a9abebce7d8236dd5edb4f Mon Sep 17 00:00:00 2001 From: yangpan Date: Thu, 11 Jan 2024 16:52:24 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E4=BC=98=E5=8C=96libs=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E6=88=96=E8=80=85=E4=B8=BA=E7=A9=BA=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sysboostd/config.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/sysboostd/config.rs b/src/sysboostd/config.rs index 17b1af3..e2869c9 100644 --- a/src/sysboostd/config.rs +++ b/src/sysboostd/config.rs @@ -120,7 +120,18 @@ fn parse_rto_config(sec: String, prop: &Properties) { name: sec_name[sec_name.len()-1].to_string(), elf_path: sec.clone(), mode: prop.get("mode").unwrap().to_string(), - libs: prop.get("libs").unwrap().split(",").map(|s| s.to_string()).collect(), + // 需要处理配置文件中libs = ;和没有libs属性的情况 + libs: match prop.get("libs") { + Some(p) => { + if p.trim().is_empty() { + Vec::new() + } + else { + p.split(",").map(|s| s.to_string()).collect() + } + } + None => {Vec::new()} + }, profile_path: prop.get("profile_path").map(|s| s.to_string()), path: prop.get("path").map(|s| s.to_string()), watch_paths: Vec::new(), -- Gitee