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

Change subject: netinfo: Read default bonding options
......................................................................

netinfo: Read default bonding options

A randomly-named reference bond is created once to obtain
the same values as defined in kernel configuration.

Some sysfs entries are ignored as they are not actually
"options", e.g. 'active_slave', 'ad_partner_mac'.

Change-Id: If8109feeef02b71c1d74dc6303839c6f45175915
Bug-Url: https://bugzilla.redhat.com/987813
Signed-off-by: Ondřej Svoboda <osvob...@redhat.com>
---
M configure.ac
M lib/vdsm/constants.py.in
M lib/vdsm/netinfo.py
M vdsm/sudoers.vdsm.in
4 files changed, 92 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/80/27680/1

diff --git a/configure.ac b/configure.ac
index 8e157a7..fdc4edc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -242,6 +242,7 @@
 AC_PATH_PROG([SYSTEMCTL_PATH], [systemctl], [/bin/systemctl])
 AC_PATH_PROG([TAR_PATH], [tar], [/bin/tar])
 AC_PATH_PROG([TC_PATH], [tc], [/sbin/tc])
+AC_PATH_PROG([TEE_PATH], [tee], [/usr/bin/tee])
 AC_PATH_PROG([TOUCH_PATH], [touch], [/bin/touch])
 AC_PATH_PROG([TUNE2FS_PATH], [tune2fs], [/sbin/tune2fs])
 AC_PATH_PROG([UDEVADM_PATH], [udevadm], [/sbin/udevadm])
diff --git a/lib/vdsm/constants.py.in b/lib/vdsm/constants.py.in
index 4ddfe84..afd6f68 100644
--- a/lib/vdsm/constants.py.in
+++ b/lib/vdsm/constants.py.in
@@ -137,6 +137,7 @@
 EXT_SUDO = '@SUDO_PATH@'
 
 EXT_TAR = '@TAR_PATH@'
+EXT_TEE = '@TEE_PATH@'
 EXT_TUNE2FS = '@TUNE2FS_PATH@'
 
 EXT_UDEVADM = '@UDEVADM_PATH@'
diff --git a/lib/vdsm/netinfo.py b/lib/vdsm/netinfo.py
index 1734966..7b27122 100644
--- a/lib/vdsm/netinfo.py
+++ b/lib/vdsm/netinfo.py
@@ -26,8 +26,10 @@
 from itertools import chain
 import logging
 import os
+import random
 import shlex
 import socket
+import string
 import struct
 from xml.dom import minidom
 
@@ -44,6 +46,7 @@
 from . import libvirtconnection
 from .netconfpersistence import RunningConfig
 from .netlink import iter_addrs, iter_links
+from .utils import execCmd, memoized, CommandPath
 
 
 NET_CONF_DIR = '/etc/sysconfig/network-scripts/'
@@ -70,6 +73,7 @@
 _BONDING_LOADBALANCE_MODES = frozenset(('0', '2', '4', '5', '6'))
 _IFCFG_ZERO_SUFFIXED = frozenset(
     ('IPADDR0', 'GATEWAY0', 'PREFIX0', 'NETMASK0'))
+_TEE_BINARY = CommandPath('tee', constants.EXT_TEE)
 
 LIBVIRT_NET_PREFIX = 'vdsm-'
 DEFAULT_MTU = '1500'
@@ -178,6 +182,21 @@
             opts[os.path.basename(path)] = [
                 el for el in optFile.read().rstrip().split(' ') if el]
     return opts
+
+
+def realBondOpts(bond, keys=None):
+    '''
+    Returns a dictionary in the same format as bondOpts(). Values that are not
+    actually options are excluded, e.g. 'ad_num_ports' or 'slaves'.
+    '''
+    EXCLUDED = frozenset(('slaves',  'active_slave', 'mii_status', 'queue_id',
+                          'ad_aggregator', 'ad_num_ports', 'ad_actor_key',
+                          'ad_partner_key', 'ad_partner_mac'))
+
+    opts = ((opt, val) for (opt, val) in bondOpts(bond, keys).iteritems()
+            if opt not in EXCLUDED)
+
+    return dict(opts)
 
 
 def bridgeOpts(bridge, keys=None):
@@ -544,6 +563,73 @@
     return info
 
 
+def _randomIfaceName():
+    MAX_LENGTH = 15
+    CHARS = string.ascii_lowercase + string.ascii_uppercase + string.digits
+
+    return ''.join(random.choice(CHARS) for _ in range(MAX_LENGTH))
+
+
+@memoized
+def _getAllDefaultBondingOptions():
+    '''
+    Returns default options per mode, in a dictionary of dictionaries. All keys
+    are strings.
+    '''
+    teeCmd = _TEE_BINARY.cmd
+    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))
+
+    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)
+
+            # 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)
+
+    return opts
+
+
+@memoized
+def _getDefaultBondingOptions(mode=None):
+    '''
+    Returns default options for the given mode. If it is None, options for
+    the default mode (usually '0') are returned.
+    '''
+    defaults = _getAllDefaultBondingOptions()
+
+    if mode is None:
+        mode = defaults['0']['mode'][-1]
+
+    return defaults[mode]
+
+
+def _bondOptsForIfcfg(opts):
+    '''
+    Options having symbolic values, e.g. 'mode', are presented by sysfs in
+    the order symbolic name, numeric value, e.g. 'balance-rr 0'.
+    From a list given by bondOpts(), the numeric value is chosen.
+    '''
+    return ' '.join((opt + '=' + val[-1] for (opt, val)
+                     in sorted(opts.iteritems())))
+
+
 def _bondinfo(link, ipaddrs):
     info = _devinfo(link, ipaddrs)
     info.update({'hwaddr': link.address, 'slaves': slaves(link.name)})
diff --git a/vdsm/sudoers.vdsm.in b/vdsm/sudoers.vdsm.in
index 584807d..dbc035c 100644
--- a/vdsm/sudoers.vdsm.in
+++ b/vdsm/sudoers.vdsm.in
@@ -32,7 +32,10 @@
     @SETSID_PATH@ @IONICE_PATH@ -c ? -n ? @SU_PATH@ vdsm -s /bin/sh -c 
/usr/libexec/vdsm/spmprotect.sh*, \
     @SERVICE_PATH@ vdsmd *, \
     @REBOOT_PATH@ -f
+Cmnd_Alias VDSM_NETWORK = \
+    @TEE_PATH@ /sys/class/net/bonding_masters, \
+    @TEE_PATH@ /sys/class/net/*/bonding/mode
 
-vdsm  ALL=(ALL) NOPASSWD: VDSM_LIFECYCLE, VDSM_STORAGE
+vdsm  ALL=(ALL) NOPASSWD: VDSM_LIFECYCLE, VDSM_STORAGE, VDSM_NETWORK
 Defaults:vdsm !requiretty
 Defaults:vdsm !syslog


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

Gerrit-MessageType: newchange
Gerrit-Change-Id: If8109feeef02b71c1d74dc6303839c6f45175915
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Ondřej Svoboda <osvob...@redhat.com>
_______________________________________________
vdsm-patches mailing list
vdsm-patches@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches

Reply via email to