From 2e81d774d7a4ff0fbf373a747b1ba288f6d9655c Mon Sep 17 00:00:00 2001 From: yangpan Date: Thu, 11 Jul 2024 16:44:45 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=8Ewaas=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E5=AF=B9=E6=8E=A5=E7=9A=84=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sysboostd/coredump_monitor.rs | 11 +-- src/sysboostd/daemon.rs | 2 +- src/sysboostd/interface.rs | 147 ++++++++++++++++++++++++++++++ src/sysboostd/main.rs | 65 ++++++++++++- 4 files changed, 216 insertions(+), 9 deletions(-) create mode 100644 src/sysboostd/interface.rs diff --git a/src/sysboostd/coredump_monitor.rs b/src/sysboostd/coredump_monitor.rs index c96bda7..011a3f3 100644 --- a/src/sysboostd/coredump_monitor.rs +++ b/src/sysboostd/coredump_monitor.rs @@ -37,10 +37,10 @@ lazy_static! { } // 设置SYSBOOST_LOG_PATH的权限仅root可写 -fn set_mode() { +pub fn set_mode(path: &str) { let mut set_mod: Vec = Vec::new(); set_mod.push("644".to_string()); - set_mod.push(SYSBOOST_LOG_PATH.to_string()); + set_mod.push(path.to_string()); let _ = run_child("/usr/bin/chmod", &set_mod); } @@ -82,7 +82,7 @@ fn record_crashed_path(path: String) { let exist = Path::new(&SYSBOOST_LOG_PATH).exists(); if !exist { let _ = std::fs::File::create(SYSBOOST_LOG_PATH.to_string()); - set_mode(); + set_mode(SYSBOOST_LOG_PATH); } let file_name = Path::new(&SYSBOOST_LOG_PATH); let mut file = match OpenOptions::new().append(true).open(file_name) { @@ -116,10 +116,7 @@ fn do_rollback(path: &String) -> i32 { } // remove link let link_path = format!("{}{}.link", SYSBOOST_DB_PATH, binary_name); - let exist = Path::new(&link_path).exists(); - if exist { - daemon::db_remove_link(&link_path); - } + daemon::db_remove_link(&link_path); // remove bash.rto let exist = Path::new(&rto_path).exists(); diff --git a/src/sysboostd/daemon.rs b/src/sysboostd/daemon.rs index 06a138b..966431b 100644 --- a/src/sysboostd/daemon.rs +++ b/src/sysboostd/daemon.rs @@ -26,7 +26,7 @@ use inotify::{EventMask, Inotify, WatchMask}; use log::{self}; use std::fs; use std::os::unix::fs as UnixFs; -use std::path::{Path}; +use std::path::Path; use std::thread; use std::time::Duration; diff --git a/src/sysboostd/interface.rs b/src/sysboostd/interface.rs new file mode 100644 index 0000000..f554cc2 --- /dev/null +++ b/src/sysboostd/interface.rs @@ -0,0 +1,147 @@ +use std::fs; +use std::path::Path; +use std::os::unix::fs as UnixFs; +use std::fs::OpenOptions; +use std::io::{Write, Read}; +use std::io::BufRead; + +use crate::aot::{set_rto_link_flag, set_app_link_flag}; +use crate::coredump_monitor::set_mode; +use crate::lib::process_ext::run_child; +use crate::daemon::{SYSBOOST_DB_PATH, self}; + +pub const OPTIMIZED_ELF_LOG: &str = "/etc/sysboost.d/.optimized.log"; + +pub fn write_back_config(name: &str) -> i32 { + let exist = Path::new(&OPTIMIZED_ELF_LOG).exists(); + if !exist { + let _ = std::fs::File::create(OPTIMIZED_ELF_LOG.to_string()); + set_mode(OPTIMIZED_ELF_LOG); + } + let file_name = Path::new(&OPTIMIZED_ELF_LOG); + let mut file = match OpenOptions::new().append(true).open(file_name) { + Ok(f) => {f} + Err(e) => { + log::error!("open {} failed: {}", OPTIMIZED_ELF_LOG, e); + return -1; + } + }; + let content = format!("{}\n", name); + match file.write_all(content.as_bytes()) { + Ok(_) => {return 0;} + Err(e) => { + log::error!("write {} failed: {}", OPTIMIZED_ELF_LOG, e); + return -1; + } + } +} +pub fn delete_one_record(name: &str) -> i32 { + let exist = Path::new(&OPTIMIZED_ELF_LOG).exists(); + if !exist { + return -1; + } + let file_name = Path::new(&OPTIMIZED_ELF_LOG); + let rfile = match OpenOptions::new().read(true).open(file_name) { + Ok(f) => {f} + Err(e) => { + log::error!("open {} failed: {}", OPTIMIZED_ELF_LOG, e); + return -1; + } + }; + let mut buf = String::new(); + let reader = std::io::BufReader::new(&rfile); + for line in reader.lines() { + if line.as_ref().unwrap().contains(name){ + continue; + } + buf.push_str(line.as_ref().unwrap()); + buf.push_str("\n") + } + let mut wfile = match OpenOptions::new().truncate(true).write(true).open(file_name) { + Ok(f) => {f} + Err(e) => { + log::error!("open {} failed: {}", OPTIMIZED_ELF_LOG, e); + return -1; + } + }; + match wfile.write_all(buf.as_bytes()) { + Ok(_) => {return 0;} + Err(e) => { + log::error!("write {} failed: {}", OPTIMIZED_ELF_LOG, e); + return -1; + } + } + +} +pub fn bolt_add_link(file_name: &str) -> i32 { + // symlink app.link to app, different modes correspond to different directories + let names: Vec<&str> = file_name.split("/").collect(); + let binary_name = names[names.len() - 1]; + let link_path = format!("{}{}.link", SYSBOOST_DB_PATH, binary_name); + let ret_e = UnixFs::symlink(&binary_name, &link_path); + match ret_e { + Ok(_) => log::info!("symlink sucess {}", link_path), + Err(_) => { + log::error!("symlink fail {}", link_path); + return -1; + } + }; + 0 +} + +pub fn gen_bolt_optimize_bin(name: &str, bolt_option: &str, profile_path: &str) -> i32 { + let mut args: Vec = Vec::new(); + args.push(bolt_option.to_string()); + let elf_path = Path::new(name); + let elf_path = match fs::canonicalize(elf_path) { + Ok(p) => p, + Err(e) => { + log::error!("bolt_optimize_bin: get realpath failed: {}", e); + return -1; + } + }; + let rto_path = elf_path.with_extension("rto"); + args.push(name.to_string()); + args.push("-o".to_string()); + args.push(rto_path.to_str().unwrap().to_string()); + let mut ret = run_child("/usr/bin/llvm-bolt", &args); + println!("yp test {}", ret); + if ret != 0 { + return ret; + } + ret = set_rto_link_flag(&rto_path.to_str().unwrap().to_string(), true); + println!("yp test {}", ret); + ret = set_app_link_flag(&name.to_string(), true); + println!("yp test {}", ret); + ret = bolt_add_link(name); + println!("yp test {}", ret); + return ret; + +} + +pub fn stop_one_elf(path: &str) -> i32 { + let names: Vec<&str> = path.split("/").collect(); + let binary_name = names[names.len() - 1]; + let rto_path = format!("{}.rto", path); + // unset flag + let ret = set_app_link_flag(&path.to_string(), false); + if ret != 0 { + log::error!("Failed to unset link flag for {}", path); + return ret; + } + // remove link + let link_path = format!("{}{}.link", SYSBOOST_DB_PATH, binary_name); + daemon::db_remove_link(&link_path); + + // remove xx.rto + let exist = Path::new(&rto_path).exists(); + if exist { + match fs::remove_file(&rto_path) { + Ok(_) => {} + Err(e) => { + log::error!("remove file failed: {}", e); + } + } + } + 0 +} \ No newline at end of file diff --git a/src/sysboostd/main.rs b/src/sysboostd/main.rs index 91fbdb8..5813a96 100644 --- a/src/sysboostd/main.rs +++ b/src/sysboostd/main.rs @@ -18,11 +18,16 @@ mod daemon; mod kmod_util; mod lib; mod netlink_client; +mod interface; 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::interface::delete_one_record; +use crate::interface::gen_bolt_optimize_bin; +use crate::interface::stop_one_elf; +use crate::interface::write_back_config; use crate::kmod_util::test_kmod; use crate::bolt::gen_profile; use crate::config::INIT_CONF; @@ -49,6 +54,13 @@ fn main() { let mut timeout = DEFAULT_TIMEOUT; let mut name = ""; + let mut is_bolt = false; + let mut bolt_option = ""; + let mut profile_path = ""; + let mut bolt_elf_name = ""; + + let mut is_stop = false; + let mut stop_elf_name = ""; // arg0 is program name, parameter is from arg1 for i in 1..args.len() { if args[i].contains("--gen-profile=") { @@ -67,7 +79,40 @@ fn main() { } continue; } - + if args[i].contains("--gen-bolt=") { + if let Some(index) = args[i].find('=') { + is_bolt = true; + bolt_elf_name = &args[i][index + 1..]; + } else { + parameter_wrong_exit(); + } + continue; + } + if args[i].contains("--bolt-option=") { + if let Some(index) = args[i].find('=') { + bolt_option = &args[i][index + 1..]; + } else { + parameter_wrong_exit(); + } + continue; + } + if args[i].contains("--profile-path=") { + if let Some(index) = args[i].find('=') { + profile_path = &args[i][index + 1..]; + } else { + parameter_wrong_exit(); + } + continue; + } + if args[i].contains("--stop=") { + if let Some(index) = args[i].find('=') { + is_stop = true; + stop_elf_name = &args[i][index + 1..]; + } else { + parameter_wrong_exit(); + } + continue; + } match args[i].as_str() { "--debug" => { is_debug = true; @@ -93,6 +138,24 @@ fn main() { // 配置文件解析 parse_sysinit_config(); parse_crashed_log(); + //sysboostd --gen-bolt="/path/to/mysqld" --bolt-option="xxx" --profile-path="/path/to/mysqld.profile" + if is_bolt { + logger::init_log_to_console(APP_NAME, log::LevelFilter::Debug); + let ret = gen_bolt_optimize_bin(bolt_elf_name, bolt_option, profile_path); + if ret < 0 { + std::process::exit(-1); + } + std::process::exit(write_back_config(bolt_elf_name)); + } + //sysboostd --stop=/path/to/mysqld + if is_stop { + logger::init_log_to_console(APP_NAME, log::LevelFilter::Debug); + let ret = stop_one_elf(stop_elf_name); + if ret < 0 { + std::process::exit(-1); + } + std::process::exit(delete_one_record(stop_elf_name)); + } if is_gen_porfile { logger::init_log_to_console(APP_NAME, log::LevelFilter::Debug); std::process::exit(gen_profile(name, timeout)); -- Gitee From 9a02d0fb63bf7c97937e6e8174951d4c05c636cd Mon Sep 17 00:00:00 2001 From: yangpan Date: Tue, 16 Jul 2024 10:48:07 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BC=98=E5=8C=96waas=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sysboostd/interface.rs | 19 ++++++++++++++----- src/sysboostd/main.rs | 14 ++++++-------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/sysboostd/interface.rs b/src/sysboostd/interface.rs index f554cc2..23392ca 100644 --- a/src/sysboostd/interface.rs +++ b/src/sysboostd/interface.rs @@ -91,7 +91,19 @@ pub fn bolt_add_link(file_name: &str) -> i32 { pub fn gen_bolt_optimize_bin(name: &str, bolt_option: &str, profile_path: &str) -> i32 { let mut args: Vec = Vec::new(); - args.push(bolt_option.to_string()); + if bolt_option.is_empty() { + args.push("-reorder-blocks=ext-tsp".to_string()); + args.push("-reorder-functions=hfsort".to_string()); + args.push("-split-functions".to_string()); + args.push("-split-all-cold".to_string()); + args.push("-split-eh".to_string()); + args.push("-dyno-stats".to_string()); + } else { + let options: Vec<&str> = bolt_option.split(" ").collect(); + for option in options{ + args.push(option.to_string()); + } + } let elf_path = Path::new(name); let elf_path = match fs::canonicalize(elf_path) { Ok(p) => p, @@ -104,17 +116,14 @@ pub fn gen_bolt_optimize_bin(name: &str, bolt_option: &str, profile_path: &str) args.push(name.to_string()); args.push("-o".to_string()); args.push(rto_path.to_str().unwrap().to_string()); + args.push(format!("-data={}", profile_path)); let mut ret = run_child("/usr/bin/llvm-bolt", &args); - println!("yp test {}", ret); if ret != 0 { return ret; } ret = set_rto_link_flag(&rto_path.to_str().unwrap().to_string(), true); - println!("yp test {}", ret); ret = set_app_link_flag(&name.to_string(), true); - println!("yp test {}", ret); ret = bolt_add_link(name); - println!("yp test {}", ret); return ret; } diff --git a/src/sysboostd/main.rs b/src/sysboostd/main.rs index 5813a96..d33c0ab 100644 --- a/src/sysboostd/main.rs +++ b/src/sysboostd/main.rs @@ -40,6 +40,7 @@ use std::thread; const APP_NAME: &str = "sysboostd"; const DEFAULT_TIMEOUT: u32 = 10; +const PROFILE_PATH_DEFAULT: &str = "/usr/lib/sysboost.d/profile/mysqld.profile"; fn parameter_wrong_exit() { println!("parameter is wrong"); @@ -83,24 +84,18 @@ fn main() { if let Some(index) = args[i].find('=') { is_bolt = true; bolt_elf_name = &args[i][index + 1..]; - } else { - parameter_wrong_exit(); } continue; } if args[i].contains("--bolt-option=") { if let Some(index) = args[i].find('=') { bolt_option = &args[i][index + 1..]; - } else { - parameter_wrong_exit(); } continue; } if args[i].contains("--profile-path=") { if let Some(index) = args[i].find('=') { profile_path = &args[i][index + 1..]; - } else { - parameter_wrong_exit(); } continue; } @@ -108,7 +103,8 @@ fn main() { if let Some(index) = args[i].find('=') { is_stop = true; stop_elf_name = &args[i][index + 1..]; - } else { + } + if stop_elf_name.is_empty() { parameter_wrong_exit(); } continue; @@ -140,7 +136,9 @@ fn main() { parse_crashed_log(); //sysboostd --gen-bolt="/path/to/mysqld" --bolt-option="xxx" --profile-path="/path/to/mysqld.profile" if is_bolt { - logger::init_log_to_console(APP_NAME, log::LevelFilter::Debug); + if profile_path.is_empty() { + profile_path = PROFILE_PATH_DEFAULT; + } let ret = gen_bolt_optimize_bin(bolt_elf_name, bolt_option, profile_path); if ret < 0 { std::process::exit(-1); -- Gitee