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