Subject: host: Show details about the network of SR-IOV VF pool From: Lin Ma lma@suse.com Fri Sep 22 19:39:10 2017 +0800 Date: Mon Oct 9 10:22:48 2017 +0200: Git: 083dfcc8ec9e684052c999b79bb3508a5e9d3c03 Signed-off-by: Lin Ma Signed-off-by: Pavel Hrdina diff --git a/ui/host.ui b/ui/host.ui index 2e5ea496..f5ea3905 100644 --- a/ui/host.ui +++ b/ui/host.ui @@ -1117,6 +1117,108 @@ 3 + + + True + True + + + True + False + vertical + 3 + + + True + False + 5 + 6 + + + True + False + start + label + True + + + 1 + 0 + + + + + True + False + start + Physical Function: + + + 0 + 0 + + + + + False + True + 0 + + + + + True + False + start + Virtual Functions: + True + + + False + True + 1 + + + + + 144 + True + True + in + + + True + True + + + + + + + + True + True + 2 + + + + + + + True + False + <b>_SR-IOV information</b> + True + True + + + + + True + True + 4 + + diff --git a/virtManager/host.py b/virtManager/host.py index 84e8865c..560bc0a6 100644 --- a/virtManager/host.py +++ b/virtManager/host.py @@ -24,6 +24,7 @@ from gi.repository import GObject from gi.repository import Gtk from virtinst import Interface +from virtinst import NodeDevice from virtinst import util from . import uiutil @@ -167,6 +168,20 @@ class vmmHost(vmmGObjectUI): self.widget("net-list").append_column(netCol) netListModel.set_sort_column_id(1, Gtk.SortType.ASCENDING) + # Virtual Function list + # [vf-name] + vf_list = self.widget("vf-list") + vf_list_model = Gtk.ListStore(str) + vf_list.set_model(vf_list_model) + vf_list.set_headers_visible(False) + + vfTextCol = Gtk.TreeViewColumn() + vf_txt = Gtk.CellRendererText() + vfTextCol.pack_start(vf_txt, True) + vfTextCol.add_attribute(vf_txt, 'text', 0) + vf_list.append_column(vfTextCol) + + def init_storage_state(self): self.storagelist = vmmStorageList(self.conn, self.builder, self.topwin) self.widget("storage-align").add(self.storagelist.top_box) @@ -398,6 +413,7 @@ class vmmHost(vmmGObjectUI): return logging.debug("Stopping network '%s'", net.get_name()) + self.widget("vf-list").get_model().clear() vmmAsyncJob.simple_async_noshow(net.stop, [], self, _("Error stopping network '%s'") % net.get_name()) @@ -613,6 +629,35 @@ class vmmHost(vmmGObjectUI): self.widget("qos-outbound-peak").set_text(qos.outbound_peak or "") self.widget("qos-outbound-burst").set_text(qos.outbound_burst or "") + def _populate_sriov_state(self, net): + (is_vf_pool, pf_name, vfs) = net.get_sriov_vf_networks() + + self.widget("net-sriov-expander").set_visible(is_vf_pool) + if not pf_name: + self.widget("pf-name").set_text("N/A") + return + + self.widget("pf-name").set_text(pf_name) + + vf_list_model = self.widget("vf-list").get_model() + vf_list_model.clear() + for vf in vfs: + addrStr = "%x:%x:%x.%x" % (vf.domain, vf.bus, vf.slot, vf.function) + pcidev = NodeDevice.lookupNodedevFromString(self.conn.get_backend(), + addrStr) + + vf_name = None + + netdevs = self.conn.filter_nodedevs("net") + for netdev in netdevs: + logging.debug(netdev.xmlobj.parent) + if pcidev.name == netdev.xmlobj.parent: + vf_name = netdev.xmlobj.interface + break + + vf_list_model.append([vf_name or addrStr]) + + def populate_net_state(self, net): active = net.is_active() @@ -642,6 +687,7 @@ class vmmHost(vmmGObjectUI): self._populate_net_ipv4_state(net) self._populate_net_ipv6_state(net) self._populate_qos_state(net) + self._populate_sriov_state(net) def reset_net_state(self): diff --git a/virtManager/network.py b/virtManager/network.py index cb260497..4c937e0e 100644 --- a/virtManager/network.py +++ b/virtManager/network.py @@ -182,3 +182,15 @@ class vmmNetwork(vmmLibvirtObject): def get_ipv6_network(self): ret = self._get_network("ipv6") return ret + [self._get_static_route("ipv6")] + + def get_sriov_vf_networks(self): + xmlobj = self.get_xmlobj() + pf_name = None + vfs = None + ret = False + if xmlobj.forward.mode == "hostdev": + ret = True + if xmlobj.forward.pf: + pf_name = xmlobj.forward.pf[0].dev + vfs = xmlobj.forward.vfs + return (ret, pf_name, vfs)