Change in vdsm[master]: netinfo: Stop NetworkManager from ifup'ing our reference bond

osvoboda at redhat.com osvoboda at redhat.com
Tue Sep 23 03:23:52 UTC 2014


Ondřej Svoboda has uploaded a new change for review.

Change subject: netinfo: Stop NetworkManager from ifup'ing our reference bond
......................................................................

netinfo: Stop NetworkManager from ifup'ing our reference bond

This is hopefully only a workaround until NM has better "server mode"
support, see https://bugzilla.redhat.com/show_bug.cgi?id=1136843

Change-Id: Iff14c4791355f05890805a8d6b5208e7adb0ef7b
Bug-Url: https://bugzilla.redhat.com/1142701
Signed-off-by: Ondřej Svoboda <osvoboda at redhat.com>
---
M configure.ac
M lib/vdsm/constants.py.in
M lib/vdsm/netinfo.py
M vdsm/sudoers.vdsm.in
4 files changed, 58 insertions(+), 22 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/27/33227/1

diff --git a/configure.ac b/configure.ac
index 0471b5f..62e512a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -276,6 +276,7 @@
 AC_PATH_PROG([MULTIPATH_PATH], [multipath], [/sbin/multipath])
 AC_PATH_PROG([MV_PATH], [mv], [/bin/mv])
 AC_PATH_PROG([NICE_PATH], [nice], [/bin/nice])
+AC_PATH_PROG([NMCLI_PATH], [nmcli], [/usr/bin/nmcli])
 AC_PATH_PROG([NTPQ_PATH], [ntpq], [/usr/sbin/ntpq])
 AC_PATH_PROG([OPENSSL_PATH], [openssl], [/usr/bin/openssl])
 AC_PATH_PROG([PERSIST_PATH], [persist], [/usr/sbin/persist])
diff --git a/lib/vdsm/constants.py.in b/lib/vdsm/constants.py.in
index ee379d6..b8eb826 100644
--- a/lib/vdsm/constants.py.in
+++ b/lib/vdsm/constants.py.in
@@ -132,6 +132,7 @@
 EXT_MULTIPATH = '@MULTIPATH_PATH@'
 
 EXT_NICE = '@NICE_PATH@'
+EXT_NMCLI = '@NMCLI_PATH@'
 
 EXT_PERSIST = '@PERSIST_PATH@'
 EXT_PGREP = '@PGREP_PATH@'
diff --git a/lib/vdsm/netinfo.py b/lib/vdsm/netinfo.py
index 4f2ccd5..e217d18 100644
--- a/lib/vdsm/netinfo.py
+++ b/lib/vdsm/netinfo.py
@@ -19,6 +19,7 @@
 #
 
 from collections import defaultdict
+from contextlib import contextmanager
 import errno
 from glob import iglob
 from datetime import datetime
@@ -44,7 +45,7 @@
 from .ipwrapper import routeShowGateways
 from . import libvirtconnection
 from .netconfpersistence import RunningConfig
-from .utils import execCmd, memoized, CommandPath
+from .utils import execCmd, memoized, namedTemporaryDir, CommandPath
 from .netlink import link as nl_link
 from .netlink import addr as nl_addr
 from .netlink import route as nl_route
@@ -76,6 +77,7 @@
 ))
 _IFCFG_ZERO_SUFFIXED = frozenset(
     ('IPADDR0', 'GATEWAY0', 'PREFIX0', 'NETMASK0'))
+_NM_CLI_BINARY = CommandPath('nmcli', constants.EXT_NMCLI)
 _TEE_BINARY = CommandPath('tee', constants.EXT_TEE)
 
 LIBVIRT_NET_PREFIX = 'vdsm-'
@@ -410,6 +412,36 @@
     return ''.join(random.choice(CHARS) for _ in range(MAX_LENGTH))
 
 
