procsys/
kernel_random.rs

1use std::path::Path;
2
3use serde::Serialize;
4
5use crate::{error::CollectResult, utils};
6
7enum KernelRandomInfo {
8    EntropyAvaliable,
9    PoolSize,
10    URandomMinReseedSeconds,
11    WriteWakeupThreshold,
12    ReadWakeupThreshold,
13    Unknown,
14}
15
16impl KernelRandomInfo {
17    fn from(name: &str) -> KernelRandomInfo {
18        match name {
19            "entropy_avail" => KernelRandomInfo::EntropyAvaliable,
20            "poolsize" => KernelRandomInfo::PoolSize,
21            "urandom_min_reseed_secs" => KernelRandomInfo::URandomMinReseedSeconds,
22            "write_wakeup_threshold" => KernelRandomInfo::WriteWakeupThreshold,
23            "read_wakeup_threshold" => KernelRandomInfo::ReadWakeupThreshold,
24            _ => KernelRandomInfo::Unknown,
25        }
26    }
27}
28
29/// KernelRandom contains information about to the kernel's random number generator
30#[derive(Debug, Serialize, Clone, Default)]
31pub struct KernelRandom {
32    pub entropy_available: Option<u64>,
33    pub pool_size: Option<u64>,
34    pub urandom_min_reseed_secs: Option<u64>,
35    pub write_wakeup_threshold: Option<u64>,
36    pub read_wakeup_threshold: Option<u64>,
37}
38
39impl KernelRandom {
40    fn new() -> Self {
41        Default::default()
42    }
43}
44
45/// collects and return kernel's random number generator information
46/// from /proc/sys/kernel/random
47/// # Example
48/// ```
49/// use procsys::kernel_random;
50///
51/// let krandom = kernel_random::collect().expect("kernel random generator");
52///
53/// let json_output = serde_json::to_string_pretty(&krandom).unwrap();
54/// println!("{}", json_output);
55///
56/// ```
57pub fn collect() -> CollectResult<KernelRandom> {
58    let krandom_dir = Path::new("/proc/sys/kernel/random");
59    collect_from(krandom_dir)
60}
61
62fn collect_from(base_path: &Path) -> CollectResult<KernelRandom> {
63    let mut krandom = KernelRandom::new();
64
65    for item in utils::list_dir_content(base_path, "", "random") {
66        match KernelRandomInfo::from(&item) {
67            KernelRandomInfo::EntropyAvaliable => {
68                krandom.entropy_available = utils::collect_info_u64(&item, base_path)?
69            }
70            KernelRandomInfo::PoolSize => {
71                krandom.pool_size = utils::collect_info_u64(&item, base_path)?
72            }
73            KernelRandomInfo::URandomMinReseedSeconds => {
74                krandom.urandom_min_reseed_secs = utils::collect_info_u64(&item, base_path)?
75            }
76            KernelRandomInfo::WriteWakeupThreshold => {
77                krandom.write_wakeup_threshold = utils::collect_info_u64(&item, base_path)?
78            }
79            KernelRandomInfo::ReadWakeupThreshold => {
80                krandom.read_wakeup_threshold = utils::collect_info_u64(&item, base_path)?
81            }
82            KernelRandomInfo::Unknown => {}
83        }
84    }
85
86    Ok(krandom)
87}
88
89#[cfg(test)]
90mod tests {
91    use super::*;
92
93    #[test]
94    fn kernel_random_gen() {
95        let krandom_dir = Path::new("test_data/fixtures/proc/sys/kernel/random");
96        let krandom =
97            collect_from(krandom_dir).expect("collecting random number generator information");
98
99        assert_eq!(krandom.entropy_available.unwrap(), 3943);
100        assert_eq!(krandom.pool_size.unwrap(), 4096);
101        assert_eq!(krandom.urandom_min_reseed_secs.unwrap(), 60);
102        assert_eq!(krandom.write_wakeup_threshold.unwrap(), 3072);
103        assert!(krandom.read_wakeup_threshold.is_none());
104    }
105}