463 lines
15 KiB
Diff
463 lines
15 KiB
Diff
From d36bb9fa9a0322f475f6039948bba6ea8e106d74 Mon Sep 17 00:00:00 2001
|
|
From: xuxiaozhou1 <xuxiaozhou1@huawei.com>
|
|
Date: Sun, 2 Jul 2023 17:32:25 +0800
|
|
Subject: [PATCH] fix: isolate debugging code through configuration predicate
|
|
'debug'
|
|
|
|
---
|
|
build.rs | 8 +++
|
|
core/libsysmaster/rel/api.rs | 106 ++++++++-------------------------
|
|
core/libsysmaster/rel/base.rs | 40 +++++++++++--
|
|
core/libsysmaster/rel/debug.rs | 106 +++++++++++++++++++++++++++++++++
|
|
core/libsysmaster/rel/mod.rs | 6 +-
|
|
5 files changed, 178 insertions(+), 88 deletions(-)
|
|
create mode 100644 core/libsysmaster/rel/debug.rs
|
|
|
|
diff --git a/build.rs b/build.rs
|
|
index 05296f5..15c2a21 100644
|
|
--- a/build.rs
|
|
+++ b/build.rs
|
|
@@ -14,6 +14,8 @@
|
|
// if use env out_dir need add build.rs
|
|
use std::{env, process::Command};
|
|
|
|
+const RELEASE: &str = "release";
|
|
+
|
|
macro_rules! warn {
|
|
($message:expr) => {
|
|
println!("cargo:warning={}", $message);
|
|
@@ -45,4 +47,10 @@ fn main() {
|
|
println!("cargo:rerun-if-changed=build.sh");
|
|
println!("cargo:rerun-if-changed=build.rs");
|
|
// println!("cargo:rerun-if-changed=config.service");
|
|
+
|
|
+ // turn on "debug" for non-release build
|
|
+ let profile = env::var("PROFILE").unwrap();
|
|
+ if profile != RELEASE {
|
|
+ println!("cargo:rustc-cfg=debug");
|
|
+ }
|
|
}
|
|
diff --git a/core/libsysmaster/rel/api.rs b/core/libsysmaster/rel/api.rs
|
|
index 94f9015..ad7743a 100644
|
|
--- a/core/libsysmaster/rel/api.rs
|
|
+++ b/core/libsysmaster/rel/api.rs
|
|
@@ -10,6 +10,8 @@
|
|
// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
// See the Mulan PSL v2 for more details.
|
|
|
|
+#[cfg(debug)]
|
|
+use super::debug::{self, ReliDebug};
|
|
use super::{
|
|
enable::{self, ReliEnable},
|
|
history::{self, ReliHistory},
|
|
@@ -19,24 +21,9 @@ use super::{
|
|
ReDbTable, ReStation, ReStationKind,
|
|
};
|
|
use crate::{error::*, rel::base};
|
|
-use basic::do_entry_or_return_io_error;
|
|
use heed::Database;
|
|
use nix::sys::stat::{self, Mode};
|
|
-use std::{
|
|
- fs::{self, File},
|
|
- path::Path,
|
|
- rc::Rc,
|
|
- thread,
|
|
- time::Duration,
|
|
-};
|
|
-
|
|
-const RELI_DEBUG_SWITCH_FILE: &str = "switch.debug";
|
|
-const RELI_DEBUG_CLEAR_FILE: &str = "clear.debug";
|
|
-const RELI_DEBUG_CFIRST_FILE: &str = "clear_first.debug";
|
|
-const RELI_DEBUG_ENABLE_FILE: &str = "enable.debug";
|
|
-const RELI_DEBUG_PANIC_FILE: &str = "panic.debug";
|
|
-const RELI_DEBUG_PFIRST_FILE: &str = "panic_first.debug";
|
|
-const RELI_DEBUG_SLEEP_FILE: &str = "sleep.debug";
|
|
+use std::rc::Rc;
|
|
|
|
/// the configuration of reliability instance
|
|
pub struct ReliConf {
|
|
@@ -76,8 +63,11 @@ impl Default for ReliConf {
|
|
/// reliability instance
|
|
#[derive(Debug)]
|
|
pub struct Reliability {
|
|
+ // debug
|
|
+ #[cfg(debug)]
|
|
+ debug: ReliDebug,
|
|
+
|
|
// control data
|
|
- dir_string: String,
|
|
enable: ReliEnable,
|
|
|
|
// output data
|
|
@@ -102,7 +92,8 @@ impl Reliability {
|
|
pub fn new(conf: &ReliConf) -> Reliability {
|
|
let dir_s = reli_prepare().expect("reliability prepare");
|
|
let reli = Reliability {
|
|
- dir_string: dir_s.clone(),
|
|
+ #[cfg(debug)]
|
|
+ debug: ReliDebug::new(&dir_s),
|
|
enable: ReliEnable::new(&dir_s),
|
|
last: ReliLast::new(&dir_s),
|
|
history: ReliHistory::new(&dir_s, conf.map_size, conf.max_dbs),
|
|
@@ -250,8 +241,8 @@ impl Reliability {
|
|
|
|
/// do the debug action: enable the recover process
|
|
pub fn debug_enable(&self) {
|
|
- let enable = Path::new(&self.dir_string).join(RELI_DEBUG_ENABLE_FILE);
|
|
- if enable.exists() {
|
|
+ #[cfg(debug)]
|
|
+ if self.debug.enable() {
|
|
log::info!("reliability debug: enable data...");
|
|
self.set_enable(true);
|
|
}
|
|
@@ -259,53 +250,25 @@ impl Reliability {
|
|
|
|
/// do the debug action: clear data excluding enable
|
|
pub fn debug_clear(&self) {
|
|
- let clear = Path::new(&self.dir_string).join(RELI_DEBUG_CLEAR_FILE);
|
|
- if clear.exists() {
|
|
- log::info!("reliability debug: clear data...");
|
|
- let cfirst = Path::new(&self.dir_string).join(RELI_DEBUG_CFIRST_FILE);
|
|
- if cfirst.exists() {
|
|
- // do nothing
|
|
- log::info!("reliability debug_clear: non-first time, do nothing.");
|
|
- } else {
|
|
- log::info!("reliability debug_clear: first time, try clear.");
|
|
- File::create(&cfirst).unwrap();
|
|
- log::debug!("Successfully created {cfirst:?}");
|
|
- log::info!("reliability debug_clear: first time, clear ...");
|
|
-
|
|
- // clear data excluding enable
|
|
- let enable = self.enable();
|
|
- self.data_clear();
|
|
- self.set_enable(enable);
|
|
- }
|
|
+ #[cfg(debug)]
|
|
+ if self.debug.clear() {
|
|
+ // clear data excluding enable
|
|
+ let enable = self.enable();
|
|
+ self.data_clear();
|
|
+ self.set_enable(enable);
|
|
}
|
|
}
|
|
|
|
/// do the debug action: panic
|
|
pub fn debug_panic(&self) {
|
|
- let panic = Path::new(&self.dir_string).join(RELI_DEBUG_PANIC_FILE);
|
|
- if panic.exists() {
|
|
- log::info!("reliability debug: panic...");
|
|
- let pfirst = Path::new(&self.dir_string).join(RELI_DEBUG_PFIRST_FILE);
|
|
- if pfirst.exists() {
|
|
- // do nothing
|
|
- log::info!("reliability debug_panic: non-first time, do nothing.");
|
|
- } else {
|
|
- log::info!("reliability debug_panic: first time, try panic.");
|
|
- File::create(&pfirst).unwrap();
|
|
- log::debug!("Successfully created {pfirst:?}");
|
|
- log::info!("reliability debug_panic: first time, panic ...");
|
|
- panic!("first debug_panic.");
|
|
- }
|
|
- }
|
|
+ #[cfg(debug)]
|
|
+ self.debug.panic();
|
|
}
|
|
|
|
/// do the debug action: sleep
|
|
pub fn debug_sleep(&self) {
|
|
- let sleep = Path::new(&self.dir_string).join(RELI_DEBUG_SLEEP_FILE);
|
|
- if sleep.exists() {
|
|
- log::info!("reliability debug: sleep...");
|
|
- thread::sleep(Duration::from_secs(3600));
|
|
- }
|
|
+ #[cfg(debug)]
|
|
+ self.debug.sleep();
|
|
}
|
|
|
|
fn input_rebuild(&self) {
|
|
@@ -365,31 +328,12 @@ impl Reliability {
|
|
}
|
|
}
|
|
|
|
-/// do the debug action: enable or disable switch flag. effective after restart.
|
|
-#[allow(dead_code)]
|
|
-pub fn reli_debug_enable_switch(enable: bool) -> Result<()> {
|
|
- log::info!("reliability debug: enable[{}] switch.", enable);
|
|
-
|
|
- let dir_string = base::reli_dir_get().unwrap();
|
|
- let switch = Path::new(&dir_string).join(RELI_DEBUG_SWITCH_FILE);
|
|
- // touch switch.debug if enable
|
|
- if enable && !switch.exists() {
|
|
- do_entry_or_return_io_error!(File::create, switch, "create");
|
|
- }
|
|
- // remove switch.debug if disable
|
|
- if !enable && switch.exists() {
|
|
- do_entry_or_return_io_error!(fs::remove_file, switch, "remove");
|
|
- }
|
|
-
|
|
- Ok(())
|
|
-}
|
|
-
|
|
/// get the debug flag of switch
|
|
pub fn reli_debug_get_switch() -> bool {
|
|
- let dir_string = base::reli_dir_get().expect("guaranteed by caller.");
|
|
- let switch = Path::new(&dir_string).join(RELI_DEBUG_SWITCH_FILE);
|
|
- log::info!("reliability debug: get switch file: {:?}.", switch);
|
|
- switch.exists()
|
|
+ #[cfg(debug)]
|
|
+ return debug::switch();
|
|
+ #[cfg(not(debug))]
|
|
+ return true;
|
|
}
|
|
|
|
fn reli_prepare() -> Result<String> {
|
|
diff --git a/core/libsysmaster/rel/base.rs b/core/libsysmaster/rel/base.rs
|
|
index 65307e0..bcc8a21 100644
|
|
--- a/core/libsysmaster/rel/base.rs
|
|
+++ b/core/libsysmaster/rel/base.rs
|
|
@@ -20,10 +20,12 @@ use serde::de::DeserializeOwned;
|
|
use serde::Serialize;
|
|
use std::cell::RefCell;
|
|
use std::collections::{HashMap, HashSet};
|
|
+#[cfg(debug)]
|
|
+use std::env;
|
|
use std::fmt::Debug;
|
|
+use std::fs;
|
|
use std::hash::Hash;
|
|
use std::path::Path;
|
|
-use std::{env, fs};
|
|
|
|
/// the reliability database
|
|
/// K & V that can be deserialized without borrowing any data from the deserializer.
|
|
@@ -275,7 +277,21 @@ pub trait ReDbTable {
|
|
|
|
const RELI_PATH_DIR: &str = "/run/sysmaster/reliability";
|
|
|
|
+/// get the directory for reliability.
|
|
pub fn reli_dir_get() -> Result<String> {
|
|
+ #[cfg(debug)]
|
|
+ return reli_dir_get_debug();
|
|
+ #[cfg(not(debug))]
|
|
+ return reli_dir_get_release();
|
|
+}
|
|
+
|
|
+#[cfg(not(debug))]
|
|
+fn reli_dir_get_release() -> Result<String> {
|
|
+ return reli_dir_get_run();
|
|
+}
|
|
+
|
|
+#[cfg(debug)]
|
|
+fn reli_dir_get_debug() -> Result<String> {
|
|
// /run/sysmaster/reliability/
|
|
let ret_run = reli_dir_get_run();
|
|
if ret_run.is_ok() {
|
|
@@ -303,17 +319,26 @@ pub fn reli_dir_get() -> Result<String> {
|
|
/// prepare the directory for reliability.
|
|
/// the reliability path is prepared and searched according to the following priority, from high to low:
|
|
/// 1. /run/sysmaster/reliability/: the real running directory.
|
|
-/// 2. OUT_DIR/../reliability/: make CI happy, which is target/debug/reliability/ or target/release/reliability/ usually.
|
|
-/// 3. PROCESS_RELI_PATH: the path customized.
|
|
+/// 2. [debug-only]OUT_DIR/../reliability/: make CI happy, which is target/debug/reliability/ or target/release/reliability/ usually.
|
|
+/// 3. [debug-only]ROCESS_RELI_PATH: the path customized.
|
|
pub fn reli_dir_prepare() -> Result<()> {
|
|
// create '/run/sysmaster/reliability' or 'xxx/reliability' with mode 700
|
|
let old_mask = stat::umask(Mode::from_bits_truncate(!0o700));
|
|
- let ret = reli_dir_prepare_body();
|
|
+ #[cfg(debug)]
|
|
+ let ret = reli_dir_prepare_debug();
|
|
+ #[cfg(not(debug))]
|
|
+ let ret = reli_dir_prepare_release();
|
|
let _ = stat::umask(old_mask);
|
|
ret
|
|
}
|
|
|
|
-fn reli_dir_prepare_body() -> Result<()> {
|
|
+#[cfg(not(debug))]
|
|
+fn reli_dir_prepare_release() -> Result<()> {
|
|
+ return reli_dir_prepare_run();
|
|
+}
|
|
+
|
|
+#[cfg(debug)]
|
|
+fn reli_dir_prepare_debug() -> Result<()> {
|
|
// // /run/sysmaster/reliability/
|
|
let ret_run = reli_dir_prepare_run();
|
|
if ret_run.is_ok() {
|
|
@@ -373,6 +398,7 @@ fn reli_dir_get_run() -> Result<String> {
|
|
}
|
|
}
|
|
|
|
+#[cfg(debug)]
|
|
fn reli_dir_prepare_out() -> Result<()> {
|
|
let dir_string = out_dir_string_get();
|
|
if let Some(d_str) = dir_string {
|
|
@@ -390,6 +416,7 @@ fn reli_dir_prepare_out() -> Result<()> {
|
|
})
|
|
}
|
|
|
|
+#[cfg(debug)]
|
|
fn reli_dir_get_out() -> Result<String> {
|
|
let dir_string = out_dir_string_get();
|
|
if let Some(d_str) = dir_string {
|
|
@@ -405,6 +432,7 @@ fn reli_dir_get_out() -> Result<String> {
|
|
})
|
|
}
|
|
|
|
+#[cfg(debug)]
|
|
fn reli_dir_prepare_customize() -> Result<()> {
|
|
let dir_string = env::var("PROCESS_LIB_LOAD_PATH").ok();
|
|
if let Some(d_str) = dir_string {
|
|
@@ -425,6 +453,7 @@ fn reli_dir_prepare_customize() -> Result<()> {
|
|
})
|
|
}
|
|
|
|
+#[cfg(debug)]
|
|
fn reli_dir_get_customize() -> Result<String> {
|
|
let dir_string = env::var("PROCESS_LIB_LOAD_PATH").ok();
|
|
if let Some(d_str) = dir_string {
|
|
@@ -443,6 +472,7 @@ fn reli_dir_get_customize() -> Result<String> {
|
|
})
|
|
}
|
|
|
|
+#[cfg(debug)]
|
|
fn out_dir_string_get() -> Option<String> {
|
|
let run = env::var("OUT_DIR").ok();
|
|
let compile: Option<String> = option_env!("OUT_DIR").map(String::from);
|
|
diff --git a/core/libsysmaster/rel/debug.rs b/core/libsysmaster/rel/debug.rs
|
|
new file mode 100644
|
|
index 0000000..fff3463
|
|
--- /dev/null
|
|
+++ b/core/libsysmaster/rel/debug.rs
|
|
@@ -0,0 +1,106 @@
|
|
+use super::base::{self};
|
|
+use crate::error::*;
|
|
+use basic::do_entry_or_return_io_error;
|
|
+use std::fs::{self, File};
|
|
+use std::path::Path;
|
|
+use std::thread;
|
|
+use std::time::Duration;
|
|
+
|
|
+const RELI_DEBUG_SWITCH_FILE: &str = "switch.debug";
|
|
+const RELI_DEBUG_CLEAR_FILE: &str = "clear.debug";
|
|
+const RELI_DEBUG_CFIRST_FILE: &str = "clear_first.debug";
|
|
+const RELI_DEBUG_ENABLE_FILE: &str = "enable.debug";
|
|
+const RELI_DEBUG_PANIC_FILE: &str = "panic.debug";
|
|
+const RELI_DEBUG_PFIRST_FILE: &str = "panic_first.debug";
|
|
+const RELI_DEBUG_SLEEP_FILE: &str = "sleep.debug";
|
|
+
|
|
+#[derive(Debug)]
|
|
+pub(crate) struct ReliDebug {
|
|
+ hdir: String, // home-directory
|
|
+}
|
|
+
|
|
+impl ReliDebug {
|
|
+ pub(crate) fn new(dir_str: &str) -> ReliDebug {
|
|
+ ReliDebug {
|
|
+ hdir: String::from(dir_str),
|
|
+ }
|
|
+ }
|
|
+
|
|
+ pub(crate) fn enable(&self) -> bool {
|
|
+ let enable = Path::new(&self.hdir).join(RELI_DEBUG_ENABLE_FILE);
|
|
+ enable.exists()
|
|
+ }
|
|
+
|
|
+ pub(crate) fn clear(&self) -> bool {
|
|
+ let clear = Path::new(&self.hdir).join(RELI_DEBUG_CLEAR_FILE);
|
|
+ if clear.exists() {
|
|
+ let cfirst = Path::new(&self.hdir).join(RELI_DEBUG_CFIRST_FILE);
|
|
+ if cfirst.exists() {
|
|
+ // do nothing
|
|
+ log::info!("reliability debug_clear: non-first time, do nothing.");
|
|
+ false
|
|
+ } else {
|
|
+ File::create(&cfirst).unwrap();
|
|
+ log::debug!("Successfully created {cfirst:?}");
|
|
+
|
|
+ // clear data
|
|
+ log::info!("reliability debug_clear: first time, clear ...");
|
|
+ true
|
|
+ }
|
|
+ } else {
|
|
+ false
|
|
+ }
|
|
+ }
|
|
+
|
|
+ pub(crate) fn panic(&self) {
|
|
+ let panic = Path::new(&self.hdir).join(RELI_DEBUG_PANIC_FILE);
|
|
+ if panic.exists() {
|
|
+ let pfirst = Path::new(&self.hdir).join(RELI_DEBUG_PFIRST_FILE);
|
|
+ if pfirst.exists() {
|
|
+ // do nothing
|
|
+ log::info!("reliability debug_panic: non-first time, do nothing.");
|
|
+ } else {
|
|
+ File::create(&pfirst).unwrap();
|
|
+ log::debug!("Successfully created {pfirst:?}");
|
|
+
|
|
+ // panic
|
|
+ log::info!("reliability debug_panic: first time, panic ...");
|
|
+ panic!("first debug_panic.");
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ pub(crate) fn sleep(&self) {
|
|
+ let sleep = Path::new(&self.hdir).join(RELI_DEBUG_SLEEP_FILE);
|
|
+ if sleep.exists() {
|
|
+ log::info!("reliability debug: sleep...");
|
|
+ thread::sleep(Duration::from_secs(3600));
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+#[allow(dead_code)]
|
|
+pub(crate) fn enable_switch(enable: bool) -> Result<()> {
|
|
+ // do the debug action: enable or disable switch flag. effective after restart.
|
|
+ log::info!("reliability debug: enable[{}] switch.", enable);
|
|
+
|
|
+ let dir_string = base::reli_dir_get().unwrap();
|
|
+ let switch = Path::new(&dir_string).join(RELI_DEBUG_SWITCH_FILE);
|
|
+ // touch switch.debug if enable
|
|
+ if enable && !switch.exists() {
|
|
+ do_entry_or_return_io_error!(File::create, switch, "create");
|
|
+ }
|
|
+ // remove switch.debug if disable
|
|
+ if !enable && switch.exists() {
|
|
+ do_entry_or_return_io_error!(fs::remove_file, switch, "remove");
|
|
+ }
|
|
+
|
|
+ Ok(())
|
|
+}
|
|
+
|
|
+pub(crate) fn switch() -> bool {
|
|
+ let dir_string = base::reli_dir_get().expect("guaranteed by caller.");
|
|
+ let switch = Path::new(&dir_string).join(RELI_DEBUG_SWITCH_FILE);
|
|
+ log::info!("reliability debug: get switch file: {:?}.", switch);
|
|
+ switch.exists()
|
|
+}
|
|
diff --git a/core/libsysmaster/rel/mod.rs b/core/libsysmaster/rel/mod.rs
|
|
index 07470e4..2ae515a 100644
|
|
--- a/core/libsysmaster/rel/mod.rs
|
|
+++ b/core/libsysmaster/rel/mod.rs
|
|
@@ -11,15 +11,17 @@
|
|
// See the Mulan PSL v2 for more details.
|
|
|
|
//! reliability module
|
|
-pub use api::{reli_debug_enable_switch, reli_debug_get_switch, ReliConf, Reliability};
|
|
+pub use api::{reli_debug_get_switch, ReliConf, Reliability};
|
|
pub use base::{reli_dir_prepare, ReDb, ReDbRoTxn, ReDbRwTxn, ReDbTable};
|
|
use serde::{Deserialize, Serialize};
|
|
pub use station::{ReStation, ReStationKind};
|
|
use std::convert::TryFrom;
|
|
|
|
-// dependency: base -> {enable | last | history | pending | station} -> api
|
|
+// dependency: base -> {enable | last | history | pending | station} -> debug -> api
|
|
mod api;
|
|
mod base;
|
|
+#[cfg(debug)]
|
|
+mod debug;
|
|
mod enable;
|
|
mod history;
|
|
mod last;
|
|
--
|
|
2.33.0
|
|
|