Skip to content

Commit 8d6d69c

Browse files
committed
fix: resolve TODO to stop failed virtio devices
Implemented VirtioDevice reset methods to run on failure. Signed-off-by: Aaron Ang <[email protected]>
1 parent 4993d4d commit 8d6d69c

File tree

13 files changed

+136
-17
lines changed

13 files changed

+136
-17
lines changed

src/vmm/src/device_manager/mmio.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,10 @@ pub(crate) mod tests {
545545
fn is_activated(&self) -> bool {
546546
false
547547
}
548+
549+
fn reset(&mut self) -> Option<(Arc<dyn VirtioInterrupt>, Vec<EventFd>)> {
550+
None
551+
}
548552
}
549553

550554
#[test]

src/vmm/src/devices/virtio/balloon/device.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,16 @@ impl VirtioDevice for Balloon {
949949
self.device_state.is_activated()
950950
}
951951

952+
fn reset(&mut self) -> Option<(Arc<dyn VirtioInterrupt>, Vec<EventFd>)> {
953+
let interrupt = self.device_state.active_state()?.interrupt.clone();
954+
let mut queue_evts = Vec::with_capacity(self.queue_evts.len());
955+
for evt in &self.queue_evts {
956+
queue_evts.push(evt.try_clone().ok()?);
957+
}
958+
self.device_state = DeviceState::Inactive;
959+
Some((interrupt, queue_evts))
960+
}
961+
952962
fn kick(&mut self) {
953963
// If device is activated, kick the balloon queue(s) to make up for any
954964
// pending or in-flight epoll events we may have not captured in snapshot.

src/vmm/src/devices/virtio/block/device.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,13 @@ impl VirtioDevice for Block {
209209
}
210210
}
211211

212+
fn reset(&mut self) -> Option<(Arc<dyn VirtioInterrupt>, Vec<EventFd>)> {
213+
match self {
214+
Self::Virtio(b) => b.reset(),
215+
Self::VhostUser(b) => b.reset(),
216+
}
217+
}
218+
212219
fn kick(&mut self) {
213220
// If device is activated, kick the block queue(s) to make up for any
214221
// pending or in-flight epoll events we may have not captured in

src/vmm/src/devices/virtio/block/vhost_user/device.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,16 @@ impl<T: VhostUserHandleBackend + Send + 'static> VirtioDevice for VhostUserBlock
373373
fn is_activated(&self) -> bool {
374374
self.device_state.is_activated()
375375
}
376+
377+
fn reset(&mut self) -> Option<(Arc<dyn VirtioInterrupt>, Vec<EventFd>)> {
378+
let interrupt = self.device_state.active_state()?.interrupt.clone();
379+
let mut queue_evts = Vec::with_capacity(self.queue_evts.len());
380+
for evt in &self.queue_evts {
381+
queue_evts.push(evt.try_clone().ok()?);
382+
}
383+
self.device_state = DeviceState::Inactive;
384+
Some((interrupt, queue_evts))
385+
}
376386
}
377387

378388
#[cfg(test)]

src/vmm/src/devices/virtio/block/virtio/device.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,16 @@ impl VirtioDevice for VirtioBlock {
671671
fn is_activated(&self) -> bool {
672672
self.device_state.is_activated()
673673
}
674+
675+
fn reset(&mut self) -> Option<(Arc<dyn VirtioInterrupt>, Vec<EventFd>)> {
676+
let interrupt = self.device_state.active_state()?.interrupt.clone();
677+
let mut queue_evts = Vec::with_capacity(self.queue_evts.len());
678+
for evt in &self.queue_evts {
679+
queue_evts.push(evt.try_clone().ok()?);
680+
}
681+
self.device_state = DeviceState::Inactive;
682+
Some((interrupt, queue_evts))
683+
}
674684
}
675685

