Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions neutron/notifiers/nova.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,9 @@ def send_events(self, batched_events):
try:
response = novaclient.server_external_events.create(
batched_events)
except ks_exceptions.EndpointNotFound:
LOG.exception("Nova endpoint not found, invalidating the session")
self.session.invalidate()
except nova_exceptions.NotFound:
LOG.debug("Nova returned NotFound for event: %s",
batched_events)
Expand Down
8 changes: 6 additions & 2 deletions neutron/plugins/ml2/drivers/mech_sriov/agent/pci_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,14 @@ def set_vf_state(self, vf_index, state, auto=False):
@param auto: set link_state to auto (0)
"""
ip = self.device(self.dev_name)
if auto:
# NOTE(ralonsoh): the state=False --> "disable" (2) has precedence over
# "auto" (0) and "enable" (1).
if state is False:
link_state = 2
elif auto:
link_state = 0
else:
link_state = 1 if state else 2
link_state = 1
vf_config = {'vf': vf_index, 'link_state': link_state}
ip.link.set_vf_feature(vf_config)

Expand Down
5 changes: 3 additions & 2 deletions neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import functools
import multiprocessing
import operator
import signal
import threading
import types
import uuid
Expand All @@ -43,6 +42,7 @@
from oslo_config import cfg
from oslo_db import exception as os_db_exc
from oslo_log import log
from oslo_service import service as oslo_service
from oslo_utils import timeutils
from ovsdbapp.backend.ovs_idl import idlutils

Expand Down Expand Up @@ -312,8 +312,9 @@ def _setup_hash_ring(self):
themselves to the hash ring.
"""
# Attempt to remove the node from the ring when the worker stops
sh = oslo_service.SignalHandler()
atexit.register(self._remove_node_from_hash_ring)
signal.signal(signal.SIGTERM, self._remove_node_from_hash_ring)
sh.add_handler("SIGTERM", self._remove_node_from_hash_ring)

admin_context = n_context.get_admin_context()
if not self._hash_ring_probe_event.is_set():
Expand Down
7 changes: 4 additions & 3 deletions neutron/plugins/ml2/ovo_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

import atexit
import queue
import signal
import threading
import traceback
import weakref
Expand All @@ -24,6 +23,7 @@
from neutron_lib import context as n_ctx
from neutron_lib.db import api as db_api
from oslo_log import log as logging
from oslo_service import service

from neutron.api.rpc.callbacks import events as rpc_events
from neutron.api.rpc.handlers import resources_rpc
Expand All @@ -38,8 +38,9 @@

def _setup_change_handlers_cleanup():
atexit.register(_ObjectChangeHandler.clean_up)
signal.signal(signal.SIGINT, _ObjectChangeHandler.clean_up)
signal.signal(signal.SIGTERM, _ObjectChangeHandler.clean_up)
sh = service.SignalHandler()
sh.add_handler("SIGINT", _ObjectChangeHandler.clean_up)
sh.add_handler("SIGTERM", _ObjectChangeHandler.clean_up)


class _ObjectChangeHandler(object):
Expand Down
12 changes: 11 additions & 1 deletion neutron/services/tag/tag_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,17 @@ def __new__(cls, *args, **kwargs):
def _extend_tags_dict(response_data, db_data):
if not directory.get_plugin(tagging.TAG_PLUGIN_TYPE):
return
tags = [tag_db.tag for tag_db in db_data.standard_attr.tags]
try:
tags = [tag_db.tag for tag_db in db_data.standard_attr.tags]
except AttributeError:
# NOTE(ralonsoh): this method can be called from a "list"
# operation. If one resource and its "standardattr" register is
# deleted concurrently, the "standard_attr" field retrieval will
# fail.
# The "list" operation is protected with a READER transaction
# context; however this is failing with the DB PostgreSQL backend.
# https://bugs.launchpad.net/neutron/+bug/2078787
tags = []
response_data['tags'] = tags

@db_api.CONTEXT_READER
Expand Down
10 changes: 10 additions & 0 deletions neutron/tests/unit/notifiers/test_nova.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,16 @@ def test_no_notification_notify_nova_on_port_data_changes_false(self):
{}, {})
self.assertFalse(send_events.called)

@mock.patch('novaclient.client.Client')
def test_nova_send_events_noendpoint_invalidate_session(self, mock_client):
create = mock_client().server_external_events.create
create.side_effect = ks_exc.EndpointNotFound
with mock.patch.object(self.nova_notifier.session,
'invalidate', return_value=True) as mock_sess:
self.nova_notifier.send_events([])
create.assert_called()
mock_sess.assert_called()

@mock.patch('novaclient.client.Client')
def test_nova_send_events_returns_bad_list(self, mock_client):
create = mock_client().server_external_events.create
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,29 @@ def test_get_vf_state_not_present(self):
self.assertEqual(pci_lib.LinkState.disable.name, result)

def test_set_vf_state(self):
# state=True, auto=False --> link_state=enable
self.pci_wrapper.set_vf_state(self.VF_INDEX, True)
vf = {'vf': self.VF_INDEX, 'link_state': 1}
self.mock_ip_device.link.set_vf_feature.assert_called_once_with(vf)

# state=False, auto=False --> link_state=disable
self.mock_ip_device.link.set_vf_feature.reset_mock()
self.pci_wrapper.set_vf_state(self.VF_INDEX, False)
vf = {'vf': self.VF_INDEX, 'link_state': 2}
self.mock_ip_device.link.set_vf_feature.assert_called_once_with(vf)

# state=True, auto=True --> link_state=auto
self.mock_ip_device.link.set_vf_feature.reset_mock()
self.pci_wrapper.set_vf_state(self.VF_INDEX, False, auto=True)
self.pci_wrapper.set_vf_state(self.VF_INDEX, True, auto=True)
vf = {'vf': self.VF_INDEX, 'link_state': 0}
self.mock_ip_device.link.set_vf_feature.assert_called_once_with(vf)

# state=False, auto=True --> link_state=disable
self.mock_ip_device.link.set_vf_feature.reset_mock()
self.pci_wrapper.set_vf_state(self.VF_INDEX, False, auto=True)
vf = {'vf': self.VF_INDEX, 'link_state': 2}
self.mock_ip_device.link.set_vf_feature.assert_called_once_with(vf)

def test_set_vf_spoofcheck(self):
self.pci_wrapper.set_vf_spoofcheck(self.VF_INDEX, True)
vf = {'vf': self.VF_INDEX, 'spoofchk': 1}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
security:
- |
A ML2/SR-IOV port with status=DOWN will always set the VF link state to
"disable", regardless of the ``propagate_uplink_status`` port field value.
The port disabling, to stop any transmission, has precedence over the
link state "auto" value.
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ oslo.privsep>=2.3.0 # Apache-2.0
oslo.reports>=1.18.0 # Apache-2.0
oslo.rootwrap>=5.15.0 # Apache-2.0
oslo.serialization>=2.25.0 # Apache-2.0
oslo.service>=2.8.0 # Apache-2.0
oslo.service>=3.1.2 # Apache-2.0
oslo.upgradecheck>=1.3.0 # Apache-2.0
oslo.utils>=4.8.0 # Apache-2.0
oslo.versionedobjects>=1.35.1 # Apache-2.0
Expand Down