[virt-tools-list] [virt-manager PATCH 4/4 v2] network: add support to create SR-IOV VF pool
Cole Robinson
crobinso at redhat.com
Mon Mar 27 21:46:20 UTC 2017
On 03/26/2017 10:22 PM, Lin Ma wrote:
> Create a network with a device pool containing all the VFs of an SR-IOV
> device.
>
I applied patches #1-3, thanks. Please split this into two patches: one with
the test/ and virtinst/ changes, the second with the ui/ and virtManager/
changes since those will take more work.
> Signed-off-by: Lin Ma <lma at suse.com>
> ---
> tests/xmlparse-xml/network-vf-pool-in.xml | 5 +
> tests/xmlparse-xml/network-vf-pool-out.xml | 6 ++
> tests/xmlparse.py | 21 ++++
> ui/createnet.ui | 92 ++++++++++++++++-
> virtManager/createnet.py | 153 ++++++++++++++++++++---------
> virtinst/network.py | 12 +++
> 6 files changed, 240 insertions(+), 49 deletions(-)
> create mode 100644 tests/xmlparse-xml/network-vf-pool-in.xml
> create mode 100644 tests/xmlparse-xml/network-vf-pool-out.xml
>
> diff --git a/virtManager/createnet.py b/virtManager/createnet.py
> index 9fdbc45..2154df1 100644
> --- a/virtManager/createnet.py
> +++ b/virtManager/createnet.py
> @@ -120,6 +120,12 @@ class vmmCreateNetwork(vmmGObjectUI):
> self.widget("header").modify_bg(Gtk.StateType.NORMAL, blue)
>
> # [ label, dev name ]
> + pf_list = self.widget("pf-list")
> + pf_model = Gtk.ListStore(str, str)
> + pf_list.set_model(pf_model)
> + uiutil.init_combo_text_column(pf_list, 0)
> +
> + # [ label, dev name ]
> fw_list = self.widget("net-forward")
> fw_model = Gtk.ListStore(str, str)
> fw_list.set_model(fw_model)
> @@ -167,6 +173,9 @@ class vmmCreateNetwork(vmmGObjectUI):
>
> self.widget("net-enable-ipv6-networking").set_active(False)
>
> + pf_model = self.widget("pf-list").get_model()
> + pf_model.clear()
> +
> fw_model = self.widget("net-forward").get_model()
> fw_model.clear()
> fw_model.append([_("Any physical device"), None])
> @@ -181,6 +190,26 @@ class vmmCreateNetwork(vmmGObjectUI):
> for name in devnames:
> fw_model.append([_("Physical device %s") % name, name])
>
> + devprettynames = []
> + ifnames = []
> + for pcidev in self.conn.filter_nodedevs("pci"):
> + if pcidev.xmlobj.capability_type == "virt_functions":
This is better for indentation:
if pcidev.xmlobj.capability_type != "virt_functions":
continue
[rest of code]
> + devdesc = pcidev.xmlobj.pretty_name()
> + for netdev in self.conn.filter_nodedevs("net"):
> + if pcidev.xmlobj.name == netdev.xmlobj.parent:
> + ifname = netdev.xmlobj.interface
> + devprettyname = "%s (%s)" % (ifname, devdesc)
> + devprettynames.append(devprettyname)
> + ifnames.append(ifname)
> + break
Indentation is weird here. You can use that 'continue' trick as well to reduce
some indentation
Note the example nodedev XML you added to tests/testdriver.xml doesn't hit
this condition, it probably needs a matching <interface> object as well. You
can test the testdriver with ./virt-manager --connect
test://`pwd`/tests/testdriver.xml
> + if not devprettynames:
> + pf_model.append([_("No available device"), None])
> + else:
> + for devprettyname, ifname in zip(devprettynames, ifnames):
> + pf_model.append([_("%s") % devprettyname, ifname])
> +
> + self.widget("pf-list").set_active(0)
> +
> self.widget("net-forward").set_active(0)
> self.widget("net-forward-mode").set_active(0)
> self.widget("net-forward-none").set_active(True)
> @@ -223,6 +252,11 @@ class vmmCreateNetwork(vmmGObjectUI):
> return self._get_network_helper("net-dhcpv6-end")
>
> def get_config_forwarding(self):
> + if self.widget("net-sriov-vfs-pool").get_active():
> + name = uiutil.get_list_selection(self.widget("pf-list"), column=1)
> + mode = "hostdev"
> + return [name, mode]
> +
> if self.widget("net-forward-none").get_active():
> return [None, None]
>
> @@ -481,10 +515,27 @@ class vmmCreateNetwork(vmmGObjectUI):
> self.widget("create-finish").grab_focus()
>
> def change_forward_type(self, ignore):
> - skip_fwd = self.widget("net-forward-none").get_active()
> + index = self.widget("pf-list").get_active()
> + model = self.widget("pf-list").get_model()
> + item = model[index]
> + if item[0] == "No available device":
You can't compare against the text here, since it's marked as translatable.
Instead check for item[1] is None
> + sriov_capable = False
> + else:
> + sriov_capable = True
> + self.widget("net-sriov-vfs-pool").set_sensitive(sriov_capable)
> + vf_pool = self.widget("net-sriov-vfs-pool").get_active()
I don't like naming these widgets 'sriov', it's better IMO to mirror libvirt
naming. So net-forward-mode-hostdev or something like that
> + if not vf_pool:
> + skip_fwd = self.widget("net-forward-none").get_active()
> +
> + self.widget("net-forward-mode").set_sensitive(not skip_fwd)
> + self.widget("net-forward").set_sensitive(not skip_fwd)
> + else:
> + self.widget("net-forward-mode").set_sensitive(False)
> + self.widget("net-forward").set_sensitive(False)
>
> - self.widget("net-forward-mode").set_sensitive(not skip_fwd)
> - self.widget("net-forward").set_sensitive(not skip_fwd)
> + self.widget("table36").set_sensitive(vf_pool)
> + self.widget("box13").set_sensitive(not vf_pool)
> + self.widget("hbox6").set_sensitive(not vf_pool)
>
If you are going to interact with any widgets in code, please give them
readable names in the ui files, not box13 etc.
> def change_ipv4_enable(self, ignore):
> enabled = self.get_config_ipv4_enable()
> @@ -676,56 +727,64 @@ class vmmCreateNetwork(vmmGObjectUI):
> net = self._build_xmlstub()
>
> net.name = self.widget("net-name").get_text()
> - net.domain_name = self.widget("net-domain-name").get_text() or None
> -
> - if self.widget("net-enable-ipv6-networking").get_active():
> - net.ipv6 = True
>
> dev, mode = self.get_config_forwarding()
> if mode:
> net.forward.mode = mode
> net.forward.dev = dev or None
>
> - if self.get_config_ipv4_enable():
> - ip = self.get_config_ip4()
> - ipobj = net.add_ip()
> - ipobj.address = str(ip.network + 1)
> - ipobj.netmask = str(ip.netmask)
> -
> - if self.get_config_dhcpv4_enable():
> - dhcpobj = ipobj.add_range()
> - dhcpobj.start = str(self.get_config_dhcpv4_start().network)
> - dhcpobj.end = str(self.get_config_dhcpv4_end().network)
> -
> - if self.get_config_ipv6_enable():
> - ip = self.get_config_ip6()
> - ipobj = net.add_ip()
> - ipobj.family = "ipv6"
> - ipobj.address = str(ip.network + 1)
> - ipobj.prefix = str(ip.prefixlen)
> -
> - if self.get_config_dhcpv6_enable():
> - dhcpobj = ipobj.add_range()
> - dhcpobj.start = str(self.get_config_dhcpv6_start().network)
> - dhcpobj.end = str(self.get_config_dhcpv6_end().network)
> -
> - netaddr = _make_ipaddr(self.get_config_routev4_network())
> - gwaddr = _make_ipaddr(self.get_config_routev4_gateway())
> - if netaddr and gwaddr:
> - route = net.add_route()
> - route.family = "ipv4"
> - route.address = netaddr.network
> - route.prefix = netaddr.prefixlen
> - route.gateway = gwaddr.network
> -
> - netaddr = _make_ipaddr(self.get_config_routev6_network())
> - gwaddr = _make_ipaddr(self.get_config_routev6_gateway())
> - if netaddr and gwaddr:
> - route = net.add_route()
> - route.family = "ipv6"
> - route.address = netaddr.network
> - route.prefix = netaddr.prefixlen
> - route.gateway = gwaddr.network
> + if net.forward.mode == "hostdev":
> + net.forward.managed = "yes"
> + pfobj = net.forward.add_pf()
> + pfobj.dev = net.forward.dev
> + net.forward.dev = None
> + net.domain_name = None
> + else:
> + net.domain_name = self.widget("net-domain-name").get_text() or None
> +
> + if self.widget("net-enable-ipv6-networking").get_active():
> + net.ipv6 = True
> +
> + if self.get_config_ipv4_enable():
> + ip = self.get_config_ip4()
> + ipobj = net.add_ip()
> + ipobj.address = str(ip.network + 1)
> + ipobj.netmask = str(ip.netmask)
> +
> + if self.get_config_dhcpv4_enable():
> + dhcpobj = ipobj.add_range()
> + dhcpobj.start = str(self.get_config_dhcpv4_start().network)
> + dhcpobj.end = str(self.get_config_dhcpv4_end().network)
> +
> + if self.get_config_ipv6_enable():
> + ip = self.get_config_ip6()
> + ipobj = net.add_ip()
> + ipobj.family = "ipv6"
> + ipobj.address = str(ip.network + 1)
> + ipobj.prefix = str(ip.prefixlen)
> +
> + if self.get_config_dhcpv6_enable():
> + dhcpobj = ipobj.add_range()
> + dhcpobj.start = str(self.get_config_dhcpv6_start().network)
> + dhcpobj.end = str(self.get_config_dhcpv6_end().network)
> +
> + netaddr = _make_ipaddr(self.get_config_routev4_network())
> + gwaddr = _make_ipaddr(self.get_config_routev4_gateway())
> + if netaddr and gwaddr:
> + route = net.add_route()
> + route.family = "ipv4"
> + route.address = netaddr.network
> + route.prefix = netaddr.prefixlen
> + route.gateway = gwaddr.network
> +
> + netaddr = _make_ipaddr(self.get_config_routev6_network())
> + gwaddr = _make_ipaddr(self.get_config_routev6_gateway())
> + if netaddr and gwaddr:
> + route = net.add_route()
> + route.family = "ipv6"
> + route.address = netaddr.network
> + route.prefix = netaddr.prefixlen
> + route.gateway = gwaddr.network
>
Please find a way to avoid indenting all this code. Move it to another
function or find a way to exit the function early in the hostdev case.
Thanks,
Cole
More information about the virt-tools-list
mailing list