github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/volume/service/restore.go (about)

     1  package service // import "github.com/docker/docker/volume/service"
     2  
     3  import (
     4  	"context"
     5  	"sync"
     6  
     7  	"github.com/docker/docker/volume"
     8  	"github.com/sirupsen/logrus"
     9  	bolt "go.etcd.io/bbolt"
    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  	ctx := context.Background()
    25  
    26  	chRemove := make(chan *volumeMetadata, len(ls))
    27  	var wg sync.WaitGroup
    28  	for _, meta := range ls {
    29  		wg.Add(1)
    30  		// this is potentially a very slow operation, so do it in a goroutine
    31  		go func(meta volumeMetadata) {
    32  			defer wg.Done()
    33  
    34  			var v volume.Volume
    35  			var err error
    36  			if meta.Driver != "" {
    37  				v, err = lookupVolume(ctx, s.drivers, meta.Driver, meta.Name)
    38  				if err != nil && err != errNoSuchVolume {
    39  					logrus.WithError(err).WithField("driver", meta.Driver).WithField("volume", meta.Name).Warn("Error restoring volume")
    40  					return
    41  				}
    42  				if v == nil {
    43  					// doesn't exist in the driver, remove it from the db
    44  					chRemove <- &meta
    45  					return
    46  				}
    47  			} else {
    48  				v, err = s.getVolume(ctx, meta.Name, meta.Driver)
    49  				if err != nil {
    50  					if err == errNoSuchVolume {
    51  						chRemove <- &meta
    52  					}
    53  					return
    54  				}
    55  
    56  				meta.Driver = v.DriverName()
    57  				if err := s.setMeta(v.Name(), meta); err != nil {
    58  					logrus.WithError(err).WithField("driver", meta.Driver).WithField("volume", v.Name()).Warn("Error updating volume metadata on restore")
    59  				}
    60  			}
    61  
    62  			// increment driver refcount
    63  			s.drivers.CreateDriver(meta.Driver)
    64  
    65  			// cache the volume
    66  			s.globalLock.Lock()
    67  			s.options[v.Name()] = meta.Options
    68  			s.labels[v.Name()] = meta.Labels
    69  			s.names[v.Name()] = v
    70  			s.refs[v.Name()] = make(map[string]struct{})
    71  			s.globalLock.Unlock()
    72  		}(meta)
    73  	}
    74  
    75  	wg.Wait()
    76  	close(chRemove)
    77  	s.db.Update(func(tx *bolt.Tx) error {
    78  		for meta := range chRemove {
    79  			if err := removeMeta(tx, meta.Name); err != nil {
    80  				logrus.WithField("volume", meta.Name).Warnf("Error removing stale entry from volume db: %v", err)
    81  			}
    82  		}
    83  		return nil
    84  	})
    85  }