Skip to content

Commit bc22b43

Browse files
acatangiusandreim
authored andcommitted
device-manager: add helper func 'for_each_device'
Signed-off-by: Adrian Catangiu <[email protected]>
1 parent cf17942 commit bc22b43

File tree

2 files changed

+62
-20
lines changed

2 files changed

+62
-20
lines changed

src/vmm/src/device_manager/mmio.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,27 @@ impl MMIODeviceManager {
319319
}
320320
None
321321
}
322+
323+
#[cfg(target_arch = "x86_64")]
324+
/// Run fn for each registered device.
325+
pub fn for_each_device<F, E>(&self, mut f: F) -> std::result::Result<(), E>
326+
where
327+
F: FnMut(
328+
&DeviceType,
329+
&String,
330+
&MMIODeviceInfo,
331+
&Mutex<dyn BusDevice>,
332+
) -> std::result::Result<(), E>,
333+
{
334+
for ((device_type, device_id), device_info) in self.get_device_info().iter() {
335+
let bus_device = self
336+
.get_device(*device_type, device_id)
337+
// Safe to unwrap() because we know the device exists.
338+
.unwrap();
339+
f(device_type, device_id, device_info, bus_device)?;
340+
}
341+
Ok(())
342+
}
322343
}
323344

324345
#[cfg(target_arch = "aarch64")]
@@ -551,6 +572,10 @@ mod tests {
551572
GuestMemoryMmap::from_ranges(&[(start_addr1, 0x1000), (start_addr2, 0x1000)]).unwrap();
552573
let mut vm = builder::setup_kvm_vm(&guest_mem, false).unwrap();
553574

575+
#[cfg(target_arch = "x86_64")]
576+
// Only used for x86_64 part of the test.
577+
let mem_clone = guest_mem.clone();
578+
554579
#[cfg(target_arch = "x86_64")]
555580
assert!(builder::setup_interrupt_controller(&mut vm).is_ok());
556581
#[cfg(target_arch = "aarch64")]
@@ -582,6 +607,27 @@ mod tests {
582607
assert!(device_manager
583608
.get_device(DeviceType::Virtio(type_id), &id)
584609
.is_none());
610+
611+
#[cfg(target_arch = "x86_64")]
612+
{
613+
let dummy2 = Arc::new(Mutex::new(DummyDevice::new()));
614+
let id2 = String::from("foo2");
615+
device_manager
616+
.register_virtio_test_device(vm.fd(), mem_clone, dummy2, &mut cmdline, &id2)
617+
.unwrap();
618+
619+
let mut count = 0;
620+
let _: Result<()> = device_manager.for_each_device(|devtype, devid, _, _| {
621+
assert_eq!(*devtype, DeviceType::Virtio(type_id));
622+
match devid.as_str() {
623+
"foo" => count += 1,
624+
"foo2" => count += 2,
625+
_ => unreachable!(),
626+
};
627+
Ok(())
628+
});
629+
assert_eq!(count, 3);
630+
}
585631
}
586632

587633
#[test]

src/vmm/src/device_manager/persist.rs

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
#![cfg(target_arch = "x86_64")]
88

99
use std::io;
10+
use std::result::Result;
1011
use std::sync::{Arc, Mutex};
1112

1213
use super::mmio::*;
1314

14-
use devices::pseudo::BootTimer;
1515
use devices::virtio::block::persist::{BlockConstructorArgs, BlockState};
1616
use devices::virtio::block::Block;
1717
use devices::virtio::net::persist::{Error as NetError, NetConstructorArgs, NetState};
@@ -106,20 +106,14 @@ impl<'a> Persist<'a> for MMIODeviceManager {
106106
net_devices: Vec::new(),
107107
vsock_device: None,
108108
};
109-
for ((device_type, device_id), device_info) in self.get_device_info().iter() {
110-
let bus_device = self
111-
.get_device(*device_type, device_id)
112-
// Safe to unwrap() because we know the device exists.
113-
.unwrap()
114-
.lock()
115-
.expect("Poisoned lock");
116-
117-
if bus_device.as_any().downcast_ref::<BootTimer>().is_some() {
109+
let _: Result<(), ()> = self.for_each_device(|devtype, devid, devinfo, bus_dev| {
110+
if *devtype == arch::DeviceType::BootTimer {
118111
// No need to save BootTimer state.
119-
continue;
112+
return Ok(());
120113
}
121114

122-
let mmio_transport = bus_device
115+
let locked_bus_dev = bus_dev.lock().expect("Poisoned lock");
116+
let mmio_transport = locked_bus_dev
123117
.as_any()
124118
// Only MmioTransport implements BusDevice on x86_64 at this point.
125119
.downcast_ref::<MmioTransport>()
@@ -136,19 +130,19 @@ impl<'a> Persist<'a> for MMIODeviceManager {
136130
.unwrap()
137131
.save();
138132
states.block_devices.push(ConnectedBlockState {
139-
device_id: device_id.clone(),
133+
device_id: devid.clone(),
140134
device_state: block_state,
141135
transport_state,
142-
mmio_slot: device_info.clone(),
136+
mmio_slot: devinfo.clone(),
143137
});
144138
}
145139
TYPE_NET => {
146140
let net_state = locked_device.as_any().downcast_ref::<Net>().unwrap().save();
147141
states.net_devices.push(ConnectedNetState {
148-
device_id: device_id.clone(),
142+
device_id: devid.clone(),
149143
device_state: net_state,
150144
transport_state,
151-
mmio_slot: device_info.clone(),
145+
mmio_slot: devinfo.clone(),
152146
});
153147
}
154148
TYPE_VSOCK => {
@@ -162,22 +156,24 @@ impl<'a> Persist<'a> for MMIODeviceManager {
162156
frontend: vsock.save(),
163157
};
164158
states.vsock_device = Some(ConnectedVsockState {
165-
device_id: device_id.clone(),
159+
device_id: devid.clone(),
166160
device_state: vsock_state,
167161
transport_state,
168-
mmio_slot: device_info.clone(),
162+
mmio_slot: devinfo.clone(),
169163
});
170164
}
171165
_ => unreachable!(),
172166
};
173-
}
167+
168+
Ok(())
169+
});
174170
states
175171
}
176172

177173
fn restore(
178174
constructor_args: Self::ConstructorArgs,
179175
state: &Self::State,
180-
) -> std::result::Result<Self, Self::Error> {
176+
) -> Result<Self, Self::Error> {
181177
let mut dev_manager =
182178
MMIODeviceManager::new(arch::MMIO_MEM_START, (arch::IRQ_BASE, arch::IRQ_MAX));
183179
let mem = &constructor_args.mem;

0 commit comments

Comments
 (0)