f99b591157
The current timeout fails during functional testing with slightly higher load. Increasing it will lower the timeout chances during high load conditions. Changed from 5 seconds to respawn_interval/2. DEFAULT_OVSDBMON_RESPAWN = 30 , so the default timeout will be 15 seconds. Change-Id: I6a9e2977b275e96dcf01c4df90a33169c42287d6 Closes-Bug: #1358206
111 lines
3.8 KiB
Python
111 lines
3.8 KiB
Python
# Copyright 2013 Red Hat, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import eventlet
|
|
|
|
from neutron.agent.linux import async_process
|
|
from neutron.openstack.common import log as logging
|
|
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class OvsdbMonitor(async_process.AsyncProcess):
|
|
"""Manages an invocation of 'ovsdb-client monitor'."""
|
|
|
|
def __init__(self, table_name, columns=None, format=None,
|
|
root_helper=None, respawn_interval=None):
|
|
|
|
cmd = ['ovsdb-client', 'monitor', table_name]
|
|
if columns:
|
|
cmd.append(','.join(columns))
|
|
if format:
|
|
cmd.append('--format=%s' % format)
|
|
super(OvsdbMonitor, self).__init__(cmd,
|
|
root_helper=root_helper,
|
|
respawn_interval=respawn_interval)
|
|
|
|
def _read_stdout(self):
|
|
data = self._process.stdout.readline()
|
|
if not data:
|
|
return
|
|
self._stdout_lines.put(data)
|
|
LOG.debug(_('Output received from ovsdb monitor: %s') % data)
|
|
return data
|
|
|
|
def _read_stderr(self):
|
|
data = super(OvsdbMonitor, self)._read_stderr()
|
|
if data:
|
|
LOG.error(_('Error received from ovsdb monitor: %s') % data)
|
|
# Do not return value to ensure that stderr output will
|
|
# stop the monitor.
|
|
|
|
|
|
class SimpleInterfaceMonitor(OvsdbMonitor):
|
|
"""Monitors the Interface table of the local host's ovsdb for changes.
|
|
|
|
The has_updates() method indicates whether changes to the ovsdb
|
|
Interface table have been detected since the monitor started or
|
|
since the previous access.
|
|
"""
|
|
|
|
def __init__(self, root_helper=None, respawn_interval=None):
|
|
super(SimpleInterfaceMonitor, self).__init__(
|
|
'Interface',
|
|
columns=['name', 'ofport'],
|
|
format='json',
|
|
root_helper=root_helper,
|
|
respawn_interval=respawn_interval,
|
|
)
|
|
self.data_received = False
|
|
if respawn_interval:
|
|
self._default_timeout = respawn_interval / 2
|
|
else:
|
|
self._default_timeout = 10
|
|
|
|
@property
|
|
def is_active(self):
|
|
return (self.data_received and
|
|
self._kill_event and
|
|
not self._kill_event.ready())
|
|
|
|
@property
|
|
def has_updates(self):
|
|
"""Indicate whether the ovsdb Interface table has been updated.
|
|
|
|
True will be returned if the monitor process is not active.
|
|
This 'failing open' minimizes the risk of falsely indicating
|
|
the absence of updates at the expense of potential false
|
|
positives.
|
|
"""
|
|
return bool(list(self.iter_stdout())) or not self.is_active
|
|
|
|
def start(self, block=False, timeout=None):
|
|
timeout = timeout or self._default_timeout
|
|
super(SimpleInterfaceMonitor, self).start()
|
|
if block:
|
|
eventlet.timeout.Timeout(timeout)
|
|
while not self.is_active:
|
|
eventlet.sleep()
|
|
|
|
def _kill(self, *args, **kwargs):
|
|
self.data_received = False
|
|
super(SimpleInterfaceMonitor, self)._kill(*args, **kwargs)
|
|
|
|
def _read_stdout(self):
|
|
data = super(SimpleInterfaceMonitor, self)._read_stdout()
|
|
if data and not self.data_received:
|
|
self.data_received = True
|
|
return data
|