[et-mgmt-tools] [PATCH] The bridge of bonding and the tag VLAN isnot displayed in virt-manager
Daniel P. Berrange
berrange at redhat.com
Fri Feb 15 18:25:49 UTC 2008
On Fri, Feb 08, 2008 at 05:31:42PM +0900, S.Sakamoto wrote:
> > > virt-manager can display only the bridge of the physics network device now
> > > when add a device and make a guest domain newly.
> > > A bridge of bonding and Tag VLAN is not displayed.
> > >
> > > So, I make the patch that a bridge of bonding and Tag VLAN came to be displayed.
> > > Do not getout from processing specific linux...
> > > but can use a bridge of bonding and the tag VLAN.
> >
> > I'd definitely welcome code to deal with VLANs - and we're already Linux
> > specific in this code, so that's not a problem.
> >
> > We can't use the 'rhpl*' python libraries though - these are Red Hat
> > specific libraries, so if we use them, virt-manager won't be able to run
> > on Debian/SUSE/etc
> >
> > If you can adapt the code to remove use of 'import rhpl' then that'd be
> > good.
>
> I remake the patch to remove use of 'import rhpl'.
After much testing on some horrible different networking configs, here is
an updated patch which I think should work correctly.
- Instead of using /etc/modprobe.conf, it reads /sys/class/net/bonding_masters
to get an accurate list of bonding devices
- It doesn't use the HAL linux.sysfs_path patch when looking for VLANs
because that is /sys/devices/pci0000:00/0000:00:1e.0/0000:01:00.0/net/eth0
but the VLANs are only visible under /sys/class/net/eth0.*
- It filters out any physical devices that are part of a bonding master
so they don't appear in the list twice
I've tested with:
- eth0 as bridge, and peth0 as physical device
- br0 as bridge and eth0 as physical device
- bond0 with eth0 as slave, and brbond0 as bridge
- eth0.5 vlan with breth05 as bridge
Which I think covers the use cases your patch was trying to address.
The algorithm it uses is thus:
- Find all bonding master devices
- Add them to netdev list
- Mark shared if in a bridge
- Find all physical devices from HAL
- Skip if a slave in a bonding device
- Check if renamed from ethN -> pethN
- Add them to netdev list
- Mark shared if in a bridge
- For all VLANs associated with physical device
- Add them to netdev list
- Mark shared if in a bridge
Let me know if this patch shows the correct lists for you - if not the
/root/.virt-manager/virt-manager.log file should contain useful debug
output
diff -r 1892867ca5c7 src/virtManager/connection.py
--- a/src/virtManager/connection.py Thu Jan 31 11:39:10 2008 -0500
+++ b/src/virtManager/connection.py Fri Feb 15 13:18:56 2008 -0500
@@ -22,6 +22,7 @@ import libvirt
import libvirt
import logging
import os, sys
+import glob
import traceback
from time import time
import logging
@@ -29,6 +30,7 @@ import dbus
import dbus
import threading
import gtk
+import string
from virtManager.domain import vmmDomain
from virtManager.network import vmmNetwork
@@ -134,9 +136,7 @@ class vmmConnection(gobject.GObject):
self.record = []
self.hostinfo = None
- self.detect_network_devices()
-
- def detect_network_devices(self):
+ # Probe for network devices
try:
# Get a connection to the SYSTEM bus
self.bus = dbus.SystemBus()
@@ -145,12 +145,21 @@ class vmmConnection(gobject.GObject):
self.hal_iface = dbus.Interface(hal_object, 'org.freedesktop.Hal.Manager')
# Track device add/removes so we can detect newly inserted CD media
- self.hal_iface.connect_to_signal("DeviceAdded", self._device_added)
- self.hal_iface.connect_to_signal("DeviceRemoved", self._device_removed)
-
- # Find info about all current present media
+ self.hal_iface.connect_to_signal("DeviceAdded", self._net_phys_device_added)
+ self.hal_iface.connect_to_signal("DeviceRemoved", self._net_phys_device_removed)
+
+ # find all bonding master devices and register them
+ # XXX bonding stuff is linux specific
+ bondMasters = self._net_get_bonding_masters()
+ for bond in bondMasters:
+ sysfspath = "/sys/class/net/" + bond
+ mac = self._net_get_mac_address(bond, sysfspath)
+ self._net_device_added(bond, mac, sysfspath)
+
+ # Find info about all current present physical net devices
+ # This is OS portable...
for path in self.hal_iface.FindDeviceByCapability("net"):
- self._device_added(path)
+ self._net_phys_device_added(path)
except:
(type, value, stacktrace) = sys.exc_info ()
logging.error("Unable to connect to HAL to list network devices: '%s'" + \
@@ -159,56 +168,70 @@ class vmmConnection(gobject.GObject):
self.bus = None
self.hal_iface = None
- def _device_added(self, path):
+ def _net_phys_device_added(self, path):
+ logging.debug("Got physical device %s" % path)
obj = self.bus.get_object("org.freedesktop.Hal", path)
if obj.QueryCapability("net"):
name = obj.GetPropertyString("net.interface")
+ # XXX ...but this is Linux specific again - patches welcomed
+ #sysfspath = obj.GetPropertyString("linux.sysfs_path")
+ # XXX hal gives back paths to /sys/devices/pci0000:00/0000:00:1e.0/0000:01:00.0/net/eth0
+ # which doesnt' work so well - we want this:
+ sysfspath = "/sys/class/net/" + name
+
+ # If running a device in bridged mode, there's a reasonable
+ # chance that the actual ethernet device has been renamed to
+ # something else. ethN -> pethN
+ psysfspath = sysfspath[0:len(sysfspath)-len(name)] + "p" + name
+ if os.path.exists(psysfspath):
+ logging.debug("Device %s named to p%s" % (name, name))
+ name = "p" + name
+ sysfspath = psysfspath
+
+ # Ignore devices that are slaves of a bond
+ if self._net_is_bonding_slave(name, sysfspath):
+ logging.debug("Skipping device %s in bonding slave" % name)
+ return
+
mac = obj.GetPropertyString("net.address")
- # Now magic to determine if the device is part of a bridge
- shared = False
- bridge = None
- try:
- # XXX Linux specific - needs porting for other OS - patches
- # welcomed...
- sysfspath = obj.GetPropertyString("linux.sysfs_path")
-
- # If running a device in bridged mode, there's a reasonable
- # chance that the actual ethernet device has been renamed to
- # something else. ethN -> pethN
- psysfspath = sysfspath[0:len(sysfspath)-len(name)] + "p" + name
- if os.path.exists(psysfspath):
- name = "p" + name
- sysfspath = psysfspath
-
- brportpath = os.path.join(sysfspath, "brport")
-
- if os.path.exists(brportpath):
- shared = True
- brlinkpath = os.path.join(brportpath, "bridge")
- dest = os.readlink(brlinkpath)
- (head,tail) = os.path.split(dest)
- bridge = tail
- except:
- (type, value, stacktrace) = sys.exc_info ()
- logging.error("Unable to determine if device is shared:" +
- str(type) + " " + str(value) + "\n" + \
- traceback.format_exc (stacktrace))
-
- if self.netdevs.has_key(path):
- currDev = self.netdevs[path]
- if currDev.get_info() == (name, mac, shared, bridge):
- return
- del self.netdevs[path]
- dev = vmmNetDevice(self.config, self, name, mac, shared, bridge)
- self.netdevs[path] = dev
- self.emit("netdev-added", dev.get_name())
-
- def _device_removed(self, path):
- if self.netdevs.has_key(path):
- dev = self.netdevs[path]
+ # Add the main NIC
+ self._net_device_added(name, mac, sysfspath)
+
+ # Add any associated VLANs
+ logging.debug("Checking for VLANs on %s" % sysfspath)
+ for vlanpath in glob.glob(sysfspath + ".*"):
+ if os.path.exists(vlanpath):
+ logging.debug("Process VLAN %s" % vlanpath)
+ vlanmac = self._net_get_mac_address(name, vlanpath)
+ (ignore,vlanname) = os.path.split(vlanpath)
+ self._net_device_added(vlanname, vlanmac, vlanpath)
+
+ def _net_device_added(self, name, mac, sysfspath):
+ # Race conditions mean we can occassionally see device twice
+ if self.netdevs.has_key(name):
+ return
+
+ bridge = self._net_get_bridge_owner(name, sysfspath)
+ shared = False
+ if bridge is not None:
+ shared = True
+
+ logging.debug("Adding net device %s %s %s bridge %s" % (name, mac, sysfspath, str(bridge)))
+
+ dev = vmmNetDevice(self.config, self, name, mac, shared, bridge)
+ self.netdevs[name] = dev
+ self.emit("netdev-added", dev.get_name())
+
+ def _net_phys_device_removed(self, path):
+ obj = self.bus.get_object("org.freedesktop.Hal", path)
+ if obj.QueryCapability("net"):
+ name = obj.GetPropertyString("net.interface")
+
+ if self.netdevs.has_key(name):
+ dev = self.netdevs[name]
self.emit("netdev-removed", dev.get_name())
- del self.netdevs[path]
+ del self.netdevs[name]
def is_read_only(self):
return self.readOnly
@@ -545,13 +568,6 @@ class vmmConnection(gobject.GObject):
newInactiveNetNames = self.vmm.listDefinedNetworks()
except:
logging.warn("Unable to list inactive networks")
-
- # check of net devices
- newPaths = []
- if self.hal_iface:
- newPaths = self.hal_iface.FindDeviceByCapability("net")
- for newPath in newPaths:
- self._device_added(newPath)
for name in newActiveNetNames:
net = self.vmm.networkLookupByName(name)
@@ -847,5 +863,47 @@ class vmmConnection(gobject.GObject):
else:
return _("Unknown")
+ def _net_get_bridge_owner(self, name, sysfspath):
+ # Now magic to determine if the device is part of a bridge
+ brportpath = os.path.join(sysfspath, "brport")
+ try:
+ if os.path.exists(brportpath):
+ brlinkpath = os.path.join(brportpath, "bridge")
+ dest = os.readlink(brlinkpath)
+ (ignore,bridge) = os.path.split(dest)
+ return bridge
+ except:
+ (type, value, stacktrace) = sys.exc_info ()
+ logging.error("Unable to determine if device is shared:" +
+ str(type) + " " + str(value) + "\n" + \
+ traceback.format_exc (stacktrace))
+
+ return None
+
+ def _net_get_mac_address(self, name, sysfspath):
+ mac = None
+ addrpath = sysfspath + "/address"
+ if os.path.exists(addrpath):
+ df = open(addrpath, 'r')
+ mac = df.readline()
+ df.close()
+ return mac.strip(" \n\t")
+
+ def _net_get_bonding_masters(self):
+ masters = []
+ f = open("/sys/class/net/bonding_masters")
+ while True:
+ rline = f.readline()
+ if not rline: break
+ if rline == "\x00": continue
+ masters.append(rline.strip(" \n\t"))
+ return masters
+
+ def _net_is_bonding_slave(self, name, sysfspath):
+ masterpath = sysfspath + "/master"
+ if os.path.exists(masterpath):
+ return True
+ return False
+
gobject.type_register(vmmConnection)
Regards,
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
More information about the et-mgmt-tools
mailing list