From 071030b7846e765ffa3db1ee10c29552f383cbb3 Mon Sep 17 00:00:00 2001 From: "Yang, Wei" Date: Mon, 13 May 2019 23:01:04 +0800 Subject: [PATCH] shimv2: Close vhostfd after vm get vhostfd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If kata containers is using vfio and vhost net,the unbinding of vfio would be hang. In the scenario, vhost net kernel thread takes a reference to the qemu's mm, and the reference also includes the mmap regions on the vfio device file. so vhost kernel thread would be not released when qemu is killed as the vhost file descriptor still is opened by shim v2 process, and the vfio device is not released because there's still a reference to the mmap. Fixes: #1669 Signed-off-by: Yang, Wei Signed-off-by: Eric Ernst --- virtcontainers/api.go | 2 ++ virtcontainers/network.go | 26 ++++++++++++++++++++++++++ virtcontainers/qemu.go | 1 + virtcontainers/sandbox.go | 5 +++++ 4 files changed, 34 insertions(+) diff --git a/virtcontainers/api.go b/virtcontainers/api.go index cdbfb1ad10..8605b978f4 100644 --- a/virtcontainers/api.go +++ b/virtcontainers/api.go @@ -108,6 +108,8 @@ func createSandboxFromConfig(ctx context.Context, sandboxConfig SandboxConfig, f } }() + s.postCreatedNetwork() + if err = s.getAndStoreGuestDetails(); err != nil { return nil, err } diff --git a/virtcontainers/network.go b/virtcontainers/network.go index ff7dd26935..2f0900a8e7 100644 --- a/virtcontainers/network.go +++ b/virtcontainers/network.go @@ -1437,6 +1437,32 @@ func (n *Network) Add(ctx context.Context, config *NetworkConfig, hypervisor hyp return endpoints, nil } +func (n *Network) PostAdd(ctx context.Context, ns *NetworkNamespace, hotplug bool) error { + if hotplug { + return nil + } + + if ns.Endpoints == nil { + return nil + } + + endpoints := ns.Endpoints + + for _, endpoint := range endpoints { + netPair := endpoint.NetworkPair() + if netPair == nil { + continue + } + if netPair.VhostFds != nil { + for _, VhostFd := range netPair.VhostFds { + VhostFd.Close() + } + } + } + + return nil +} + // Remove network endpoints in the network namespace. It also deletes the network // namespace in case the namespace has been created by us. func (n *Network) Remove(ctx context.Context, ns *NetworkNamespace, hypervisor hypervisor, hotunplug bool) error { diff --git a/virtcontainers/qemu.go b/virtcontainers/qemu.go index 1217dfc32b..c549099026 100644 --- a/virtcontainers/qemu.go +++ b/virtcontainers/qemu.go @@ -1027,6 +1027,7 @@ func (q *qemu) hotAddNetDevice(name, hardAddr string, VMFds, VhostFds []*os.File if err := q.qmpMonitorCh.qmp.ExecuteGetFD(q.qmpMonitorCh.ctx, fdName, VhostFd); err != nil { return err } + VhostFd.Close() VhostFdNames = append(VhostFdNames, fdName) } return q.qmpMonitorCh.qmp.ExecuteNetdevAddByFds(q.qmpMonitorCh.ctx, "tap", name, VMFdNames, VhostFdNames) diff --git a/virtcontainers/sandbox.go b/virtcontainers/sandbox.go index 18ed78c10b..93fa306056 100644 --- a/virtcontainers/sandbox.go +++ b/virtcontainers/sandbox.go @@ -839,6 +839,11 @@ func (s *Sandbox) createNetwork() error { return s.store.Store(store.Network, s.networkNS) } +func (s *Sandbox) postCreatedNetwork() error { + + return s.network.PostAdd(s.ctx, &s.networkNS, s.factory != nil) +} + func (s *Sandbox) removeNetwork() error { span, _ := s.trace("removeNetwork") defer span.Finish()