Petr Horáček has uploaded a new change for review.
Change subject: net: configurators: persist custom bond option
......................................................................
net: configurators: persist custom bond option
Until now, custom bond property was exposed only to
before_network_setup hook and then dropped (so it was not
passed to configurators and persisted). But this is not how
custom *network* property behaves. We want these two custom
properties to be symmetric - they have to be persisted
(if unified persistence is used). Unlike custom network
properties (which are known as 'special' by Engine), custom bond
properties have to be reported in netinfo. Last but not least,
we need this custom property to be able to tag bonding as
'OVS Bond' so it will be handled by OVS hook, not by default
configurator.
This patch moves removal of custom property down to
configurators. Thanks to it, custom property is persisted,
but not set as a bond option.
Custom property is not dropped only in configurators, but in
models.py:Bond:areOptionsApplied as well - we don't want
configurator to reconfigure bond when there is a custom
property defined while its value is not used by configurator.
Change-Id: Ic4f1564e19904cc1d53bc6d1cf732ca35375332e
Signed-off-by: Petr Horáček <phoracek(a)redhat.com>
---
M debian/vdsm.install
M lib/vdsm/netinfo.py
M tests/functional/networkTests.py
M vdsm.spec.in
M vdsm/network/Makefile.am
M vdsm/network/configurators/ifcfg.py
M vdsm/network/configurators/iproute2.py
M vdsm/network/models.py
A vdsm/network/utils.py
9 files changed, 85 insertions(+), 9 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/22/44022/1
diff --git a/debian/vdsm.install b/debian/vdsm.install
index 819f165..b69c7c1 100644
--- a/debian/vdsm.install
+++ b/debian/vdsm.install
@@ -73,6 +73,7 @@
./usr/share/vdsm/network/configurators/ifcfg.py
./usr/share/vdsm/network/configurators/iproute2.py
./usr/share/vdsm/network/configurators/libvirt.py
+./usr/share/vdsm/network/utils.py
./usr/share/vdsm/numaUtils.py
./usr/share/vdsm/parted_utils.py
./usr/share/vdsm/ppc64HardwareInfo.py
diff --git a/lib/vdsm/netinfo.py b/lib/vdsm/netinfo.py
index 01f25c7..4dbe308 100644
--- a/lib/vdsm/netinfo.py
+++ b/lib/vdsm/netinfo.py
@@ -73,7 +73,7 @@
_BONDING_FAILOVER_MODES = frozenset(('1', '3'))
_BONDING_LOADBALANCE_MODES = frozenset(('0', '2', '4', '5', '6'))
_EXCLUDED_BONDING_ENTRIES = frozenset((
- 'slaves', 'active_slave', 'mii_status', 'queue_id', 'ad_aggregator',
+ 'slaves', 'active_slave', 'mii_status', 'queue_id', 'ad_aggregator',
'ad_num_ports', 'ad_actor_key', 'ad_partner_key', 'ad_partner_mac'
))
_IFCFG_ZERO_SUFFIXED = frozenset(
@@ -610,6 +610,15 @@
return info
+def _bondCustomOpts(dev, devinfo, running_config):
+ """Add custom bonding options read from running_config."""
+ if dev.name in running_config.bonds:
+ for option in running_config.bonds[dev.name]['options'].split():
+ if option.startswith('custom='):
+ devinfo['opts']['custom'] = option.split('=', 1)[1]
+ break
+
+
def _devinfo(link, ipaddrs):
ipv4addr, ipv4netmask, ipv4addrs, ipv6addrs = getIpInfo(link.name, ipaddrs)
return {'addr': ipv4addr,
@@ -740,6 +749,7 @@
ipv6routes = getIPv6Routes()
paddr = permAddr()
ipaddrs = _getIpAddrs()
+ running_config = RunningConfig()
if vdsmnets is None:
nets = networks()
@@ -755,6 +765,7 @@
d['nics'][dev.name] = _nicinfo(dev, paddr, ipaddrs)
elif dev.isBOND():
d['bondings'][dev.name] = _bondinfo(dev, ipaddrs)
+ _bondCustomOpts(dev, d, running_config)
elif dev.isVLAN():
d['vlans'][dev.name] = _vlaninfo(dev, ipaddrs)
diff --git a/tests/functional/networkTests.py b/tests/functional/networkTests.py
index c5da1f2..5bc11d8 100644
--- a/tests/functional/networkTests.py
+++ b/tests/functional/networkTests.py
@@ -1505,7 +1505,7 @@
self.assertEquals(status, SUCCESS, msg)
self.vdsm_net.save_config()
-
+
@cleanupNet
@RequireDummyMod
@ValidateRunningAsRoot
@@ -1526,7 +1526,7 @@
status, msg = self.setupNetworks(
{NETWORK_NAME: {'remove': True}}, {}, NOCHK)
self.assertEquals(status, SUCCESS, msg)
-
+
@cleanupNet
@RequireDummyMod
@ValidateRunningAsRoot
@@ -1689,7 +1689,7 @@
def _verify_running_config_intact():
self.assertEqual(set([NET_MGMT, NET_CHANGED, NET_UNCHANGED,
- NET_ADDITIONAL]),
+ NET_ADDITIONAL]),
set(self.vdsm_net.config.networks.keys()))
self.assertEqual(set([BOND_CHANGED, BOND_UNCHANGED]),
set(self.vdsm_net.config.bonds.keys()))
@@ -1721,7 +1721,7 @@
_assert_all_nets_exist()
_verify_running_config_intact()
self.assertEqual(set(['ifcfg-%s' % NET_ADDITIONAL,
- 'ifcfg-%s' % nic_d]),
+ 'ifcfg-%s' % nic_d]),
set(os.listdir(NET_CONF_BACK_DIR)))
# another 'boot' should restore nothing
@@ -2505,3 +2505,28 @@
self.assertNetworkDoesntExist(NETWORK_NAME)
self.assertBondDoesntExist(BONDING_NAME, [nic])
self.vdsm_net.save_config()
+
+ @cleanupNet
+ @ValidateRunningAsRoot
+ def test_setupNetworks_bond_with_custom_option(self):
+ with dummyIf(2) as nics:
+ status, msg = self.setupNetworks(
+ {},
+ {BONDING_NAME: {'nics': nics,
+ 'options': 'custom=foo=bar mode=4'}},
+ NOCHK)
+ self.assertEqual(status, SUCCESS, msg)
+ self.assertBondExists(BONDING_NAME, nics)
+ if vdsm.config.config.get('vars', 'net_persistence') == 'unified':
+ # custom property has to be shown in netinfo and persisted (if
+ # unified persistence is used).
+ self._assert_exact_bond_opts(BONDING_NAME,
+ ['mode=4', 'custom=foo=bar'])
+ bond = self.vdsm_net.config.bonds.get(BONDING_NAME)
+ self.assertSetEqual(set(['mode=4', 'custom=foo=bar']),
+ set(bond.get('options').split()))
+
+ status, msg = self.setupNetworks(
+ {}, {BONDING_NAME: {'remove': True}}, NOCHK)
+ self.assertEqual(status, SUCCESS, msg)
+ self.assertBondDoesntExist(BONDING_NAME, nics)
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 8a54ed8..7ba765a 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -1087,6 +1087,7 @@
%{_datadir}/%{vdsm_name}/network/configurators/ifcfg.py*
%{_datadir}/%{vdsm_name}/network/configurators/libvirt.py*
%{_datadir}/%{vdsm_name}/network/configurators/iproute2.py*
+%{_datadir}/%{vdsm_name}/network/utils.py*
%{_datadir}/%{vdsm_name}/storage/__init__.py*
%{_datadir}/%{vdsm_name}/storage/blockSD.py*
%{_datadir}/%{vdsm_name}/storage/blockVolume.py*
diff --git a/vdsm/network/Makefile.am b/vdsm/network/Makefile.am
index 9aa3f23..071cf53 100644
--- a/vdsm/network/Makefile.am
+++ b/vdsm/network/Makefile.am
@@ -31,4 +31,5 @@
sourceroute.py \
sourceroutethread.py \
tc.py \
+ utils.py \
$(NULL)
diff --git a/vdsm/network/configurators/ifcfg.py b/vdsm/network/configurators/ifcfg.py
index c3f9893..d78c5db 100644
--- a/vdsm/network/configurators/ifcfg.py
+++ b/vdsm/network/configurators/ifcfg.py
@@ -45,6 +45,7 @@
from ..errors import ConfigNetworkError, ERR_FAILED_IFUP
from ..models import Nic, Bridge, IpConfig
from ..sourceroute import StaticSourceRoute, DynamicSourceRoute
+from ..utils import remove_custom_bond_option
import dsaversion # TODO: Make parent package import when vdsm is a package
@@ -585,7 +586,9 @@
def addBonding(self, bond, **opts):
""" Create ifcfg-* file with proper fields for bond """
- conf = 'BONDING_OPTS=%s\n' % pipes.quote(bond.options or '')
+ # 'custom' is not a real bond option, it just piggybacks custom values
+ options = remove_custom_bond_option(bond.options)
+ conf = 'BONDING_OPTS=%s\n' % pipes.quote(options)
opts['hotplug'] = 'no' # So that udev doesn't trigger an ifup
if bond.bridge:
conf += 'BRIDGE=%s\n' % pipes.quote(bond.bridge.name)
diff --git a/vdsm/network/configurators/iproute2.py b/vdsm/network/configurators/iproute2.py
index b06e0ad..cf31a38 100644
--- a/vdsm/network/configurators/iproute2.py
+++ b/vdsm/network/configurators/iproute2.py
@@ -35,6 +35,7 @@
from ..errors import ConfigNetworkError, ERR_FAILED_IFUP, ERR_FAILED_IFDOWN
from ..models import Nic
from ..sourceroute import DynamicSourceRoute
+from ..utils import remove_custom_bond_option
_BRIDGING_OPT_PATH = '/sys/class/net/%s/bridge/%s'
_ETHTOOL_BINARY = CommandPath(
@@ -321,7 +322,9 @@
def addBondOptions(self, bond):
logging.debug('Add bond options %s', bond.options)
- for option in bond.options.split():
+ # 'custom' is not a real bond option, it just piggybacks custom values
+ options = remove_custom_bond_option(bond.options)
+ for option in options:
key, value = option.split('=')
with open(netinfo.BONDING_OPT % (bond.name, key), 'w') as f:
f.write(value)
diff --git a/vdsm/network/models.py b/vdsm/network/models.py
index 8e33950..4ae7508 100644
--- a/vdsm/network/models.py
+++ b/vdsm/network/models.py
@@ -28,6 +28,7 @@
from .errors import ConfigNetworkError
from . import errors as ne
+from .utils import remove_custom_bond_option
class NetDevice(object):
@@ -208,9 +209,11 @@
# TODO: this method returns True iff self.options are a subset of the
# TODO: current bonding options. VDSM should probably compute if the
# TODO: non-default settings are equal to the non-default state.
- if not self.options:
+ # 'custom' is not a real bond option, it just piggybacks custom values
+ options = remove_custom_bond_option(self.options)
+ if options == '':
return True
- confOpts = [option.split('=', 1) for option in self.options.split(' ')]
+ confOpts = [option.split('=', 1) for option in options.split(' ')]
activeOpts = netinfo.bondOpts(self.name,
(name for name, value in confOpts))
return all(value in activeOpts[name] for name, value in confOpts)
diff --git a/vdsm/network/utils.py b/vdsm/network/utils.py
new file mode 100644
index 0000000..370d82e
--- /dev/null
+++ b/vdsm/network/utils.py
@@ -0,0 +1,28 @@
+# Copyright 2015 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+
+def remove_custom_bond_option(options):
+ """ Removes 'custom' option from bond options string.
+
+ >>> remove_custom_bond_option('custom=foo=bar mode=1')
+ 'mode=1'
+ """
+ return ' '.join((option for option in options.split()
+ if not option.startswith('custom=')))
--
To view, visit https://gerrit.ovirt.org/44022
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic4f1564e19904cc1d53bc6d1cf732ca35375332e
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Petr Horáček <phoracek(a)redhat.com>
Piotr Kliczewski has uploaded a new change for review.
Change subject: ssl: ssl socket may throw sslerror during reading
......................................................................
ssl: ssl socket may throw sslerror during reading
When client closes socket in not clean way sometimes we can get SSLError
with unexpected eof. When this situation occurs we need to make sure to
handle this situation properly.
Bug-Url: https://bugzilla.redhat.com/1256446
Change-Id: I8de60d91f81b08e9cb78df07f09d2bcc903c1bad
Signed-off-by: pkliczewski <piotr.kliczewski(a)gmail.com>
---
M lib/yajsonrpc/betterAsyncore.py
1 file changed, 3 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/25/46625/1
diff --git a/lib/yajsonrpc/betterAsyncore.py b/lib/yajsonrpc/betterAsyncore.py
index ef5738b..7896aaf 100644
--- a/lib/yajsonrpc/betterAsyncore.py
+++ b/lib/yajsonrpc/betterAsyncore.py
@@ -21,6 +21,7 @@
import socket
from errno import EWOULDBLOCK
+from vdsm.m2cutils import SSL
from vdsm.infra.eventfd import EventFD
from vdsm.utils import traceback
@@ -122,6 +123,8 @@
return ''
else:
raise
+ except SSL.SSLError:
+ self.handle_close()
def send(self, data):
try:
--
To view, visit https://gerrit.ovirt.org/46625
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8de60d91f81b08e9cb78df07f09d2bcc903c1bad
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Piotr Kliczewski <piotr.kliczewski(a)gmail.com>
Hello Adam Litke,
I'd like you to do a code review. Please visit
https://gerrit.ovirt.org/46485
to review the following change.
Change subject: safelease: Increase spmprotect timeouts
......................................................................
safelease: Increase spmprotect timeouts
When spmprotect.sh fail to renew the lease, it start a fencing process:
1. Send SIGUSR1 signal to vdsm
2. Send SIGTERM signal to vdsm after 7 seconds
3. Send SIGKILL signal to vdsm after 9 seconds
4. Reboot the machine after 20 seconds
When vdsm receives the SIGUSR1 signal, the signal handler invokes
stopSpm, which releases the cluster lock. Releasing the cluster lock will
terminate the waiting spmprotect.sh, preventing termination of vdsm and
reboot.
If vdsm fails to release the cluster lock within 7 seconds, spmprotect.sh
will terminate it, and if did not terminate, spmprotect.sh will kill it.
When systemd starts vdsm again, vdsm looks for spmprotect.sh processes and
tries to release the lease. If the lease cannot be released after 10
seconds, it kills the pending spmprotect.sh processes, preventing reboot.
Testing with both block and file storage show that this flow is broken
when access to master domain is blocked:
1. In block storage, vdsm gets stuck trying to unmount the master mount,
and spmprotect.sh kills it before it try to release the cluster lock.
2. In file storage, vdsm gets stuck trying to write spm status to the
master domain, and spmprotect.sh kills it before it try to release
the cluster lock.
3. When vdsm starts up, sometimes it manage to kill the waiting
spmprotect.sh process, and sometimes spmprotect.sh reboot the
machine before vdsm kills it.
We cannot fix 1 and 2 easily. 3 can be fixed by giving vdsm more time
for stopSpm flow, and more time to startup and kill pending
spmprotect.sh process.
This patch increases spmprotect timeouts to increase the chance of clean
shutdown and decrease the chance of unneeded reboot.
New spmprotect.sh flow is:
1. Send SIGUSR1 signal to vdsm
2. Send SIGTERM signal to vdsm after 10 seconds
3. Send SIGKILL signal to vdsm after 20 seconds
4. Reboot the machine after 60 seconds
Change-Id: Ib71fa06c21602fd9d43516c5b4c997c481708697
Bug-Url: https://bugzilla.redhat.com/1222564
Signed-off-by: Nir Soffer <nsoffer(a)redhat.com>
Reviewed-on: https://gerrit.ovirt.org/46057
Continuous-Integration: Jenkins CI
Reviewed-by: Adam Litke <alitke(a)redhat.com>
---
M vdsm/storage/protect/spmprotect.sh
1 file changed, 3 insertions(+), 3 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/85/46485/1
diff --git a/vdsm/storage/protect/spmprotect.sh b/vdsm/storage/protect/spmprotect.sh
index fc0e390..b13b07c 100755
--- a/vdsm/storage/protect/spmprotect.sh
+++ b/vdsm/storage/protect/spmprotect.sh
@@ -71,12 +71,12 @@
trap "" INT
log "Fencing sdUUID=$sdUUID id=$ID lease_path=$LEASE_FILE"
- (sleep 20 && echodo $REBOOTCMD) &
+ (sleep 60 && echodo $REBOOTCMD) &
disown
- (sleep 7
+ (sleep 10
log "Trying to stop vdsm for sdUUID=$sdUUID id=$ID lease_path=$LEASE_FILE"
echodo $KILL "$VDSM_PID"
- sleep 2
+ sleep 10
echodo $KILL -9 "$VDSM_PID"
)&
disown
--
To view, visit https://gerrit.ovirt.org/46485
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib71fa06c21602fd9d43516c5b4c997c481708697
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Nir Soffer <nsoffer(a)redhat.com>
Gerrit-Reviewer: Adam Litke <alitke(a)redhat.com>