qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] net: delay peer host device delete


From: Michael S. Tsirkin
Subject: [Qemu-devel] [PATCH] net: delay peer host device delete
Date: Mon, 20 Sep 2010 18:30:42 +0200
User-agent: Mutt/1.5.20 (2009-12-10)

With -netdev, virtio devices present offload
features to guest, depending on the backend used.
Thus, removing host ntedev peer while guest is
active leads to guest-visible inconsistency and/or crashes.
See e.g. https://bugzilla.redhat.com/show_bug.cgi?id=623735

As a solution, while guest (NIC) peer device exists,
we must prevent the host peer from being deleted.

This patch does this by adding peer_deleted flag in nic state:
if host device is going away while guest device
is around, set this flag and keep host device around
for as long as guest device exists.

Signed-off-by: Michael S. Tsirkin <address@hidden>
---
 net.c |   21 ++++++++++++++++++++-
 net.h |    1 +
 2 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/net.c b/net.c
index 3d0fde7..10855d1 100644
--- a/net.c
+++ b/net.c
@@ -286,12 +286,31 @@ void qemu_del_vlan_client(VLANClientState *vc)
     if (vc->vlan) {
         QTAILQ_REMOVE(&vc->vlan->clients, vc, next);
     } else {
+        /* Even if client will not be deleted yet, remove it from list so it
+         * does not appear in monitor.  */
+        QTAILQ_REMOVE(&non_vlan_clients, vc, next);
+        /* Detect that guest-visible (NIC) peer is active, and delay deletion.
+         * */
+        if (vc->peer && vc->peer->info->type == NET_CLIENT_TYPE_NIC) {
+            NICState *nic = DO_UPCAST(NICState, nc, vc->peer);
+            assert(!nic->peer_deleted);
+            nic->peer_deleted = true;
+            return;
+        }
         if (vc->send_queue) {
             qemu_del_net_queue(vc->send_queue);
         }
-        QTAILQ_REMOVE(&non_vlan_clients, vc, next);
         if (vc->peer) {
             vc->peer->peer = NULL;
+            /* If this is a guest-visible (NIC) device,
+             * and peer has already been removed from monitor,
+             * delete it here. */
+            if (vc->info->type == NET_CLIENT_TYPE_NIC) {
+                NICState *nic = DO_UPCAST(NICState, nc, vc);
+                if (nic->peer_deleted) {
+                    qemu_del_vlan_client(vc->peer);
+                }
+            }
         }
     }
 
diff --git a/net.h b/net.h
index 518cf9c..44c31a9 100644
--- a/net.h
+++ b/net.h
@@ -72,6 +72,7 @@ typedef struct NICState {
     VLANClientState nc;
     NICConf *conf;
     void *opaque;
+    bool peer_deleted;
 } NICState;
 
 struct VLANState {
-- 
1.7.2.2



reply via email to

[Prev in Thread] Current Thread [Next in Thread]