vmm/vmm_config/
entropy.rs1use std::ops::Deref;
5use std::sync::{Arc, Mutex};
6
7use serde::{Deserialize, Serialize};
8
9use super::RateLimiterConfig;
10use crate::devices::virtio::rng::{Entropy, EntropyError};
11
12#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)]
15#[serde(deny_unknown_fields)]
16pub struct EntropyDeviceConfig {
17 pub rate_limiter: Option<RateLimiterConfig>,
19}
20
21impl From<&Entropy> for EntropyDeviceConfig {
22 fn from(dev: &Entropy) -> Self {
23 let rate_limiter: RateLimiterConfig = dev.rate_limiter().into();
24 EntropyDeviceConfig {
25 rate_limiter: rate_limiter.into_option(),
26 }
27 }
28}
29
30#[derive(Debug, thiserror::Error, displaydoc::Display)]
33pub enum EntropyDeviceError {
34 CreateDevice(#[from] EntropyError),
36 CreateRateLimiter(#[from] std::io::Error),
38}
39
40#[derive(Debug, Default)]
42pub struct EntropyDeviceBuilder(Option<Arc<Mutex<Entropy>>>);
43
44impl EntropyDeviceBuilder {
45 pub fn new() -> Self {
47 Self(None)
48 }
49
50 pub fn build(
52 &mut self,
53 config: EntropyDeviceConfig,
54 ) -> Result<Arc<Mutex<Entropy>>, EntropyDeviceError> {
55 let rate_limiter = config
56 .rate_limiter
57 .map(RateLimiterConfig::try_into)
58 .transpose()?;
59 let dev = Arc::new(Mutex::new(Entropy::new(rate_limiter.unwrap_or_default())?));
60 self.0 = Some(dev.clone());
61
62 Ok(dev)
63 }
64
65 pub fn insert(&mut self, config: EntropyDeviceConfig) -> Result<(), EntropyDeviceError> {
67 let _ = self.build(config)?;
68 Ok(())
69 }
70
71 pub fn get(&self) -> Option<&Arc<Mutex<Entropy>>> {
73 self.0.as_ref()
74 }
75
76 pub fn config(&self) -> Option<EntropyDeviceConfig> {
78 self.0
79 .as_ref()
80 .map(|dev| EntropyDeviceConfig::from(dev.lock().unwrap().deref()))
81 }
82
83 pub fn set_device(&mut self, device: Arc<Mutex<Entropy>>) {
85 self.0 = Some(device);
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92 use crate::rate_limiter::RateLimiter;
93
94 #[test]
95 fn test_entropy_device_create() {
96 let config = EntropyDeviceConfig::default();
97 let mut builder = EntropyDeviceBuilder::new();
98 assert!(builder.get().is_none());
99
100 builder.insert(config.clone()).unwrap();
101 assert!(builder.get().is_some());
102 assert_eq!(builder.config().unwrap(), config);
103 }
104
105 #[test]
106 fn test_set_device() {
107 let mut builder = EntropyDeviceBuilder::new();
108 let device = Entropy::new(RateLimiter::default()).unwrap();
109 assert!(builder.0.is_none());
110 builder.set_device(Arc::new(Mutex::new(device)));
111 assert!(builder.0.is_some());
112 }
113}