From ea2c4cb7831aaa7a98f7d3d7379f6262bbbf2153 Mon Sep 17 00:00:00 2001
From: zhouli57 <zhouli57@huawei.com>
Date: Tue, 22 Feb 2022 10:51:40 +0800
Subject: [PATCH 07/10] net: fix the bug when tap is abnormally removed

If the backend tap device is removed, readv returns less than 0.
At this time, the content in the tap needs to be cleaned up.
Here, read is called to process, otherwise handle_rx may be triggered
all the time, resulting in an infinite loop.

Signed-off-by: zhouli57 <zhouli57@huawei.com>
---
 virtio/src/net.rs | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/virtio/src/net.rs b/virtio/src/net.rs
index bbb1cc7..69ecc36 100644
--- a/virtio/src/net.rs
+++ b/virtio/src/net.rs
@@ -149,6 +149,18 @@ impl NetIoHandler {
                 if e.kind() == std::io::ErrorKind::WouldBlock {
                     break;
                 }
+
+                // If the backend tap device is removed, readv returns less than 0.
+                // At this time, the content in the tap needs to be cleaned up.
+                // Here, read is called to process, otherwise handle_rx may be triggered all the time.
+                let mut buf = [0; 1024];
+                match tap.read(&mut buf) {
+                    Ok(cnt) => error!("Failed to call readv but tap read is ok: cnt {}", cnt),
+                    Err(e) => {
+                        // When the backend tap device is abnormally removed, read return EBADFD.
+                        error!("Failed to read tap: {}", e);
+                    }
+                }
                 bail!("Failed to call readv for net handle_rx: {}", e);
             }
 
@@ -446,7 +458,7 @@ impl EventNotifierHelper for NetIoHandler {
                 tap_fd,
                 Some(handler),
                 NotifierOperation::AddShared,
-                EventSet::IN,
+                EventSet::IN | EventSet::EDGE_TRIGGERED,
             ));
         }
 
-- 
2.25.1

