github.com/ssdev-go/moby@v17.12.1-ce-rc2+incompatible/volume/store/restore.go (about)

     1  package store
     2  
     3  import (
     4  	"sync"
     5  
     6  	"github.com/boltdb/bolt"
     7  	"github.com/docker/docker/volume"
     8  	"github.com/docker/docker/volume/drivers"
     9  	"github.com/sirupsen/logrus"
    10  )
    11  
    12  // restore is called when a new volume store is created.
    13  // It's primary purpose is to ensure that all drivers' refcounts are set based
    14  // on known volumes after a restart.
    15  // This only attempts to track volumes that are actually stored in the on-disk db.
    16  // It does not probe the available drivers to find anything that may have been added
    17  // out of band.
    18  func (s *VolumeStore) restore() {
    19  	var ls []volumeMetadata
    20  	s.db.View(func(tx *bolt.Tx) error {
    21  		ls = listMeta(tx)
    22  		return nil
    23  	})
    24  
    25  	chRemove := make(chan *volumeMetadata, len(ls))
    26  	var wg sync.WaitGroup
    27  	for _, meta := range ls {
    28  		wg.Add(1)
    29  		// this is potentially a very slow operation, so do it in a goroutine
    30  		go func(meta volumeMetadata) {
    31  			defer wg.Done()
    32  
    33  			var v volume.Volume
    34  			var err error
    35  			if meta.Driver != "" {
    36  				v, err = lookupVolume(meta.Driver, meta.Name)
    37  				if err != nil && err != errNoSuchVolume {
    38  					logrus.WithError(err).WithField("driver", meta.Driver).WithField("volume", meta.Name).Warn("Error restoring volume")
    39  					return
    40  				}
    41  				if v == nil {
    42  					// doesn't exist in the driver, remove it from the db
    43  					chRemove <- &meta
    44  					return
    45  				}
    46  			} else {
    47  				v, err = s.getVolume(meta.Name)
    48  				if err != nil {
    49  					if err == errNoSuchVolume {
    50  						chRemove <- &meta
    51  					}
    52  					return
    53  				}
    54  
    55  				meta.Driver = v.DriverName()
    56  				if err := s.setMeta(v.Name(), meta); err != nil {
    57  					logrus.WithError(err).WithField("driver", meta.Driver).WithField("volume", v.Name()).Warn("Error updating volume metadata on restore")
    58  				}
    59  			}
    60  
    61  			// increment driver refcount
    62  			volumedrivers.CreateDriver(meta.Driver)
    63  
    64  			// cache the volume
    65  			s.globalLock.Lock()
    66  			s.options[v.Name()] = meta.Options
    67  			s.labels[v.Name()] = meta.Labels
    68  			s.names[v.Name()] = v
    69  			s.globalLock.Unlock()
    70  		}(meta)
    71  	}
    72  
    73  	wg.Wait()
    74  	close(chRemove)
    75  	s.db.Update(func(tx *bolt.Tx) error {
    76  		for meta := range chRemove {
    77  			if err := removeMeta(tx, meta.Name); err != nil {
    78  				logrus.WithField("volume", meta.Name).Warnf("Error removing stale entry from volume db: %v", err)
    79  			}
    80  		}
    81  		return nil
    82  	})
    83  }