in src/vmm/src/device_manager/persist.rs [259:400]
fn restore(
constructor_args: Self::ConstructorArgs,
state: &Self::State,
) -> Result<Self, Self::Error> {
let mut dev_manager =
MMIODeviceManager::new(arch::MMIO_MEM_START, (arch::IRQ_BASE, arch::IRQ_MAX));
let mem = &constructor_args.mem;
let vm = constructor_args.vm;
#[cfg(target_arch = "aarch64")]
{
for state in &state.legacy_devices {
if state.type_ == DeviceType::Serial {
let serial = crate::builder::setup_serial_device(
constructor_args.event_manager,
Box::new(crate::builder::SerialStdin::get()),
Box::new(std::io::stdout()),
)
.map_err(Error::Legacy)?;
dev_manager
.register_mmio_serial(vm, serial, Some(state.mmio_slot.clone()))
.map_err(Error::DeviceManager)?;
}
if state.type_ == DeviceType::Rtc {
let rtc = crate::builder::setup_rtc_device();
dev_manager
.register_mmio_rtc(rtc, Some(state.mmio_slot.clone()))
.map_err(Error::DeviceManager)?;
}
}
}
let mut restore_helper = |device: Arc<Mutex<dyn VirtioDevice>>,
as_subscriber: Arc<Mutex<dyn MutEventSubscriber>>,
id: &String,
state: &MmioTransportState,
slot: &MMIODeviceInfo,
event_manager: &mut EventManager|
-> Result<(), Self::Error> {
dev_manager
.slot_sanity_check(slot)
.map_err(Error::DeviceManager)?;
let restore_args = MmioTransportConstructorArgs {
mem: mem.clone(),
device,
};
let mmio_transport =
MmioTransport::restore(restore_args, state).map_err(|()| Error::MmioTransport)?;
dev_manager
.register_mmio_virtio(vm, id.clone(), mmio_transport, slot)
.map_err(Error::DeviceManager)?;
event_manager.add_subscriber(as_subscriber);
Ok(())
};
if let Some(balloon_state) = &state.balloon_device {
let device = Arc::new(Mutex::new(
Balloon::restore(
BalloonConstructorArgs { mem: mem.clone() },
&balloon_state.device_state,
)
.map_err(Error::Balloon)?,
));
restore_helper(
device.clone(),
device,
&balloon_state.device_id,
&balloon_state.transport_state,
&balloon_state.mmio_slot,
constructor_args.event_manager,
)?;
}
for block_state in &state.block_devices {
let device = Arc::new(Mutex::new(
Block::restore(
BlockConstructorArgs { mem: mem.clone() },
&block_state.device_state,
)
.map_err(Error::Block)?,
));
restore_helper(
device.clone(),
device,
&block_state.device_id,
&block_state.transport_state,
&block_state.mmio_slot,
constructor_args.event_manager,
)?;
}
for net_state in &state.net_devices {
let device = Arc::new(Mutex::new(
Net::restore(
NetConstructorArgs { mem: mem.clone() },
&net_state.device_state,
)
.map_err(Error::Net)?,
));
restore_helper(
device.clone(),
device,
&net_state.device_id,
&net_state.transport_state,
&net_state.mmio_slot,
constructor_args.event_manager,
)?;
}
if let Some(vsock_state) = &state.vsock_device {
let ctor_args = VsockUdsConstructorArgs {
cid: vsock_state.device_state.frontend.cid,
};
let backend = VsockUnixBackend::restore(ctor_args, &vsock_state.device_state.backend)
.map_err(Error::VsockUnixBackend)?;
let device = Arc::new(Mutex::new(
Vsock::restore(
VsockConstructorArgs {
mem: mem.clone(),
backend,
},
&vsock_state.device_state.frontend,
)
.map_err(Error::Vsock)?,
));
restore_helper(
device.clone(),
device,
&vsock_state.device_id,
&vsock_state.transport_state,
&vsock_state.mmio_slot,
constructor_args.event_manager,
)?;
}
Ok(dev_manager)
}