676686
impl Drop for VirtioBlock {

src/vmm/src/devices/virtio/device.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,7 @@ pub trait VirtioDevice: AsAny + Send {
155155

156156
/// Optionally deactivates this device and returns ownership of the guest memory map, interrupt
157157
/// event, and queue events.
158-
fn reset(&mut self) -> Option<(Arc<dyn VirtioInterrupt>, Vec<EventFd>)> {
159-
None
160-
}
158+
fn reset(&mut self) -> Option<(Arc<dyn VirtioInterrupt>, Vec<EventFd>)>;
161159

162160
/// Mark pages used by queues as dirty.
163161
fn mark_queue_memory_dirty(&mut self, mem: &GuestMemoryMmap) -> Result<(), QueueError> {
@@ -254,6 +252,10 @@ pub(crate) mod tests {
254252
fn is_activated(&self) -> bool {
255253
todo!()
256254
}
255+
256+
fn reset(&mut self) -> Option<(Arc<dyn VirtioInterrupt>, Vec<EventFd>)> {
257+
todo!()
258+
}
257259
}
258260

259261
#[test]

src/vmm/src/devices/virtio/mem/device.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,16 @@ impl VirtioDevice for VirtioMem {
658658
self.device_state.is_activated()
659659
}
660660

661+
fn reset(&mut self) -> Option<(Arc<dyn VirtioInterrupt>, Vec<EventFd>)> {
662+
let interrupt = self.device_state.active_state()?.interrupt.clone();
663+
let mut queue_evts = Vec::with_capacity(self.queue_events.len());
664+
for evt in &self.queue_events {
665+
queue_evts.push(evt.try_clone().ok()?);
666+
}
667+
self.device_state = DeviceState::Inactive;
668+
Some((interrupt, queue_evts))
669+
}
670+
661671
fn activate(
662672
&mut self,
663673
mem: GuestMemoryMmap,

src/vmm/src/devices/virtio/net/device.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,16 @@ impl VirtioDevice for Net {
10391039
self.device_state.is_activated()
10401040
}
10411041

1042+
fn reset(&mut self) -> Option<(Arc<dyn VirtioInterrupt>, Vec<EventFd>)> {
1043+
let interrupt = self.device_state.active_state()?.interrupt.clone();
1044+
let mut queue_evts = Vec::with_capacity(self.queue_evts.len());
1045+
for evt in &self.queue_evts {
1046+
queue_evts.push(evt.try_clone().ok()?);
1047+
}
1048+
self.device_state = DeviceState::Inactive;
1049+
Some((interrupt, queue_evts))
1050+
}
1051+
10421052
fn kick(&mut self) {
10431053
// If device is activated, kick the net queue(s) to make up for any
10441054
// pending or in-flight epoll events we may have not captured in snapshot.

src/vmm/src/devices/virtio/pmem/device.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,16 @@ impl VirtioDevice for Pmem {
399399
self.device_state.is_activated()
400400
}
401401

402+
fn reset(&mut self) -> Option<(Arc<dyn VirtioInterrupt>, Vec<EventFd>)> {
403+
let interrupt = self.device_state.active_state()?.interrupt.clone();
404+
let mut queue_evts = Vec::with_capacity(self.queue_events.len());
405+
for evt in &self.queue_events {
406+
queue_evts.push(evt.try_clone().ok()?);
407+
}
408+
self.device_state = DeviceState::Inactive;
409+
Some((interrupt, queue_evts))
410+
}
411+
402412
fn kick(&mut self) {
403413
if self.is_activated() {
404414
info!("kick pmem {}.", self.config.id);

src/vmm/src/devices/virtio/rng/device.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,16 @@ impl VirtioDevice for Entropy {
296296
self.device_state.is_activated()
297297
}
298298

299+
fn reset(&mut self) -> Option<(Arc<dyn VirtioInterrupt>, Vec<EventFd>)> {
300+
let interrupt = self.device_state.active_state()?.interrupt.clone();
301+
let mut queue_evts = Vec::with_capacity(self.queue_events.len());
302+
for evt in &self.queue_events {
303+
queue_evts.push(evt.try_clone().ok()?);
304+
}
305+
self.device_state = DeviceState::Inactive;
306+
Some((interrupt, queue_evts))
307+
}
308+
299309
fn activate(
300310
&mut self,
301311
mem: GuestMemoryMmap,

0 commit comments

Comments
 (0)