Add RWMutex lock into TruncIndex to fix race condition when inserting values

The idx.index array is overwritten when a new value is inserted to the index.
When two containers are created concurrently, their ids are inserted to the
index and one can overwrite the other leaving one of ids missing from the
index. Adding a RWMutex lock around read/write operations fixes this.

Docker-DCO-1.1-Signed-off-by: James Allen <jamesallen0108@gmail.com> (github: jpallen)
This commit is contained in:
James Allen 2014-01-15 17:29:46 +00:00
parent dbf249e239
commit 37fcbfa1f4

View file

@ -418,6 +418,7 @@ func GetTotalUsedFds() int {
// TruncIndex allows the retrieval of string identifiers by any of their unique prefixes.
// This is used to retrieve image and container IDs by more convenient shorthand prefixes.
type TruncIndex struct {
sync.RWMutex
index *suffixarray.Index
ids map[string]bool
bytes []byte
@ -432,6 +433,8 @@ func NewTruncIndex() *TruncIndex {
}
func (idx *TruncIndex) Add(id string) error {
idx.Lock()
defer idx.Unlock()
if strings.Contains(id, " ") {
return fmt.Errorf("Illegal character: ' '")
}
@ -445,6 +448,8 @@ func (idx *TruncIndex) Add(id string) error {
}
func (idx *TruncIndex) Delete(id string) error {
idx.Lock()
defer idx.Unlock()
if _, exists := idx.ids[id]; !exists {
return fmt.Errorf("No such id: %s", id)
}
@ -470,6 +475,8 @@ func (idx *TruncIndex) lookup(s string) (int, int, error) {
}
func (idx *TruncIndex) Get(s string) (string, error) {
idx.RLock()
defer idx.RUnlock()
before, after, err := idx.lookup(s)
//log.Printf("Get(%s) bytes=|%s| before=|%d| after=|%d|\n", s, idx.bytes, before, after)
if err != nil {