Skip to content

Commit

Permalink
Merge pull request #493 from saschagrunert/layer-store-load-lock
Browse files Browse the repository at this point in the history
Remove locking from layer store creation
  • Loading branch information
rhatdan authored Jan 31, 2020
2 parents 4176c81 + dd3bd89 commit f9ce88b
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 21 deletions.
47 changes: 28 additions & 19 deletions layers.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,10 @@ type LayerStore interface {
// ApplyDiff reads a tarstream which was created by a previous call to Diff and
// applies its changes to a specified layer.
ApplyDiff(to string, diff io.Reader) (int64, error)

// LoadLocked wraps Load in a locked state. This means it loads the store
// and cleans-up invalid layers if needed.
LoadLocked() error
}

type layerStore struct {
Expand Down Expand Up @@ -346,39 +350,48 @@ func (r *layerStore) Load() error {
r.byname = names
r.bycompressedsum = compressedsums
r.byuncompressedsum = uncompressedsums

// Load and merge information about which layers are mounted, and where.
if r.IsReadWrite() {
r.mountsLockfile.RLock()
defer r.mountsLockfile.Unlock()
if err = r.loadMounts(); err != nil {
return err
}
}
// Last step: if we're writable, try to remove anything that a previous
// user of this storage area marked for deletion but didn't manage to
// actually delete.
if r.IsReadWrite() && r.Locked() {
for _, layer := range r.layers {
if layer.Flags == nil {
layer.Flags = make(map[string]interface{})
}
if cleanup, ok := layer.Flags[incompleteFlag]; ok {
if b, ok := cleanup.(bool); ok && b {
err = r.deleteInternal(layer.ID)
if err != nil {
break

// Last step: as we’re writable, try to remove anything that a previous
// user of this storage area marked for deletion but didn't manage to
// actually delete.
if r.Locked() {
for _, layer := range r.layers {
if layer.Flags == nil {
layer.Flags = make(map[string]interface{})
}
if cleanup, ok := layer.Flags[incompleteFlag]; ok {
if b, ok := cleanup.(bool); ok && b {
err = r.deleteInternal(layer.ID)
if err != nil {
break
}
shouldSave = true
}
shouldSave = true
}
}
}
if shouldSave {
return r.saveLayers()
}
}

return err
}

func (r *layerStore) LoadLocked() error {
r.lockfile.Lock()
defer r.lockfile.Unlock()
return r.Load()
}

func (r *layerStore) loadMounts() error {
mounts := make(map[string]*Layer)
mpath := r.mountspath()
Expand Down Expand Up @@ -487,8 +500,6 @@ func (s *store) newLayerStore(rundir string, layerdir string, driver drivers.Dri
if err != nil {
return nil, err
}
lockfile.Lock()
defer lockfile.Unlock()
mountsLockfile, err := GetLockfile(filepath.Join(rundir, "mountpoints.lock"))
if err != nil {
return nil, err
Expand Down Expand Up @@ -516,8 +527,6 @@ func newROLayerStore(rundir string, layerdir string, driver drivers.Driver) (ROL
if err != nil {
return nil, err
}
lockfile.RLock()
defer lockfile.Unlock()
rlstore := layerStore{
lockfile: lockfile,
mountsLockfile: nil,
Expand Down
10 changes: 8 additions & 2 deletions store.go
Original file line number Diff line number Diff line change
Expand Up @@ -2783,18 +2783,24 @@ func (s *store) ContainerParentOwners(id string) ([]int, []int, error) {
}

func (s *store) Layers() ([]Layer, error) {
var layers []Layer
lstore, err := s.LayerStore()
if err != nil {
return nil, err
}
if err := lstore.LoadLocked(); err != nil {
return nil, err
}
layers, err := lstore.Layers()
if err != nil {
return nil, err
}

lstores, err := s.ROLayerStores()
if err != nil {
return nil, err
}

for _, s := range append([]ROLayerStore{lstore}, lstores...) {
for _, s := range lstores {
store := s
store.RLock()
defer store.Unlock()
Expand Down

0 comments on commit f9ce88b

Please sign in to comment.