+ at contextmanager
+def _avoidNetworkManager(interface):
+    """Make a network interface unmanaged by NetworkManager.
+
+    Until NM supports placing its 'unmanaged-devices' directive in
+    /etc/NetworkManager/conf.d/00-server.conf we are left with a hack.
+    The directive should also support globbing so we do not have to use
+    a predictable name for e.g. the reference bond (but we could accept that,
+    too).
+
+    Please see https://bugzilla.redhat.com/show_bug.cgi?id=1136843"""
+    has_nm = pgrep('NetworkManager')
+
+    if has_nm:
+        nmcli = _NM_CLI_BINARY.cmd
+        with namedTemporaryDir() as tempDir:
+            ifcfgPath = os.path.join(tempDir, 'ifcfg-' + interface)
+            with open(ifcfgPath, 'w') as ifcfgFile:
+                ifcfgFile.write('DEVICE=%s\nNM_CONTROLLED=no' % interface)
+
+            rc, _, _ = execCmd([nmcli, 'conn', 'load', ifcfgPath], sudo=True)
+            if rc:
+                raise RuntimeError('Failed to unmanage %s.' % interface)
+    try:
+        yield
+    finally:
+        if has_nm:
+            execCmd([nmcli, 'conn', 'delete', interface], sudo=True)
+
+
 @memoized
 def _getAllDefaultBondingOptions():
     """
@@ -420,31 +452,32 @@
     MAX_MODE = 6
 
     bondName = _randomIfaceName()
-    rc, _, err = execCmd([teeCmd, BONDING_MASTERS],
-                         data='+' + bondName, sudo=True)
-    if rc:
-        raise RuntimeError('Creating a reference bond failed', '\n'.join(err))
+    with _avoidNetworkManager():
+        rc, _, _ = execCmd([teeCmd, BONDING_MASTERS], data='+' + bondName,
+                           sudo=True)
+        if rc:
+            raise RuntimeError('Creating a reference bond failed.')
 
-    opts = {}
-    try:
-        defaultMode = bondOpts(bondName, keys=['mode'])['mode']
+        opts = {}
+        try:
+            defaultMode = bondOpts(bondName, keys=['mode'])['mode']
 
-        # read default values for all modes
-        for mode in range(0, MAX_MODE + 1):
-            mode = str(mode)
-            rc, _, err = execCmd([teeCmd, BONDING_OPT % (bondName, 'mode')],
-                                 data=mode, sudo=True)
-            if rc:
-                raise RuntimeError('Changing a bond\'s mode failed, is '
-                                   'NetworkManager running?', '\n'.join(err))
+            # read default values for all modes
+            for mode in range(0, MAX_MODE + 1):
+                mode = str(mode)
+                rc, _, _ = execCmd([teeCmd, BONDING_OPT % (bondName, 'mode')],
+                                   data=mode, sudo=True)
+                if rc:
+                    raise RuntimeError('Changing a bond\'s mode failed, is '
+                                       'NetworkManager running?')
 
-            # only read non-empty options
-            opts[mode] = dict(((opt, val) for (opt, val) in
-                               _realBondOpts(bondName).iteritems() if val))
-            opts[mode]['mode'] = defaultMode
+                # only read non-empty options
+                opts[mode] = dict(((opt, val) for (opt, val) in
+                                   _realBondOpts(bondName).iteritems() if val))
+                opts[mode]['mode'] = defaultMode
 
-    finally:
-        execCmd([teeCmd, BONDING_MASTERS], data='-' + bondName, sudo=True)
+        finally:
+            execCmd([teeCmd, BONDING_MASTERS], data='-' + bondName, sudo=True)
 
     return opts
 
diff --git a/vdsm/sudoers.vdsm.in b/vdsm/sudoers.vdsm.in
index b201525..0a1d7fb 100644
--- a/vdsm/sudoers.vdsm.in
+++ b/vdsm/sudoers.vdsm.in
@@ -31,6 +31,7 @@
     @SERVICE_PATH@ vdsmd *, \
     @REBOOT_PATH@ -f
 Cmnd_Alias VDSM_NETWORK = \
+    @NMCLI_PATH@ conn, \
     @TEE_PATH@ /sys/class/net/bonding_masters, \
     @TEE_PATH@ /sys/class/net/*/bonding/mode
 


-- 
To view, visit http://gerrit.ovirt.org/33227
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iff14c4791355f05890805a8d6b5208e7adb0ef7b
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Ondřej Svoboda <osvoboda at redhat.com>


More information about the vdsm-patches mailing list