From 7b44d4dbf2db1460f1f5424fb000c0b40f232d99 Mon Sep 17 00:00:00 2001 From: Peng Tao Date: Fri, 13 Oct 2017 17:27:36 +0800 Subject: [PATCH 1/4] Revert "qemu: cleanup: simplify qmp code" This reverts commit a4e81d7cd7677048c752f2d6a4146260445f08ba. --- hypervisor/qemu/network.go | 49 ++++++++++++++++++++------ hypervisor/qemu/qemu.go | 12 ++++--- hypervisor/qemu/qmp_wrapper_amd64.go | 49 ++++++++++++++++---------- hypervisor/qemu/qmp_wrapper_arm64.go | 45 +++++++++++++---------- hypervisor/qemu/qmp_wrapper_ppc64le.go | 43 ++++++++++++---------- hypervisor/qemu/qmp_wrapper_s390x.go | 38 +++++++++++--------- 6 files changed, 148 insertions(+), 88 deletions(-) diff --git a/hypervisor/qemu/network.go b/hypervisor/qemu/network.go index 9b98f388..dc58f425 100644 --- a/hypervisor/qemu/network.go +++ b/hypervisor/qemu/network.go @@ -4,31 +4,58 @@ package qemu import ( "fmt" + "os" "os/exec" "strings" "syscall" + "unsafe" "github.com/golang/glog" "github.com/hyperhq/runv/hypervisor/network" - "github.com/vishvananda/netlink" ) -func GetTapDevice(device, bridge, options string) error { - la := netlink.NewLinkAttrs() - la.Name = device - tapdev := &netlink.Tuntap{LinkAttrs: la, Mode: syscall.IFF_TAP} +const ( + IFNAMSIZ = 16 + CIFF_TAP = 0x0002 + CIFF_NO_PI = 0x1000 + CIFF_ONE_QUEUE = 0x2000 +) + +type ifReq struct { + Name [IFNAMSIZ]byte + Flags uint16 + pad [0x28 - 0x10 - 2]byte +} - if err := netlink.LinkAdd(tapdev); err != nil { - glog.Errorf("fail to create tap device: %v, %v", device, err) - return err +func GetTapFd(device, bridge, options string) (int, error) { + var ( + req ifReq + errno syscall.Errno + ) + + tapFile, err := os.OpenFile("/dev/net/tun", os.O_RDWR, 0) + if err != nil { + return -1, err } - if err := network.UpAndAddToBridge(device, bridge, options); err != nil { + req.Flags = CIFF_TAP | CIFF_NO_PI | CIFF_ONE_QUEUE + copy(req.Name[:len(req.Name)-1], []byte(device)) + _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, tapFile.Fd(), + uintptr(syscall.TUNSETIFF), + uintptr(unsafe.Pointer(&req))) + if errno != 0 { + tapFile.Close() + return -1, fmt.Errorf("create tap device failed\n") + } + + err = network.UpAndAddToBridge(device, bridge, options) + if err != nil { glog.Errorf("Add to bridge failed %s %s", bridge, device) - return err + tapFile.Close() + return -1, err } - return nil + return int(tapFile.Fd()), nil } func GetVhostUserPort(device, bridge, sockPath, option string) error { diff --git a/hypervisor/qemu/qemu.go b/hypervisor/qemu/qemu.go index 9ff5e6f3..74deaa5e 100644 --- a/hypervisor/qemu/qemu.go +++ b/hypervisor/qemu/qemu.go @@ -260,13 +260,16 @@ func (qc *QemuContext) RemoveDisk(ctx *hypervisor.VmContext, blockInfo *hypervis } func (qc *QemuContext) AddNic(ctx *hypervisor.VmContext, host *hypervisor.HostNicInfo, guest *hypervisor.GuestNicInfo, result chan<- hypervisor.VmEvent) { - waitChan := make(chan hypervisor.VmEvent, 1) - var err error = nil + var ( + fd int = -1 + err error + waitChan chan hypervisor.VmEvent = make(chan hypervisor.VmEvent, 1) + ) if ctx.Boot.EnableVhostUser { err = GetVhostUserPort(host.Device, host.Bridge, ctx.HomeDir, host.Options) } else { - err = GetTapDevice(host.Device, host.Bridge, host.Options) + fd, err = GetTapFd(host.Device, host.Bridge, host.Options) } if err != nil { @@ -280,13 +283,14 @@ func (qc *QemuContext) AddNic(ctx *hypervisor.VmContext, host *hypervisor.HostNi go func() { // close tap file if necessary ev, ok := <-waitChan + syscall.Close(fd) if !ok { close(result) } else { result <- ev } }() - newNetworkAddSession(ctx, qc, host, guest, waitChan) + newNetworkAddSession(ctx, qc, host.Id, host.Device, fd, guest.Device, host.Mac, guest.Index, guest.Busaddr, waitChan) } func (qc *QemuContext) RemoveNic(ctx *hypervisor.VmContext, n *hypervisor.InterfaceCreated, callback hypervisor.VmEvent, result chan<- hypervisor.VmEvent) { diff --git a/hypervisor/qemu/qmp_wrapper_amd64.go b/hypervisor/qemu/qmp_wrapper_amd64.go index c5b3b986..59223a9b 100644 --- a/hypervisor/qemu/qmp_wrapper_amd64.go +++ b/hypervisor/qemu/qmp_wrapper_amd64.go @@ -4,15 +4,17 @@ package qemu import ( "fmt" + "syscall" + "github.com/golang/glog" "github.com/hyperhq/runv/hypervisor" ) -func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, host *hypervisor.HostNicInfo, guest *hypervisor.GuestNicInfo, result chan<- hypervisor.VmEvent) { - busAddr := fmt.Sprintf("0x%x", guest.Busaddr) +func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, id, tapname string, fd int, device, mac string, index, addr int, result chan<- hypervisor.VmEvent) { + busAddr := fmt.Sprintf("0x%x", addr) commands := []*QmpCommand{} if ctx.Boot.EnableVhostUser { - chardevId := guest.Device + "-chardev" + chardevId := device + "-chardev" commands = append(commands, &QmpCommand{ Execute: "chardev-add", Arguments: map[string]interface{}{ @@ -23,7 +25,7 @@ func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, host *hype "addr": map[string]interface{}{ "type": "unix", "data": map[string]interface{}{ - "path": ctx.HomeDir + "/" + host.Id, + "path": ctx.HomeDir + "/" + id, }, }, "wait": false, @@ -35,20 +37,31 @@ func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, host *hype Execute: "netdev_add", Arguments: map[string]interface{}{ "type": "vhost-user", - "id": guest.Device, + "id": device, "chardev": chardevId, "vhostforce": true, }, }) - } else { + } else if fd > 0 { + scm := syscall.UnixRights(fd) + glog.V(1).Infof("send net to qemu at %d", fd) + commands = append(commands, &QmpCommand{ + Execute: "getfd", + Arguments: map[string]interface{}{ + "fdname": "fd" + device, + }, + Scm: scm, + }, &QmpCommand{ + Execute: "netdev_add", + Arguments: map[string]interface{}{ + "type": "tap", "id": device, "fd": "fd" + device, + }, + }) + } else if tapname != "" { commands = append(commands, &QmpCommand{ Execute: "netdev_add", Arguments: map[string]interface{}{ - "type": "tap", - "script": "no", - "id": guest.Device, - "ifname": host.Device, - "br": host.Bridge, + "type": "tap", "id": device, "ifname": tapname, "script": "no", }, }) } @@ -56,21 +69,21 @@ func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, host *hype Execute: "device_add", Arguments: map[string]interface{}{ "driver": "virtio-net-pci", - "netdev": guest.Device, - "mac": host.Mac, + "netdev": device, + "mac": mac, "bus": "pci.0", "addr": busAddr, - "id": guest.Device, + "id": device, }, }) qc.qmp <- &QmpSession{ commands: commands, respond: defaultRespond(result, &hypervisor.NetDevInsertedEvent{ - Id: host.Id, - Index: guest.Index, - DeviceName: guest.Device, - Address: guest.Busaddr, + Id: id, + Index: index, + DeviceName: device, + Address: addr, }), } } diff --git a/hypervisor/qemu/qmp_wrapper_arm64.go b/hypervisor/qemu/qmp_wrapper_arm64.go index 79b83d8b..a1f86d79 100644 --- a/hypervisor/qemu/qmp_wrapper_arm64.go +++ b/hypervisor/qemu/qmp_wrapper_arm64.go @@ -4,44 +4,51 @@ package qemu import ( "fmt" + "syscall" + "github.com/golang/glog" "github.com/hyperhq/runv/hypervisor" ) -func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, host *hypervisor.HostNicInfo, guest *hypervisor.GuestNicInfo, result chan<- hypervisor.VmEvent) { - busAddr := fmt.Sprintf("0x%x", guest.Busaddr) - commands := []*QmpCommand{} - commands = append(commands, &QmpCommand{ +func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, id string, fd int, device, mac string, index, addr int, result chan<- hypervisor.VmEvent) { + busAddr := fmt.Sprintf("0x%x", addr) + commands := make([]*QmpCommand, 3) + scm := syscall.UnixRights(fd) + glog.V(1).Infof("send net to qemu at %d", fd) + commands[0] = &QmpCommand{ + Execute: "getfd", + Arguments: map[string]interface{}{ + "fdname": "fd" + device, + }, + Scm: scm, + } + commands[1] = &QmpCommand{ Execute: "netdev_add", Arguments: map[string]interface{}{ - "type": "tap", - "script": "no", - "id": guest.Device, - "ifname": host.Device, - "br": host.Bridge, + "type": "tap", "id": device, "fd": "fd" + device, }, - }) - commands = append(commands, &QmpCommand{ + } + commands[2] = &QmpCommand{ Execute: "device_add", Arguments: map[string]interface{}{ - "netdev": guest.Device, + "netdev": device, "driver": "virtio-net-pci", "disable-modern": "off", "disable-legacy": "on", "bus": "pci.0", "addr": busAddr, - "mac": host.Mac, - "id": guest.Device, + "mac": mac, + "id": device, }, - }) + } qc.qmp <- &QmpSession{ commands: commands, respond: defaultRespond(result, &hypervisor.NetDevInsertedEvent{ - Id: host.Id, - Index: guest.Index, - DeviceName: guest.Device, - Address: guest.Busaddr, + Id: id, + Index: index, + DeviceName: device, + Address: addr, }), } } diff --git a/hypervisor/qemu/qmp_wrapper_ppc64le.go b/hypervisor/qemu/qmp_wrapper_ppc64le.go index e02e03fd..e27cbb6e 100644 --- a/hypervisor/qemu/qmp_wrapper_ppc64le.go +++ b/hypervisor/qemu/qmp_wrapper_ppc64le.go @@ -10,38 +10,43 @@ import ( "github.com/hyperhq/runv/hypervisor" ) -func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, qc *QemuContext, host *hypervisor.HostNicInfo, guest *hypervisor.GuestNicInfo, result chan<- hypervisor.VmEvent) { - busAddr := fmt.Sprintf("0x%x", guest.Busaddr) - commands := []*QmpCommand{} - commands = append(commands, &QmpCommand{ +func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, id string, fd int, device, mac string, index, addr int, result chan<- hypervisor.VmEvent) { + busAddr := fmt.Sprintf("0x%x", addr) + commands := make([]*QmpCommand, 3) + scm := syscall.UnixRights(fd) + glog.V(1).Infof("send net to qemu at %d", fd) + commands[0] = &QmpCommand{ + Execute: "getfd", + Arguments: map[string]interface{}{ + "fdname": "fd" + device, + }, + Scm: scm, + } + commands[1] = &QmpCommand{ Execute: "netdev_add", Arguments: map[string]interface{}{ - "type": "tap", - "script": "no", - "id": guest.Device, - "ifname": host.Device, - "br": host.Bridge, + "type": "tap", "id": device, "fd": "fd" + device, }, - }) - commands = append(commands, &QmpCommand{ + } + commands[2] = &QmpCommand{ Execute: "device_add", Arguments: map[string]interface{}{ "driver": "virtio-net-pci", - "netdev": guest.Device, - "mac": host.Mac, + "netdev": device, + "mac": mac, "bus": "pci.0", "addr": busAddr, - "id": guest.Device, + "id": device, }, - }) + } qc.qmp <- &QmpSession{ commands: commands, respond: defaultRespond(result, &hypervisor.NetDevInsertedEvent{ - Id: host.Id, - Index: guest.Index, - DeviceName: guest.Device, - Address: guest.Busaddr, + Id: id, + Index: index, + DeviceName: device, + Address: addr, }), } } diff --git a/hypervisor/qemu/qmp_wrapper_s390x.go b/hypervisor/qemu/qmp_wrapper_s390x.go index c36890f8..6ab27fe0 100644 --- a/hypervisor/qemu/qmp_wrapper_s390x.go +++ b/hypervisor/qemu/qmp_wrapper_s390x.go @@ -10,35 +10,39 @@ import ( ) func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, id string, fd int, device, mac string, index, addr int, result chan<- hypervisor.VmEvent) { - commands := []*QmpCommand{} + commands := make([]*QmpCommand, 3) scm := syscall.UnixRights(fd) - commands = appends(commands, &QmpCommand{ + glog.V(1).Infof("send net to qemu at %d", fd) + commands[0] = &QmpCommand{ + Execute: "getfd", + Arguments: map[string]interface{}{ + "fdname": "fd" + device, + }, + Scm: scm, + } + commands[1] = &QmpCommand{ Execute: "netdev_add", Arguments: map[string]interface{}{ - "type": "tap", - "script": "no", - "id": guest.Device, - "ifname": host.Device, - "br": host.Bridge, + "type": "tap", "id": device, "fd": "fd" + device, }, - }) - commands = append(commands, &QmpCommand{ + } + commands[2] = &QmpCommand{ Execute: "device_add", Arguments: map[string]interface{}{ "driver": "virtio-net-ccw", - "netdev": guest.Device, - "mac": host.Mac, - "id": guest.Device, + "netdev": device, + "mac": mac, + "id": device, }, - }) + } qc.qmp <- &QmpSession{ commands: commands, respond: defaultRespond(result, &hypervisor.NetDevInsertedEvent{ - Id: host.Id, - Index: guest.Index, - DeviceName: guest.Device, - Address: guest.Busaddr, + Id: id, + Index: index, + DeviceName: device, + Address: addr, }), } } From 54ad40779be4c3e1789f79385ab6e14b4c3881d5 Mon Sep 17 00:00:00 2001 From: Peng Tao Date: Fri, 13 Oct 2017 17:56:16 +0800 Subject: [PATCH 2/4] qemu: clean up newNetworkAddSession This is part of a4e81d7cd7677048c752f2d6a4146260445f08ba ("qemu: cleanup: simplify qmp code"). Signed-off-by: Gao feng Signed-off-by: Peng Tao --- hypervisor/qemu/qemu.go | 2 +- hypervisor/qemu/qmp_wrapper_amd64.go | 32 +++++++++++++------------- hypervisor/qemu/qmp_wrapper_arm64.go | 22 +++++++++--------- hypervisor/qemu/qmp_wrapper_ppc64le.go | 22 +++++++++--------- hypervisor/qemu/qmp_wrapper_s390x.go | 20 ++++++++-------- 5 files changed, 49 insertions(+), 49 deletions(-) diff --git a/hypervisor/qemu/qemu.go b/hypervisor/qemu/qemu.go index 74deaa5e..4fe51fc4 100644 --- a/hypervisor/qemu/qemu.go +++ b/hypervisor/qemu/qemu.go @@ -290,7 +290,7 @@ func (qc *QemuContext) AddNic(ctx *hypervisor.VmContext, host *hypervisor.HostNi result <- ev } }() - newNetworkAddSession(ctx, qc, host.Id, host.Device, fd, guest.Device, host.Mac, guest.Index, guest.Busaddr, waitChan) + newNetworkAddSession(ctx, qc, fd, host, guest, waitChan) } func (qc *QemuContext) RemoveNic(ctx *hypervisor.VmContext, n *hypervisor.InterfaceCreated, callback hypervisor.VmEvent, result chan<- hypervisor.VmEvent) { diff --git a/hypervisor/qemu/qmp_wrapper_amd64.go b/hypervisor/qemu/qmp_wrapper_amd64.go index 59223a9b..8b0ad18b 100644 --- a/hypervisor/qemu/qmp_wrapper_amd64.go +++ b/hypervisor/qemu/qmp_wrapper_amd64.go @@ -10,11 +10,11 @@ import ( "github.com/hyperhq/runv/hypervisor" ) -func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, id, tapname string, fd int, device, mac string, index, addr int, result chan<- hypervisor.VmEvent) { - busAddr := fmt.Sprintf("0x%x", addr) +func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, fd int, host *hypervisor.HostNicInfo, guest *hypervisor.GuestNicInfo, result chan<- hypervisor.VmEvent) { + busAddr := fmt.Sprintf("0x%x", guest.Busaddr) commands := []*QmpCommand{} if ctx.Boot.EnableVhostUser { - chardevId := device + "-chardev" + chardevId := guest.Device + "-chardev" commands = append(commands, &QmpCommand{ Execute: "chardev-add", Arguments: map[string]interface{}{ @@ -25,7 +25,7 @@ func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, id, tapnam "addr": map[string]interface{}{ "type": "unix", "data": map[string]interface{}{ - "path": ctx.HomeDir + "/" + id, + "path": ctx.HomeDir + "/" + host.Id, }, }, "wait": false, @@ -37,7 +37,7 @@ func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, id, tapnam Execute: "netdev_add", Arguments: map[string]interface{}{ "type": "vhost-user", - "id": device, + "id": guest.Device, "chardev": chardevId, "vhostforce": true, }, @@ -48,20 +48,20 @@ func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, id, tapnam commands = append(commands, &QmpCommand{ Execute: "getfd", Arguments: map[string]interface{}{ - "fdname": "fd" + device, + "fdname": "fd" + guest.Device, }, Scm: scm, }, &QmpCommand{ Execute: "netdev_add", Arguments: map[string]interface{}{ - "type": "tap", "id": device, "fd": "fd" + device, + "type": "tap", "id": guest.Device, "fd": "fd" + guest.Device, }, }) - } else if tapname != "" { + } else if host.Device != "" { commands = append(commands, &QmpCommand{ Execute: "netdev_add", Arguments: map[string]interface{}{ - "type": "tap", "id": device, "ifname": tapname, "script": "no", + "type": "tap", "id": guest.Device, "ifname": host.Device, "script": "no", }, }) } @@ -69,21 +69,21 @@ func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, id, tapnam Execute: "device_add", Arguments: map[string]interface{}{ "driver": "virtio-net-pci", - "netdev": device, - "mac": mac, + "netdev": guest.Device, + "mac": host.Mac, "bus": "pci.0", "addr": busAddr, - "id": device, + "id": guest.Device, }, }) qc.qmp <- &QmpSession{ commands: commands, respond: defaultRespond(result, &hypervisor.NetDevInsertedEvent{ - Id: id, - Index: index, - DeviceName: device, - Address: addr, + Id: host.Id, + Index: guest.Index, + DeviceName: guest.Device, + Address: guest.Busaddr, }), } } diff --git a/hypervisor/qemu/qmp_wrapper_arm64.go b/hypervisor/qemu/qmp_wrapper_arm64.go index a1f86d79..74ebaa3d 100644 --- a/hypervisor/qemu/qmp_wrapper_arm64.go +++ b/hypervisor/qemu/qmp_wrapper_arm64.go @@ -10,45 +10,45 @@ import ( "github.com/hyperhq/runv/hypervisor" ) -func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, id string, fd int, device, mac string, index, addr int, result chan<- hypervisor.VmEvent) { - busAddr := fmt.Sprintf("0x%x", addr) +func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, fd int, host *hypervisor.HostNicInfo, guest *hypervisor.GuestNicInfo, result chan<- hypervisor.VmEvent) { + busAddr := fmt.Sprintf("0x%x", guest.Busaddr) commands := make([]*QmpCommand, 3) scm := syscall.UnixRights(fd) glog.V(1).Infof("send net to qemu at %d", fd) commands[0] = &QmpCommand{ Execute: "getfd", Arguments: map[string]interface{}{ - "fdname": "fd" + device, + "fdname": "fd" + guest.Device, }, Scm: scm, } commands[1] = &QmpCommand{ Execute: "netdev_add", Arguments: map[string]interface{}{ - "type": "tap", "id": device, "fd": "fd" + device, + "type": "tap", "id": guest.Device, "fd": "fd" + guest.Device, }, } commands[2] = &QmpCommand{ Execute: "device_add", Arguments: map[string]interface{}{ - "netdev": device, + "netdev": guest.Device, "driver": "virtio-net-pci", "disable-modern": "off", "disable-legacy": "on", "bus": "pci.0", "addr": busAddr, - "mac": mac, - "id": device, + "mac": host.Mac, + "id": guest.Device, }, } qc.qmp <- &QmpSession{ commands: commands, respond: defaultRespond(result, &hypervisor.NetDevInsertedEvent{ - Id: id, - Index: index, - DeviceName: device, - Address: addr, + Id: host.Id, + Index: guest.Index, + DeviceName: guest.Device, + Address: guest.Busaddr, }), } } diff --git a/hypervisor/qemu/qmp_wrapper_ppc64le.go b/hypervisor/qemu/qmp_wrapper_ppc64le.go index e27cbb6e..6b82db9e 100644 --- a/hypervisor/qemu/qmp_wrapper_ppc64le.go +++ b/hypervisor/qemu/qmp_wrapper_ppc64le.go @@ -10,43 +10,43 @@ import ( "github.com/hyperhq/runv/hypervisor" ) -func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, id string, fd int, device, mac string, index, addr int, result chan<- hypervisor.VmEvent) { - busAddr := fmt.Sprintf("0x%x", addr) +func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, fd int, host *hypervisor.HostNicInfo, guest *hypervisor.GuestNicInfo, result chan<- hypervisor.VmEvent) { + busAddr := fmt.Sprintf("0x%x", guest.Busaddr) commands := make([]*QmpCommand, 3) scm := syscall.UnixRights(fd) glog.V(1).Infof("send net to qemu at %d", fd) commands[0] = &QmpCommand{ Execute: "getfd", Arguments: map[string]interface{}{ - "fdname": "fd" + device, + "fdname": "fd" + guest.Device, }, Scm: scm, } commands[1] = &QmpCommand{ Execute: "netdev_add", Arguments: map[string]interface{}{ - "type": "tap", "id": device, "fd": "fd" + device, + "type": "tap", "id": guest.Device, "fd": "fd" + guest.Device, }, } commands[2] = &QmpCommand{ Execute: "device_add", Arguments: map[string]interface{}{ "driver": "virtio-net-pci", - "netdev": device, - "mac": mac, + "netdev": guest.Device, + "mac": host.Mac, "bus": "pci.0", "addr": busAddr, - "id": device, + "id": guest.Device, }, } qc.qmp <- &QmpSession{ commands: commands, respond: defaultRespond(result, &hypervisor.NetDevInsertedEvent{ - Id: id, - Index: index, - DeviceName: device, - Address: addr, + Id: host.Id, + Index: guest.Index, + DeviceName: guest.Device, + Address: guest.Busaddr, }), } } diff --git a/hypervisor/qemu/qmp_wrapper_s390x.go b/hypervisor/qemu/qmp_wrapper_s390x.go index 6ab27fe0..b9436ae4 100644 --- a/hypervisor/qemu/qmp_wrapper_s390x.go +++ b/hypervisor/qemu/qmp_wrapper_s390x.go @@ -9,40 +9,40 @@ import ( "github.com/hyperhq/runv/hypervisor" ) -func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, id string, fd int, device, mac string, index, addr int, result chan<- hypervisor.VmEvent) { +func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, fd int, host *hypervisor.HostNicInfo, guest *hypervisor.GuestNicInfo, result chan<- hypervisor.VmEvent) { commands := make([]*QmpCommand, 3) scm := syscall.UnixRights(fd) glog.V(1).Infof("send net to qemu at %d", fd) commands[0] = &QmpCommand{ Execute: "getfd", Arguments: map[string]interface{}{ - "fdname": "fd" + device, + "fdname": "fd" + guest.Device, }, Scm: scm, } commands[1] = &QmpCommand{ Execute: "netdev_add", Arguments: map[string]interface{}{ - "type": "tap", "id": device, "fd": "fd" + device, + "type": "tap", "id": guest.Device, "fd": "fd" + guest.Device, }, } commands[2] = &QmpCommand{ Execute: "device_add", Arguments: map[string]interface{}{ "driver": "virtio-net-ccw", - "netdev": device, - "mac": mac, - "id": device, + "netdev": guest.Device, + "mac": host.Mac, + "id": guest.Device, }, } qc.qmp <- &QmpSession{ commands: commands, respond: defaultRespond(result, &hypervisor.NetDevInsertedEvent{ - Id: id, - Index: index, - DeviceName: device, - Address: addr, + Id: host.Id, + Index: guest.Index, + DeviceName: guest.Device, + Address: guest.Busaddr, }), } } From 8292ffb747252f197dbcfc217a3ad89b8d275913 Mon Sep 17 00:00:00 2001 From: Peng Tao Date: Fri, 13 Oct 2017 17:58:03 +0800 Subject: [PATCH 3/4] qemu: only close tap fd on addnic failure It causes various bizarre CI failures mostly pulling image failures. Signed-off-by: Peng Tao --- hypervisor/qemu/qemu.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hypervisor/qemu/qemu.go b/hypervisor/qemu/qemu.go index 4fe51fc4..7705a0a6 100644 --- a/hypervisor/qemu/qemu.go +++ b/hypervisor/qemu/qemu.go @@ -283,10 +283,13 @@ func (qc *QemuContext) AddNic(ctx *hypervisor.VmContext, host *hypervisor.HostNi go func() { // close tap file if necessary ev, ok := <-waitChan - syscall.Close(fd) if !ok { + syscall.Close(fd) close(result) } else { + if _, ok := ev.(*hypervisor.DeviceFailed); ok { + syscall.Close(fd) + } result <- ev } }() From 7ec7d7b05053d71f6c4a8cdd94fa911cc28832b9 Mon Sep 17 00:00:00 2001 From: Peng Tao Date: Fri, 13 Oct 2017 19:16:23 +0800 Subject: [PATCH 4/4] qemu: close tap fd properly Still need to pass tap fd around to keep it open until nic is removed. Signed-off-by: Peng Tao --- hypervisor/events.go | 2 ++ hypervisor/network.go | 2 ++ hypervisor/qemu/qemu.go | 1 + hypervisor/qemu/qmp_wrapper_amd64.go | 1 + hypervisor/qemu/qmp_wrapper_arm64.go | 1 + hypervisor/qemu/qmp_wrapper_ppc64le.go | 1 + hypervisor/qemu/qmp_wrapper_s390x.go | 1 + 7 files changed, 9 insertions(+) diff --git a/hypervisor/events.go b/hypervisor/events.go index e8a2f3a8..2302b257 100644 --- a/hypervisor/events.go +++ b/hypervisor/events.go @@ -52,6 +52,7 @@ type InterfaceCreated struct { Id string //user specified in (ref api.InterfaceDescription: a user identifier of interface, user may use this to specify a nic, normally you can use IPAddr as an Id.) Index int PCIAddr int + TapFd int Bridge string HostDevice string DeviceName string @@ -73,6 +74,7 @@ type NetDevInsertedEvent struct { Index int DeviceName string Address int + TapFd int } func (ne *NetDevInsertedEvent) ResultId() string { diff --git a/hypervisor/network.go b/hypervisor/network.go index c7860666..bf07a936 100644 --- a/hypervisor/network.go +++ b/hypervisor/network.go @@ -173,6 +173,8 @@ func (nc *NetworkContext) addInterface(inf *api.InterfaceDescription, result cha result <- fe return } else if ni, ok := ev.(*NetDevInsertedEvent); ok { + created := nc.idMap[inf.Id] + created.TapFd = ni.TapFd nc.sandbox.Log(DEBUG, "nic insert success: %s", ni.Id) result <- ni return diff --git a/hypervisor/qemu/qemu.go b/hypervisor/qemu/qemu.go index 7705a0a6..9b71c84a 100644 --- a/hypervisor/qemu/qemu.go +++ b/hypervisor/qemu/qemu.go @@ -297,6 +297,7 @@ func (qc *QemuContext) AddNic(ctx *hypervisor.VmContext, host *hypervisor.HostNi } func (qc *QemuContext) RemoveNic(ctx *hypervisor.VmContext, n *hypervisor.InterfaceCreated, callback hypervisor.VmEvent, result chan<- hypervisor.VmEvent) { + syscall.Close(n.TapFd) newNetworkDelSession(ctx, qc, n.NewName, callback, result) } diff --git a/hypervisor/qemu/qmp_wrapper_amd64.go b/hypervisor/qemu/qmp_wrapper_amd64.go index 8b0ad18b..bf840566 100644 --- a/hypervisor/qemu/qmp_wrapper_amd64.go +++ b/hypervisor/qemu/qmp_wrapper_amd64.go @@ -84,6 +84,7 @@ func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, fd int, ho Index: guest.Index, DeviceName: guest.Device, Address: guest.Busaddr, + TapFd: fd, }), } } diff --git a/hypervisor/qemu/qmp_wrapper_arm64.go b/hypervisor/qemu/qmp_wrapper_arm64.go index 74ebaa3d..a713da66 100644 --- a/hypervisor/qemu/qmp_wrapper_arm64.go +++ b/hypervisor/qemu/qmp_wrapper_arm64.go @@ -49,6 +49,7 @@ func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, fd int, ho Index: guest.Index, DeviceName: guest.Device, Address: guest.Busaddr, + TapFd: fd, }), } } diff --git a/hypervisor/qemu/qmp_wrapper_ppc64le.go b/hypervisor/qemu/qmp_wrapper_ppc64le.go index 6b82db9e..749e8081 100644 --- a/hypervisor/qemu/qmp_wrapper_ppc64le.go +++ b/hypervisor/qemu/qmp_wrapper_ppc64le.go @@ -47,6 +47,7 @@ func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, fd int, ho Index: guest.Index, DeviceName: guest.Device, Address: guest.Busaddr, + TapFd: fd, }), } } diff --git a/hypervisor/qemu/qmp_wrapper_s390x.go b/hypervisor/qemu/qmp_wrapper_s390x.go index b9436ae4..63c0c513 100644 --- a/hypervisor/qemu/qmp_wrapper_s390x.go +++ b/hypervisor/qemu/qmp_wrapper_s390x.go @@ -43,6 +43,7 @@ func newNetworkAddSession(ctx *hypervisor.VmContext, qc *QemuContext, fd int, ho Index: guest.Index, DeviceName: guest.Device, Address: guest.Busaddr, + TapFd: fd, }), } }