Skip to content

Commit fe94489

Browse files
mayastor-borsabhilashshetty04
andcommitted
Merge #1948
1948: adding in memory structure to store pool information r=abhilashshetty04 a=abhilashshetty04 Co-authored-by: Abhilash Shetty <abhilash.shetty@datacore.com>
2 parents b9655d3 + 366eef3 commit fe94489

File tree

4 files changed

+92
-10
lines changed

4 files changed

+92
-10
lines changed

io-engine/src/grpc/v1/pool.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::{
1111
self, FindPoolArgs, IPoolFactory, ListPoolArgs, PoolArgs, PoolBackend, PoolFactory,
1212
PoolOps, ReplicaArgs,
1313
},
14+
pool_information::pool_info_read,
1415
};
1516
use ::function_name::named;
1617
use futures::FutureExt;
@@ -461,13 +462,25 @@ impl Deref for PoolErrorsNt {
461462
}
462463
}
463464
impl PoolErrorsNt {
464-
fn new(environ: &MayastorEnvironment, stats: &BdevErrorStats) -> Self {
465+
fn new(pool: &str, environ: &MayastorEnvironment, stats: &BdevErrorStats) -> Self {
466+
let mut io_stalled = false;
467+
let mut io_stall_transition_count: u64 = 0;
468+
469+
let cache = pool_info_read();
470+
471+
if let Some(pool_lock) = cache.get(pool) {
472+
let mut pool_mut = pool_lock.write();
473+
pool_mut.update_transition_timestamp(*environ.pool_args.io_stall_transition_window);
474+
io_stalled = pool_mut.io_stalled;
475+
io_stall_transition_count = pool_mut.transition_timestamps.len() as u64;
476+
}
477+
465478
Self(PoolErrors {
466479
alerts: None,
467480
io_error_count: stats.error_count(),
468481
io_error_threshold: environ.pool_args.io_error_threshold,
469-
io_stalled: false,
470-
io_stall_transition_count: 0,
482+
io_stalled,
483+
io_stall_transition_count,
471484
io_stall_transition_threshold: environ.pool_args.io_stall_transition_threshold,
472485
})
473486
}
@@ -488,8 +501,9 @@ impl PoolErrorsNt {
488501

489502
// todo: add sliding window parameters
490503
match self.io_stall_transition_count {
491-
0 => {}
492-
errors if errors < self.io_stall_transition_threshold => {
504+
// todo: Notice should be raised on 1 transition.
505+
0 | 1 => {}
506+
num_stalls if num_stalls < self.io_stall_transition_threshold => {
493507
self.set_alert(PoolAlertStatus::Attention, PoolAlert::IoStallIntermittent)
494508
}
495509
_ => self.set_alert(PoolAlertStatus::Warning, PoolAlert::IoStallIntermittentExc),
@@ -576,7 +590,7 @@ impl AsyncFrom<&dyn PoolOps> for Pool {
576590

577591
let errors = stats.as_ref().map(|stats| {
578592
let environ = MayastorEnvironment::global();
579-
PoolErrorsNt::new(&environ, stats)
593+
PoolErrorsNt::new(value.name(), &environ, stats)
580594
.with_io_errors()
581595
.with_io_stall()
582596
});

io-engine/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub mod lvm;
3131
pub mod lvs;
3232
pub mod persistent_store;
3333
pub mod pool_backend;
34+
pub mod pool_information;
3435
pub mod prctl;
3536
pub mod rebuild;
3637
pub mod replica_backend;

io-engine/src/lvs/lvs_store.rs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use core::f64;
2+
use parking_lot::RwLock;
23
use std::{convert::TryFrom, fmt::Debug, os::raw::c_void, pin::Pin, ptr::NonNull, str::FromStr};
34

45
use crate::sleep::mayastor_sleep;
@@ -39,6 +40,7 @@ use crate::{
3940
LvolSnapshotDescriptor,
4041
},
4142
pool_backend::{PoolArgs, ReplicaArgs},
43+
pool_information::{pool_info_write, PoolInfo},
4244
};
4345

4446
static ROUND_TO_MB: u32 = 1024 * 1024;
@@ -223,6 +225,18 @@ impl Lvs {
223225
uuid::Uuid::from_bytes(t).to_string()
224226
}
225227

228+
/// Adds pool information to in memory cache.
229+
pub fn add_info(&self) {
230+
let mut cache = pool_info_write();
231+
cache.insert(self.name().to_string(), RwLock::new(PoolInfo::default()));
232+
}
233+
234+
/// Removes pool information from in memory cache.
235+
pub fn remove_info(pool: &str) {
236+
let mut cache = pool_info_write();
237+
cache.remove(pool);
238+
}
239+
226240
// checks for the disks length and parses to correct format
227241
pub fn parse_disk(disks: Vec<String>) -> Result<String, LvsError> {
228242
let disk = match disks.first() {
@@ -314,6 +328,7 @@ impl Lvs {
314328
} else {
315329
lvs.share_all().await;
316330
info!("{:?}: existing lvs imported successfully", lvs);
331+
lvs.add_info();
317332
Ok(lvs)
318333
}
319334
}
@@ -556,6 +571,7 @@ impl Lvs {
556571
match Self::lookup(&args.name) {
557572
Some(pool) => {
558573
info!("{:?}: new lvs created successfully", pool);
574+
pool.add_info();
559575
Ok(pool)
560576
}
561577
None => Err(LvsError::PoolCreate {
@@ -713,12 +729,19 @@ impl Lvs {
713729

714730
unsafe { vbdev_lvs_unload(self.as_inner_ptr(), Some(Self::lvs_op_cb), cb_arg(s)) };
715731

716-
r.await
732+
let result = r
733+
.await
717734
.expect("callback gone while exporting lvs")
718735
.to_result(|e| LvsError::Export {
719736
source: BsError::from_i32(e),
720737
name: pool.clone(),
721-
})?;
738+
});
739+
740+
if Lvs::lookup(&pool).is_none() {
741+
Lvs::remove_info(&pool);
742+
}
743+
744+
result?;
722745

723746
info!(
724747
"{}: lvs exported successfully. base bdev: {}",
@@ -822,12 +845,19 @@ impl Lvs {
822845

823846
unsafe { vbdev_lvs_destruct(self.as_inner_ptr(), Some(Self::lvs_op_cb), cb_arg(s)) };
824847

825-
r.await
848+
let result = r
849+
.await
826850
.expect("callback gone while destroying lvs")
827851
.to_result(|e| LvsError::Export {
828852
source: BsError::from_i32(e),
829853
name: pool.clone(),
830-
})?;
854+
});
855+
856+
if Lvs::lookup(&pool).is_none() {
857+
Lvs::remove_info(&pool);
858+
}
859+
860+
result?;
831861

832862
info!(
833863
"{}: lvs destroyed successfully. base_bdev: {base_bdev:?}",

io-engine/src/pool_information.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use once_cell::sync::Lazy;
2+
use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard};
3+
use std::{
4+
collections::{HashMap, VecDeque},
5+
time::{Duration, Instant},
6+
};
7+
8+
/// In-memory structure containing pool runtime information.
9+
pub static POOL_INFO: Lazy<RwLock<HashMap<String, RwLock<PoolInfo>>>> =
10+
Lazy::new(|| RwLock::new(HashMap::new()));
11+
12+
/// Pool specfic information stored in-memory.
13+
#[derive(Default, Debug, Clone)]
14+
pub struct PoolInfo {
15+
/// Set when Pools io is under stall.
16+
pub io_stalled: bool,
17+
/// Contains list of timestamps when pool went into stall state.
18+
pub transition_timestamps: VecDeque<Instant>,
19+
}
20+
21+
impl PoolInfo {
22+
/// Retains only transition timestamps that are within the stall_transition_window.
23+
pub fn update_transition_timestamp(&mut self, stall_transition_window: Duration) {
24+
self.transition_timestamps
25+
.retain(|ts| ts.elapsed() < stall_transition_window);
26+
}
27+
}
28+
29+
/// Returns write lock of the hashmap.
30+
pub fn pool_info_write() -> RwLockWriteGuard<'static, HashMap<String, RwLock<PoolInfo>>> {
31+
POOL_INFO.write()
32+
}
33+
34+
/// Returns read lock of the hashmap.
35+
pub fn pool_info_read() -> RwLockReadGuard<'static, HashMap<String, RwLock<PoolInfo>>> {
36+
POOL_INFO.read()
37+
}

0 commit comments

Comments
 (0)