dragonball: METRICS is refactored to RwLock<DragonballMetrics>

In this commit, the METRICS is refactored to RwLock<DragonballMetrics>.

Fixes: #7248

Signed-off-by: lisongqian <mail@lisongqian.cn>
This commit is contained in:
lisongqian 2023-09-23 13:54:54 +08:00
parent 1280f85343
commit fa60fbe023
3 changed files with 20 additions and 17 deletions

View File

@ -90,13 +90,15 @@ fn set_intgauge_vec_vcpu(icv: &prometheus::IntGaugeVec) {
} }
fn set_intgauge_vec_seccomp(icv: &prometheus::IntGaugeVec) { fn set_intgauge_vec_seccomp(icv: &prometheus::IntGaugeVec) {
let metric_gurad = METRICS.read().unwrap();
icv.with_label_values(&["num_faults"]) icv.with_label_values(&["num_faults"])
.set(METRICS.seccomp.num_faults.count() as i64); .set(metric_gurad.seccomp.num_faults.count() as i64);
} }
fn set_intgauge_vec_signals(icv: &prometheus::IntGaugeVec) { fn set_intgauge_vec_signals(icv: &prometheus::IntGaugeVec) {
let metric_gurad = METRICS.read().unwrap();
icv.with_label_values(&["sigbus"]) icv.with_label_values(&["sigbus"])
.set(METRICS.signals.sigbus.count() as i64); .set(metric_gurad.signals.sigbus.count() as i64);
icv.with_label_values(&["sigsegv"]) icv.with_label_values(&["sigsegv"])
.set(METRICS.signals.sigsegv.count() as i64); .set(metric_gurad.signals.sigsegv.count() as i64);
} }

View File

@ -2,15 +2,15 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use dbs_utils::metric::SharedIncMetric; use std::sync::{Arc, RwLock};
use dbs_utils::metric::{IncMetric, SharedIncMetric};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use serde::Serialize; use serde::Serialize;
pub use dbs_utils::metric::IncMetric;
lazy_static! { lazy_static! {
/// Static instance used for handling metrics. /// Static instance used for handling metrics.
pub static ref METRICS: DragonballMetrics = DragonballMetrics::default(); pub static ref METRICS: RwLock<DragonballMetrics> = RwLock::new(DragonballMetrics::default());
} }
/// Metrics specific to VCPUs' mode of functioning. /// Metrics specific to VCPUs' mode of functioning.

View File

@ -1,11 +1,12 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use dbs_utils::metric::IncMetric;
use libc::{_exit, c_int, c_void, siginfo_t, SIGBUS, SIGSEGV, SIGSYS}; use libc::{_exit, c_int, c_void, siginfo_t, SIGBUS, SIGSEGV, SIGSYS};
use log::error; use log::error;
use vmm_sys_util::signal::register_signal_handler; use vmm_sys_util::signal::register_signal_handler;
use crate::metric::{IncMetric, METRICS}; use crate::metric::METRICS;
// The offset of `si_syscall` (offending syscall identifier) within the siginfo structure // The offset of `si_syscall` (offending syscall identifier) within the siginfo structure
// expressed as an `(u)int*`. // expressed as an `(u)int*`.
@ -51,7 +52,7 @@ extern "C" fn sigsys_handler(num: c_int, info: *mut siginfo_t, _unused: *mut c_v
let syscall = unsafe { *(info as *const i32).offset(SI_OFF_SYSCALL) as usize }; let syscall = unsafe { *(info as *const i32).offset(SI_OFF_SYSCALL) as usize };
// SIGSYS is triggered when bad syscalls are detected. num_faults is only added when SIGSYS is detected // SIGSYS is triggered when bad syscalls are detected. num_faults is only added when SIGSYS is detected
// so it actually only collects the count for bad syscalls. // so it actually only collects the count for bad syscalls.
METRICS.seccomp.num_faults.inc(); METRICS.read().unwrap().seccomp.num_faults.inc();
error!( error!(
"Shutting down VM after intercepting a bad syscall ({}).", "Shutting down VM after intercepting a bad syscall ({}).",
syscall syscall
@ -82,8 +83,8 @@ extern "C" fn sigbus_sigsegv_handler(num: c_int, info: *mut siginfo_t, _unused:
// Other signals which might do async unsafe things incompatible with the rest of this // Other signals which might do async unsafe things incompatible with the rest of this
// function are blocked due to the sa_mask used when registering the signal handler. // function are blocked due to the sa_mask used when registering the signal handler.
match si_signo { match si_signo {
SIGBUS => METRICS.signals.sigbus.inc(), SIGBUS => METRICS.read().unwrap().signals.sigbus.inc(),
SIGSEGV => METRICS.signals.sigsegv.inc(), SIGSEGV => METRICS.read().unwrap().signals.sigsegv.inc(),
_ => (), _ => (),
} }
@ -182,19 +183,19 @@ mod tests {
.unwrap(); .unwrap();
assert!(apply_filter(&TryInto::<BpfProgram>::try_into(filter).unwrap()).is_ok()); assert!(apply_filter(&TryInto::<BpfProgram>::try_into(filter).unwrap()).is_ok());
assert_eq!(METRICS.seccomp.num_faults.count(), 0); assert_eq!(METRICS.read().unwrap().seccomp.num_faults.count(), 0);
// Call the blacklisted `SYS_mkdirat`. // Call the blacklisted `SYS_mkdirat`.
unsafe { syscall(libc::SYS_mkdirat, "/foo/bar\0") }; unsafe { syscall(libc::SYS_mkdirat, "/foo/bar\0") };
// Call SIGBUS signal handler. // Call SIGBUS signal handler.
assert_eq!(METRICS.signals.sigbus.count(), 0); assert_eq!(METRICS.read().unwrap().signals.sigbus.count(), 0);
unsafe { unsafe {
syscall(libc::SYS_kill, process::id(), SIGBUS); syscall(libc::SYS_kill, process::id(), SIGBUS);
} }
// Call SIGSEGV signal handler. // Call SIGSEGV signal handler.
assert_eq!(METRICS.signals.sigsegv.count(), 0); assert_eq!(METRICS.read().unwrap().signals.sigsegv.count(), 0);
unsafe { unsafe {
syscall(libc::SYS_kill, process::id(), SIGSEGV); syscall(libc::SYS_kill, process::id(), SIGSEGV);
} }
@ -211,9 +212,9 @@ mod tests {
// tests, so we use this as an heuristic to decide if we check the assertion. // tests, so we use this as an heuristic to decide if we check the assertion.
if cpu_count() > 1 { if cpu_count() > 1 {
// The signal handler should let the program continue during unit tests. // The signal handler should let the program continue during unit tests.
assert!(METRICS.seccomp.num_faults.count() >= 1); assert!(METRICS.read().unwrap().seccomp.num_faults.count() >= 1);
} }
assert!(METRICS.signals.sigbus.count() >= 1); assert!(METRICS.read().unwrap().signals.sigbus.count() >= 1);
assert!(METRICS.signals.sigsegv.count() >= 1); assert!(METRICS.read().unwrap().signals.sigsegv.count() >= 1);
} }
} }