Skip to content

Commit 10751cc

Browse files
committed
Fix race conditions in ovsdbdriver cache handling
1 parent 509af00 commit 10751cc

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

drivers/ovsdbDriver.go

+22-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type OvsdbDriver struct {
3737
bridgeName string // Name of the bridge we are operating on
3838
ovs *libovsdb.OvsdbClient
3939
cache map[string]map[libovsdb.UUID]libovsdb.Row
40-
cacheLock sync.Mutex
40+
cacheLock sync.RWMutex // lock to protect cache accesses
4141
}
4242

4343
// NewOvsdbDriver creates a new OVSDB driver instance.
@@ -105,6 +105,9 @@ func (d *OvsdbDriver) Delete() error {
105105
}
106106

107107
func (d *OvsdbDriver) getRootUUID() libovsdb.UUID {
108+
d.cacheLock.RLock()
109+
defer d.cacheLock.RUnlock()
110+
108111
for uuid := range d.cache[rootTable] {
109112
return uuid
110113
}
@@ -248,6 +251,10 @@ func (d *OvsdbDriver) GetPortOrIntfNameFromID(id string, isPort bool) (string, e
248251
table = interfaceTable
249252
}
250253

254+
d.cacheLock.RLock()
255+
defer d.cacheLock.RUnlock()
256+
257+
// walk thru all ports
251258
for _, row := range d.cache[table] {
252259
if extIDs, ok := row.Fields["external_ids"]; ok {
253260
extIDMap := extIDs.(libovsdb.OvsMap).GoMap
@@ -353,13 +360,15 @@ func (d *OvsdbDriver) DeletePort(intfName string) error {
353360
}
354361

355362
// also fetch the port-uuid from cache
363+
d.cacheLock.RLock()
356364
for uuid, row := range d.cache["Port"] {
357365
name := row.Fields["name"].(string)
358366
if name == intfName {
359367
portUUID = []libovsdb.UUID{uuid}
360368
break
361369
}
362370
}
371+
d.cacheLock.RUnlock()
363372

364373
// mutate the Ports column of the row in the Bridge table
365374
mutateSet, _ := libovsdb.NewOvsSet(portUUID)
@@ -498,6 +507,10 @@ func (d *OvsdbDriver) RemoveController(target string) error {
498507

499508
// IsControllerPresent : Check if Controller already exists
500509
func (d *OvsdbDriver) IsControllerPresent(target string) bool {
510+
d.cacheLock.RLock()
511+
defer d.cacheLock.RUnlock()
512+
513+
// walk the local cache
501514
for tName, table := range d.cache {
502515
if tName == "Controller" {
503516
for _, row := range table {
@@ -519,6 +532,10 @@ func (d *OvsdbDriver) IsControllerPresent(target string) bool {
519532

520533
// IsPortNamePresent checks if port already exists in OVS bridge
521534
func (d *OvsdbDriver) IsPortNamePresent(intfName string) bool {
535+
d.cacheLock.RLock()
536+
defer d.cacheLock.RUnlock()
537+
538+
// walk the local cache
522539
for tName, table := range d.cache {
523540
if tName == "Port" {
524541
for _, row := range table {
@@ -572,6 +589,10 @@ func (d *OvsdbDriver) GetOfpPortNo(intfName string) (uint32, error) {
572589

573590
// IsVtepPresent checks if VTEP already exists
574591
func (d *OvsdbDriver) IsVtepPresent(remoteIP string) (bool, string) {
592+
d.cacheLock.RLock()
593+
defer d.cacheLock.RUnlock()
594+
595+
// walk the local cache
575596
for tName, table := range d.cache {
576597
if tName == "Interface" {
577598
for _, row := range table {

drivers/ovsdriver.go

+6
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"os"
2323
"strconv"
2424
"strings"
25+
"sync"
2526

2627
log "github.com/Sirupsen/logrus"
2728
"github.com/contiv/ofnet"
@@ -75,9 +76,14 @@ type OvsDriver struct {
7576
oper OvsDriverOperState // Oper state of the driver
7677
localIP string // Local IP address
7778
switchDb map[string]*OvsSwitch // OVS switch instances
79+
lock sync.Mutex // lock for modifying shared state
7880
}
7981

8082
func (d *OvsDriver) getIntfName() (string, error) {
83+
// take a lock for modifying shared state
84+
d.lock.Lock()
85+
defer d.lock.Unlock()
86+
8187
// get the next available port number
8288
for i := 0; i < maxIntfRetry; i++ {
8389
// Pick next port number

0 commit comments

Comments
 (0)