[PATCH rhel6-branch] (v2) Support bonding in %pre section (#971961)
Radek Vykydal
rvykydal at redhat.com
Tue Oct 8 13:08:58 UTC 2013
Changes in this version:
- waiting for bond device: poll for device existence every 1s instead of sleep(2)
- disconnecting of slaves: use dbus method instead of writing NM_CONTROLLED=no
to ifcfg file
- wait for bond device activation (instead of waiting for nm to be connected
which returns immediately if another device is active)
Based on patch by Masahiro Matsuya
Resolves: rhbz#971961
---
kickstart.py | 43 +++++++++++++++++++++++++++++++++++++++----
network.py | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 77 insertions(+), 4 deletions(-)
diff --git a/kickstart.py b/kickstart.py
index 1e9b529..1c113a8 100644
--- a/kickstart.py
+++ b/kickstart.py
@@ -684,13 +684,36 @@ class NetworkData(commands.network.RHEL6_NetworkData):
anaconda.id.network.setHostname(self.hostname)
anaconda.id.network.overrideDHCPhostname = True
+ activate_new_device = False
if not dev:
- if self.hostname:
+ if self.bondslaves:
+ if not self.activate:
+ log.info("bond %s not configured in stage 2, only activation supported, please use --activate option" % device)
+ return
+ activate_new_device = True
+ dev = anaconda.id.network.enableBondingDevice(device)
+ dev.set(("BONDING_OPTS", self.bondopts))
+ slaves = self.bondslaves.split(',')
+ for slave in slaves:
+ slavedev = devices.get(slave, None)
+ if slavedev:
+ # disconnect the slave
+ anaconda.id.network.disconnectDevice(slavedev.iface)
+
+ mac = slavedev.get('HWADDR')
+ uuid = slavedev.get('UUID')
+ slavedev.clear()
+ slavedev.set(("DEVICE", slave))
+ if mac:
+ slavedev.set(("HWADDR", mac))
+ if uuid:
+ slavedev.set(("UUID", uuid))
+ slavedev.set(("SLAVE", "yes"))
+ slavedev.set(("MASTER", device))
+ slavedev.set(("ONBOOT", "yes"))
+ elif self.hostname:
# Only set hostname
return
- elif self.bondslaves:
- log.info("bond %s not configured, only supported for devices activated during installation" % device)
- return
else:
raise KickstartValueError, formatErrorMsg(self.lineno, msg="The provided network interface %s does not exist" % device)
@@ -743,6 +766,18 @@ class NetworkData(commands.network.RHEL6_NetworkData):
if self.nodefroute:
dev.set (("DEFROUTE", "no"))
+ if activate_new_device:
+ log.info("Bringing up network device %s in stage2 kickstart ..." %
+ dev.iface)
+ dev.set (("onboot", "yes"))
+ anaconda.id.network.write()
+ if not anaconda.id.network.waitForDevice(dev.iface):
+ log.info("Can't find bond device %s")
+ return
+ failed_ifaces = anaconda.id.network.waitForDevicesActivation([dev.iface])
+ log.info("Activation %s" % ('succeeded' if not failed_ifaces else 'failed',))
+ return
+
needs_net = (anaconda.methodstr and
(anaconda.methodstr.startswith("http:") or
anaconda.methodstr.startswith("ftp:") or
diff --git a/network.py b/network.py
index 523ef6b..29f17c4 100644
--- a/network.py
+++ b/network.py
@@ -642,6 +642,18 @@ class Network:
log.warning("autoconnectFCoEDevices: %s file not found" %
device.path)
+ def enableBondingDevice(self, devName, instPath=''):
+ dev = NetworkDevice(instPath + netscriptsDir, devName)
+ self.netdevices[devName] = dev
+ dev.set(("DEVICE", devName))
+ dev.set(("TYPE", "Bond"))
+ dev.set(("NM_CONTROLLED", "yes"))
+ if not os.access(dev.path, os.R_OK):
+ f = open(dev.path, "w")
+ f.close()
+ dev.writeIfcfgFile()
+ return dev
+
def hasActiveIPoIBDevice(self):
active_devs = getActiveNetDevs()
for devName, device in self.netdevices.items():
@@ -734,6 +746,15 @@ class Network:
f.write("options ipv6 disable=1\n")
f.close()
+ def waitForDevice(self, device, timeout=CONNECTION_TIMEOUT):
+ props = isys.getDeviceProperties(device)
+ i = 0
+ while not props and i < timeout:
+ props = isys.getDeviceProperties(device)
+ i += 1
+ time.sleep(1)
+ return bool(props)
+
def waitForDevicesActivation(self, devices):
waited_devs_props = {}
@@ -795,6 +816,23 @@ class Network:
self.write()
return self.waitForConnection()
+ def disconnectDevice(self, devname):
+ bus = dbus.SystemBus()
+ nm = bus.get_object(isys.NM_SERVICE, isys.NM_MANAGER_PATH)
+ device_paths = nm.get_dbus_method("GetDevices")()
+ for device_path in device_paths:
+ device = bus.get_object(isys.NM_SERVICE, device_path)
+ device_props_iface = dbus.Interface(device, isys.DBUS_PROPS_IFACE)
+ iface = str(device_props_iface.Get(isys.NM_DEVICE_IFACE, "Interface"))
+ if iface == devname:
+ try:
+ device.get_dbus_method("Disconnect")()
+ except dbus.DBusException as e:
+ log.debug("disconnectDevice %s: %s" % (devname, e))
+ return False
+ return True
+ return False
+
# get a kernel cmdline string for dracut needed for access to host host
def dracutSetupArgs(self, networkStorageDevice):
netargs=set()
--
1.7.11.7
More information about the anaconda-patches
mailing list