Avoid race condition when processing RowEvents

In https://review.opendev.org/#/c/753824/ ovsdbapp adds the ability
to pass a "frozen" object to the RowEventHandler so that if a
transaction is started from the main thread that changes the row,
it won't step on the values that the Event is trying to process.

This patch backports the needed ovsdbapp changes for
RowEventHandler which converts the row to a frozen_row.

Change-Id: I87489596e2ff224431f7e83f43a1725172ee0953
Related-Bug: #1896816
(cherry picked from commit ab6d4afd95)
This commit is contained in:
Terry Wilson 2020-09-23 20:32:33 +00:00
parent b634f4f623
commit aec9bc271e
2 changed files with 39 additions and 3 deletions

View File

@ -0,0 +1,36 @@
# Copyright 2021 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.
#
# We don't technically require ovsdbapp that has these fixes so
# just include them here for stable releases
try:
from ovsdbapp.backend.ovs_idl import idlutils
frozen_row = idlutils.frozen_row
except AttributeError:
def frozen_row(row):
return row._table.rows.IndexEntry(
uuid=row.uuid,
**{col: getattr(row, col)
for col in row._table.columns if hasattr(row, col)})
try:
from ovsdbapp.backend.ovs_idl import event as row_event
from ovsdbapp import event as ovsdb_event
RowEventHandler = row_event.RowEventHandler
except AttributeError:
class RowEventHandler(ovsdb_event.RowEventHandler):
def notify(self, event, row, updates=None):
row = frozen_row(row)
super().notify(event, row, updates)

View File

@ -27,7 +27,6 @@ from ovs.stream import Stream
from ovsdbapp.backend.ovs_idl import connection
from ovsdbapp.backend.ovs_idl import event as row_event
from ovsdbapp.backend.ovs_idl import idlutils
from ovsdbapp import event
from neutron.common.ovn import constants as ovn_const
from neutron.common.ovn import exceptions
@ -35,6 +34,7 @@ from neutron.common.ovn import hash_ring_manager
from neutron.common.ovn import utils
from neutron.conf.plugins.ml2.drivers.ovn import ovn_conf
from neutron.db import ovn_hash_ring_db
from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import backports
CONF = cfg.CONF
@ -358,7 +358,7 @@ class NeutronPgDropPortGroupCreated(row_event.WaitEvent):
self.event_name = 'PortGroupCreated'
class OvnDbNotifyHandler(event.RowEventHandler):
class OvnDbNotifyHandler(backports.RowEventHandler):
def __init__(self, driver):
super(OvnDbNotifyHandler, self).__init__()
self.driver = driver
@ -374,7 +374,7 @@ class Ml2OvnIdlBase(connection.OvsdbIdl):
class BaseOvnIdl(Ml2OvnIdlBase):
def __init__(self, remote, schema):
self.notify_handler = event.RowEventHandler()
self.notify_handler = backports.RowEventHandler()
super(BaseOvnIdl, self).__init__(remote, schema)
@classmethod