On Mon, Sep 20, 2010 at 11:41:45AM -0500, Anthony Liguori wrote: > On 09/20/2010 11:30 AM, Michael S. Tsirkin wrote: > >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. > > Having an unclear life cycle really worries me. > > Wouldn't the more correct solution be to avoid removing the netdev > device until after the peer has successfully been removed? > > Regards, > > Anthony Liguori
This is exactly what the patch does. > >Signed-off-by: Michael S. Tsirkin<m...@redhat.com> > >--- > > 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 {