github.com/toplink-cn/moby@v0.0.0-20240305205811-460b4aebdf81/layer/layer_store.go (about)

     1  package layer // import "github.com/docker/docker/layer"
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  	"os"
     9  	"path/filepath"
    10  	"sync"
    11  
    12  	"github.com/containerd/log"
    13  	"github.com/docker/distribution"
    14  	"github.com/docker/docker/daemon/graphdriver"
    15  	"github.com/docker/docker/pkg/idtools"
    16  	"github.com/docker/docker/pkg/plugingetter"
    17  	"github.com/docker/docker/pkg/stringid"
    18  	"github.com/moby/locker"
    19  	"github.com/opencontainers/go-digest"
    20  	"github.com/vbatts/tar-split/tar/asm"
    21  	"github.com/vbatts/tar-split/tar/storage"
    22  )
    23  
    24  // maxLayerDepth represents the maximum number of
    25  // layers which can be chained together. 125 was
    26  // chosen to account for the 127 max in some
    27  // graphdrivers plus the 2 additional layers
    28  // used to create a rwlayer.
    29  const maxLayerDepth = 125
    30  
    31  type layerStore struct {
    32  	store       *fileMetadataStore
    33  	driver      graphdriver.Driver
    34  	useTarSplit bool
    35  
    36  	layerMap map[ChainID]*roLayer
    37  	layerL   sync.Mutex
    38  
    39  	mounts map[string]*mountedLayer
    40  	mountL sync.Mutex
    41  
    42  	// protect *RWLayer() methods from operating on the same name/id
    43  	locker *locker.Locker
    44  }
    45  
    46  // StoreOptions are the options used to create a new Store instance
    47  type StoreOptions struct {
    48  	Root                      string
    49  	MetadataStorePathTemplate string
    50  	GraphDriver               string
    51  	GraphDriverOptions        []string
    52  	IDMapping                 idtools.IdentityMapping
    53  	PluginGetter              plugingetter.PluginGetter
    54  	ExperimentalEnabled       bool
    55  }
    56  
    57  // NewStoreFromOptions creates a new Store instance
    58  func NewStoreFromOptions(options StoreOptions) (Store, error) {
    59  	driver, err := graphdriver.New(options.GraphDriver, options.PluginGetter, graphdriver.Options{
    60  		Root:                options.Root,
    61  		DriverOptions:       options.GraphDriverOptions,
    62  		IDMap:               options.IDMapping,
    63  		ExperimentalEnabled: options.ExperimentalEnabled,
    64  	})
    65  	if err != nil {
    66  		if options.GraphDriver != "" {
    67  			return nil, fmt.Errorf("error initializing graphdriver: %v: %s", err, options.GraphDriver)
    68  		}
    69  		return nil, fmt.Errorf("error initializing graphdriver: %v", err)
    70  	}
    71  	log.G(context.TODO()).Debugf("Initialized graph driver %s", driver)
    72  
    73  	root := fmt.Sprintf(options.MetadataStorePathTemplate, driver)
    74  
    75  	return newStoreFromGraphDriver(root, driver)
    76  }
    77  
    78  // newStoreFromGraphDriver creates a new Store instance using the provided
    79  // metadata store and graph driver. The metadata store will be used to restore
    80  // the Store.
    81  func newStoreFromGraphDriver(root string, driver graphdriver.Driver) (Store, error) {
    82  	caps := graphdriver.Capabilities{}
    83  	if capDriver, ok := driver.(graphdriver.CapabilityDriver); ok {
    84  		caps = capDriver.Capabilities()
    85  	}
    86  
    87  	ms, err := newFSMetadataStore(root)
    88  	if err != nil {
    89  		return nil, err
    90  	}
    91  
    92  	ls := &layerStore{
    93  		store:       ms,
    94  		driver:      driver,
    95  		layerMap:    map[ChainID]*roLayer{},
    96  		mounts:      map[string]*mountedLayer{},
    97  		locker:      locker.New(),
    98  		useTarSplit: !caps.ReproducesExactDiffs,
    99  	}
   100  
   101  	ids, mounts, err := ms.List()
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  
   106  	for _, id := range ids {
   107  		l, err := ls.loadLayer(id)
   108  		if err != nil {
   109  			log.G(context.TODO()).Debugf("Failed to load layer %s: %s", id, err)
   110  			continue
   111  		}
   112  		if l.parent != nil {
   113  			l.parent.referenceCount++
   114  		}
   115  	}
   116  
   117  	for _, mount := range mounts {
   118  		if err := ls.loadMount(mount); err != nil {
   119  			log.G(context.TODO()).Debugf("Failed to load mount %s: %s", mount, err)
   120  		}
   121  	}
   122  
   123  	return ls, nil
   124  }
   125  
   126  func (ls *layerStore) Driver() graphdriver.Driver {
   127  	return ls.driver
   128  }
   129  
   130  func (ls *layerStore) loadLayer(layer ChainID) (*roLayer, error) {
   131  	cl, ok := ls.layerMap[layer]
   132  	if ok {
   133  		return cl, nil
   134  	}
   135  
   136  	diff, err := ls.store.GetDiffID(layer)
   137  	if err != nil {
   138  		return nil, fmt.Errorf("failed to get diff id for %s: %s", layer, err)
   139  	}
   140  
   141  	size, err := ls.store.GetSize(layer)
   142  	if err != nil {
   143  		return nil, fmt.Errorf("failed to get size for %s: %s", layer, err)
   144  	}
   145  
   146  	cacheID, err := ls.store.GetCacheID(layer)
   147  	if err != nil {
   148  		return nil, fmt.Errorf("failed to get cache id for %s: %s", layer, err)
   149  	}
   150  
   151  	parent, err := ls.store.GetParent(layer)
   152  	if err != nil {
   153  		return nil, fmt.Errorf("failed to get parent for %s: %s", layer, err)
   154  	}
   155  
   156  	descriptor, err := ls.store.GetDescriptor(layer)
   157  	if err != nil {
   158  		return nil, fmt.Errorf("failed to get descriptor for %s: %s", layer, err)
   159  	}
   160  
   161  	cl = &roLayer{
   162  		chainID:    layer,
   163  		diffID:     diff,
   164  		size:       size,
   165  		cacheID:    cacheID,
   166  		layerStore: ls,
   167  		references: map[Layer]struct{}{},
   168  		descriptor: descriptor,
   169  	}
   170  
   171  	if parent != "" {
   172  		p, err := ls.loadLayer(parent)
   173  		if err != nil {
   174  			return nil, err
   175  		}
   176  		cl.parent = p
   177  	}
   178  
   179  	ls.layerMap[cl.chainID] = cl
   180  
   181  	return cl, nil
   182  }
   183  
   184  func (ls *layerStore) loadMount(mount string) error {
   185  	ls.mountL.Lock()
   186  	defer ls.mountL.Unlock()
   187  	if _, ok := ls.mounts[mount]; ok {
   188  		return nil
   189  	}
   190  
   191  	mountID, err := ls.store.GetMountID(mount)
   192  	if err != nil {
   193  		return err
   194  	}
   195  
   196  	initID, err := ls.store.GetInitID(mount)
   197  	if err != nil {
   198  		return err
   199  	}
   200  
   201  	parent, err := ls.store.GetMountParent(mount)
   202  	if err != nil {
   203  		return err
   204  	}
   205  
   206  	ml := &mountedLayer{
   207  		name:       mount,
   208  		mountID:    mountID,
   209  		initID:     initID,
   210  		layerStore: ls,
   211  		references: map[RWLayer]*referencedRWLayer{},
   212  	}
   213  
   214  	if parent != "" {
   215  		p, err := ls.loadLayer(parent)
   216  		if err != nil {
   217  			return err
   218  		}
   219  		ml.parent = p
   220  
   221  		p.referenceCount++
   222  	}
   223  
   224  	ls.mounts[ml.name] = ml
   225  
   226  	return nil
   227  }
   228  
   229  func (ls *layerStore) applyTar(tx *fileMetadataTransaction, ts io.Reader, parent string, layer *roLayer) error {
   230  	digester := digest.Canonical.Digester()
   231  	tr := io.TeeReader(ts, digester.Hash())
   232  
   233  	rdr := tr
   234  	if ls.useTarSplit {
   235  		tsw, err := tx.TarSplitWriter(true)
   236  		if err != nil {
   237  			return err
   238  		}
   239  		metaPacker := storage.NewJSONPacker(tsw)
   240  		defer tsw.Close()
   241  
   242  		// we're passing nil here for the file putter, because the ApplyDiff will
   243  		// handle the extraction of the archive
   244  		rdr, err = asm.NewInputTarStream(tr, metaPacker, nil)
   245  		if err != nil {
   246  			return err
   247  		}
   248  	}
   249  
   250  	applySize, err := ls.driver.ApplyDiff(layer.cacheID, parent, rdr)
   251  	// discard trailing data but ensure metadata is picked up to reconstruct stream
   252  	// unconditionally call io.Copy here before checking err to ensure the resources
   253  	// allocated by NewInputTarStream above are always released
   254  	io.Copy(io.Discard, rdr) // ignore error as reader may be closed
   255  	if err != nil {
   256  		return err
   257  	}
   258  
   259  	layer.size = applySize
   260  	layer.diffID = DiffID(digester.Digest())
   261  
   262  	log.G(context.TODO()).Debugf("Applied tar %s to %s, size: %d", layer.diffID, layer.cacheID, applySize)
   263  
   264  	return nil
   265  }
   266  
   267  func (ls *layerStore) Register(ts io.Reader, parent ChainID) (Layer, error) {
   268  	return ls.registerWithDescriptor(ts, parent, distribution.Descriptor{})
   269  }
   270  
   271  func (ls *layerStore) registerWithDescriptor(ts io.Reader, parent ChainID, descriptor distribution.Descriptor) (Layer, error) {
   272  	// cErr is used to hold the error which will always trigger
   273  	// cleanup of creates sources but may not be an error returned
   274  	// to the caller (already exists).
   275  	var cErr error
   276  	var pid string
   277  	var p *roLayer
   278  
   279  	if string(parent) != "" {
   280  		ls.layerL.Lock()
   281  		p = ls.get(parent)
   282  		ls.layerL.Unlock()
   283  		if p == nil {
   284  			return nil, ErrLayerDoesNotExist
   285  		}
   286  		pid = p.cacheID
   287  		// Release parent chain if error
   288  		defer func() {
   289  			if cErr != nil {
   290  				ls.layerL.Lock()
   291  				ls.releaseLayer(p)
   292  				ls.layerL.Unlock()
   293  			}
   294  		}()
   295  		if p.depth() >= maxLayerDepth {
   296  			cErr = ErrMaxDepthExceeded
   297  			return nil, cErr
   298  		}
   299  	}
   300  
   301  	// Create new roLayer
   302  	layer := &roLayer{
   303  		parent:         p,
   304  		cacheID:        stringid.GenerateRandomID(),
   305  		referenceCount: 1,
   306  		layerStore:     ls,
   307  		references:     map[Layer]struct{}{},
   308  		descriptor:     descriptor,
   309  	}
   310  
   311  	if cErr = ls.driver.Create(layer.cacheID, pid, nil); cErr != nil {
   312  		return nil, cErr
   313  	}
   314  
   315  	tx, cErr := ls.store.StartTransaction()
   316  	if cErr != nil {
   317  		return nil, cErr
   318  	}
   319  
   320  	defer func() {
   321  		if cErr != nil {
   322  			log.G(context.TODO()).Debugf("Cleaning up layer %s: %v", layer.cacheID, cErr)
   323  			if err := ls.driver.Remove(layer.cacheID); err != nil {
   324  				log.G(context.TODO()).Errorf("Error cleaning up cache layer %s: %v", layer.cacheID, err)
   325  			}
   326  			if err := tx.Cancel(); err != nil {
   327  				log.G(context.TODO()).Errorf("Error canceling metadata transaction %q: %s", tx.String(), err)
   328  			}
   329  		}
   330  	}()
   331  
   332  	if cErr = ls.applyTar(tx, ts, pid, layer); cErr != nil {
   333  		return nil, cErr
   334  	}
   335  
   336  	if layer.parent == nil {
   337  		layer.chainID = ChainID(layer.diffID)
   338  	} else {
   339  		layer.chainID = createChainIDFromParent(layer.parent.chainID, layer.diffID)
   340  	}
   341  
   342  	if cErr = storeLayer(tx, layer); cErr != nil {
   343  		return nil, cErr
   344  	}
   345  
   346  	ls.layerL.Lock()
   347  	defer ls.layerL.Unlock()
   348  
   349  	if existingLayer := ls.get(layer.chainID); existingLayer != nil {
   350  		// Set error for cleanup, but do not return the error
   351  		cErr = errors.New("layer already exists")
   352  		return existingLayer.getReference(), nil
   353  	}
   354  
   355  	if cErr = tx.Commit(layer.chainID); cErr != nil {
   356  		return nil, cErr
   357  	}
   358  
   359  	ls.layerMap[layer.chainID] = layer
   360  
   361  	return layer.getReference(), nil
   362  }
   363  
   364  func (ls *layerStore) get(layer ChainID) *roLayer {
   365  	l, ok := ls.layerMap[layer]
   366  	if !ok {
   367  		return nil
   368  	}
   369  	l.referenceCount++
   370  	return l
   371  }
   372  
   373  func (ls *layerStore) Get(l ChainID) (Layer, error) {
   374  	ls.layerL.Lock()
   375  	defer ls.layerL.Unlock()
   376  
   377  	layer := ls.get(l)
   378  	if layer == nil {
   379  		return nil, ErrLayerDoesNotExist
   380  	}
   381  
   382  	return layer.getReference(), nil
   383  }
   384  
   385  func (ls *layerStore) Map() map[ChainID]Layer {
   386  	ls.layerL.Lock()
   387  	defer ls.layerL.Unlock()
   388  
   389  	layers := map[ChainID]Layer{}
   390  
   391  	for k, v := range ls.layerMap {
   392  		layers[k] = v
   393  	}
   394  
   395  	return layers
   396  }
   397  
   398  func (ls *layerStore) deleteLayer(layer *roLayer, metadata *Metadata) error {
   399  	// Rename layer digest folder first so we detect orphan layer(s)
   400  	// if ls.driver.Remove fails
   401  	var dir string
   402  	for {
   403  		dgst := digest.Digest(layer.chainID)
   404  		tmpID := fmt.Sprintf("%s-%s-removing", dgst.Encoded(), stringid.GenerateRandomID())
   405  		dir = filepath.Join(ls.store.root, string(dgst.Algorithm()), tmpID)
   406  		err := os.Rename(ls.store.getLayerDirectory(layer.chainID), dir)
   407  		if os.IsExist(err) {
   408  			continue
   409  		}
   410  		break
   411  	}
   412  	err := ls.driver.Remove(layer.cacheID)
   413  	if err != nil {
   414  		return err
   415  	}
   416  	err = os.RemoveAll(dir)
   417  	if err != nil {
   418  		return err
   419  	}
   420  	metadata.DiffID = layer.diffID
   421  	metadata.ChainID = layer.chainID
   422  	metadata.Size = layer.Size()
   423  	if err != nil {
   424  		return err
   425  	}
   426  	metadata.DiffSize = layer.size
   427  
   428  	return nil
   429  }
   430  
   431  func (ls *layerStore) releaseLayer(l *roLayer) ([]Metadata, error) {
   432  	depth := 0
   433  	removed := []Metadata{}
   434  	for {
   435  		if l.referenceCount == 0 {
   436  			panic("layer not retained")
   437  		}
   438  		l.referenceCount--
   439  		if l.referenceCount != 0 {
   440  			return removed, nil
   441  		}
   442  
   443  		if len(removed) == 0 && depth > 0 {
   444  			panic("cannot remove layer with child")
   445  		}
   446  		if l.hasReferences() {
   447  			panic("cannot delete referenced layer")
   448  		}
   449  		// Remove layer from layer map first so it is not considered to exist
   450  		// when if ls.deleteLayer fails.
   451  		delete(ls.layerMap, l.chainID)
   452  
   453  		var metadata Metadata
   454  		if err := ls.deleteLayer(l, &metadata); err != nil {
   455  			return nil, err
   456  		}
   457  		removed = append(removed, metadata)
   458  
   459  		if l.parent == nil {
   460  			return removed, nil
   461  		}
   462  
   463  		depth++
   464  		l = l.parent
   465  	}
   466  }
   467  
   468  func (ls *layerStore) Release(l Layer) ([]Metadata, error) {
   469  	ls.layerL.Lock()
   470  	defer ls.layerL.Unlock()
   471  	layer, ok := ls.layerMap[l.ChainID()]
   472  	if !ok {
   473  		return []Metadata{}, nil
   474  	}
   475  	if !layer.hasReference(l) {
   476  		return nil, ErrLayerNotRetained
   477  	}
   478  
   479  	layer.deleteReference(l)
   480  
   481  	return ls.releaseLayer(layer)
   482  }
   483  
   484  func (ls *layerStore) CreateRWLayer(name string, parent ChainID, opts *CreateRWLayerOpts) (_ RWLayer, err error) {
   485  	var (
   486  		storageOpt map[string]string
   487  		initFunc   MountInit
   488  		mountLabel string
   489  	)
   490  
   491  	if opts != nil {
   492  		mountLabel = opts.MountLabel
   493  		storageOpt = opts.StorageOpt
   494  		initFunc = opts.InitFunc
   495  	}
   496  
   497  	ls.locker.Lock(name)
   498  	defer ls.locker.Unlock(name)
   499  
   500  	ls.mountL.Lock()
   501  	_, ok := ls.mounts[name]
   502  	ls.mountL.Unlock()
   503  	if ok {
   504  		return nil, ErrMountNameConflict
   505  	}
   506  
   507  	var pid string
   508  	var p *roLayer
   509  	if string(parent) != "" {
   510  		ls.layerL.Lock()
   511  		p = ls.get(parent)
   512  		ls.layerL.Unlock()
   513  		if p == nil {
   514  			return nil, ErrLayerDoesNotExist
   515  		}
   516  		pid = p.cacheID
   517  
   518  		// Release parent chain if error
   519  		defer func() {
   520  			if err != nil {
   521  				ls.layerL.Lock()
   522  				ls.releaseLayer(p)
   523  				ls.layerL.Unlock()
   524  			}
   525  		}()
   526  	}
   527  
   528  	m := &mountedLayer{
   529  		name:       name,
   530  		parent:     p,
   531  		mountID:    ls.mountID(name),
   532  		layerStore: ls,
   533  		references: map[RWLayer]*referencedRWLayer{},
   534  	}
   535  
   536  	if initFunc != nil {
   537  		pid, err = ls.initMount(m.mountID, pid, mountLabel, initFunc, storageOpt)
   538  		if err != nil {
   539  			return
   540  		}
   541  		m.initID = pid
   542  	}
   543  
   544  	createOpts := &graphdriver.CreateOpts{
   545  		StorageOpt: storageOpt,
   546  	}
   547  
   548  	if err = ls.driver.CreateReadWrite(m.mountID, pid, createOpts); err != nil {
   549  		return
   550  	}
   551  	if err = ls.saveMount(m); err != nil {
   552  		return
   553  	}
   554  
   555  	return m.getReference(), nil
   556  }
   557  
   558  func (ls *layerStore) GetRWLayer(id string) (RWLayer, error) {
   559  	ls.locker.Lock(id)
   560  	defer ls.locker.Unlock(id)
   561  
   562  	ls.mountL.Lock()
   563  	mount := ls.mounts[id]
   564  	ls.mountL.Unlock()
   565  	if mount == nil {
   566  		return nil, ErrMountDoesNotExist
   567  	}
   568  
   569  	return mount.getReference(), nil
   570  }
   571  
   572  func (ls *layerStore) GetMountID(id string) (string, error) {
   573  	ls.mountL.Lock()
   574  	mount := ls.mounts[id]
   575  	ls.mountL.Unlock()
   576  
   577  	if mount == nil {
   578  		return "", ErrMountDoesNotExist
   579  	}
   580  	log.G(context.TODO()).Debugf("GetMountID id: %s -> mountID: %s", id, mount.mountID)
   581  
   582  	return mount.mountID, nil
   583  }
   584  
   585  func (ls *layerStore) ReleaseRWLayer(l RWLayer) ([]Metadata, error) {
   586  	name := l.Name()
   587  	ls.locker.Lock(name)
   588  	defer ls.locker.Unlock(name)
   589  
   590  	ls.mountL.Lock()
   591  	m := ls.mounts[name]
   592  	ls.mountL.Unlock()
   593  	if m == nil {
   594  		return []Metadata{}, nil
   595  	}
   596  
   597  	if err := m.deleteReference(l); err != nil {
   598  		return nil, err
   599  	}
   600  
   601  	if m.hasReferences() {
   602  		return []Metadata{}, nil
   603  	}
   604  
   605  	if err := ls.driver.Remove(m.mountID); err != nil {
   606  		log.G(context.TODO()).Errorf("Error removing mounted layer %s: %s", m.name, err)
   607  		m.retakeReference(l)
   608  		return nil, err
   609  	}
   610  
   611  	if m.initID != "" {
   612  		if err := ls.driver.Remove(m.initID); err != nil {
   613  			log.G(context.TODO()).Errorf("Error removing init layer %s: %s", m.name, err)
   614  			m.retakeReference(l)
   615  			return nil, err
   616  		}
   617  	}
   618  
   619  	if err := ls.store.RemoveMount(m.name); err != nil {
   620  		log.G(context.TODO()).Errorf("Error removing mount metadata: %s: %s", m.name, err)
   621  		m.retakeReference(l)
   622  		return nil, err
   623  	}
   624  
   625  	ls.mountL.Lock()
   626  	delete(ls.mounts, name)
   627  	ls.mountL.Unlock()
   628  
   629  	ls.layerL.Lock()
   630  	defer ls.layerL.Unlock()
   631  	if m.parent != nil {
   632  		return ls.releaseLayer(m.parent)
   633  	}
   634  
   635  	return []Metadata{}, nil
   636  }
   637  
   638  func (ls *layerStore) saveMount(mount *mountedLayer) error {
   639  	if err := ls.store.SetMountID(mount.name, mount.mountID); err != nil {
   640  		return err
   641  	}
   642  
   643  	if mount.initID != "" {
   644  		if err := ls.store.SetInitID(mount.name, mount.initID); err != nil {
   645  			return err
   646  		}
   647  	}
   648  
   649  	if mount.parent != nil {
   650  		if err := ls.store.SetMountParent(mount.name, mount.parent.chainID); err != nil {
   651  			return err
   652  		}
   653  	}
   654  
   655  	ls.mountL.Lock()
   656  	ls.mounts[mount.name] = mount
   657  	ls.mountL.Unlock()
   658  
   659  	return nil
   660  }
   661  
   662  func (ls *layerStore) initMount(graphID, parent, mountLabel string, initFunc MountInit, storageOpt map[string]string) (string, error) {
   663  	// Use "<graph-id>-init" to maintain compatibility with graph drivers
   664  	// which are expecting this layer with this special name. If all
   665  	// graph drivers can be updated to not rely on knowing about this layer
   666  	// then the initID should be randomly generated.
   667  	initID := fmt.Sprintf("%s-init", graphID)
   668  
   669  	createOpts := &graphdriver.CreateOpts{
   670  		MountLabel: mountLabel,
   671  		StorageOpt: storageOpt,
   672  	}
   673  
   674  	if err := ls.driver.CreateReadWrite(initID, parent, createOpts); err != nil {
   675  		return "", err
   676  	}
   677  	p, err := ls.driver.Get(initID, "")
   678  	if err != nil {
   679  		return "", err
   680  	}
   681  
   682  	if err := initFunc(p); err != nil {
   683  		ls.driver.Put(initID)
   684  		return "", err
   685  	}
   686  
   687  	if err := ls.driver.Put(initID); err != nil {
   688  		return "", err
   689  	}
   690  
   691  	return initID, nil
   692  }
   693  
   694  func (ls *layerStore) getTarStream(rl *roLayer) (io.ReadCloser, error) {
   695  	if !ls.useTarSplit {
   696  		var parentCacheID string
   697  		if rl.parent != nil {
   698  			parentCacheID = rl.parent.cacheID
   699  		}
   700  
   701  		return ls.driver.Diff(rl.cacheID, parentCacheID)
   702  	}
   703  
   704  	r, err := ls.store.TarSplitReader(rl.chainID)
   705  	if err != nil {
   706  		return nil, err
   707  	}
   708  
   709  	pr, pw := io.Pipe()
   710  	go func() {
   711  		err := ls.assembleTarTo(rl.cacheID, r, nil, pw)
   712  		if err != nil {
   713  			pw.CloseWithError(err)
   714  		} else {
   715  			pw.Close()
   716  		}
   717  	}()
   718  
   719  	return pr, nil
   720  }
   721  
   722  func (ls *layerStore) assembleTarTo(graphID string, metadata io.ReadCloser, size *int64, w io.Writer) error {
   723  	diffDriver, ok := ls.driver.(graphdriver.DiffGetterDriver)
   724  	if !ok {
   725  		diffDriver = &naiveDiffPathDriver{ls.driver}
   726  	}
   727  
   728  	defer metadata.Close()
   729  
   730  	// get our relative path to the container
   731  	fileGetCloser, err := diffDriver.DiffGetter(graphID)
   732  	if err != nil {
   733  		return err
   734  	}
   735  	defer fileGetCloser.Close()
   736  
   737  	metaUnpacker := storage.NewJSONUnpacker(metadata)
   738  	upackerCounter := &unpackSizeCounter{metaUnpacker, size}
   739  	log.G(context.TODO()).Debugf("Assembling tar data for %s", graphID)
   740  	return asm.WriteOutputTarStream(fileGetCloser, upackerCounter, w)
   741  }
   742  
   743  func (ls *layerStore) Cleanup() error {
   744  	orphanLayers, err := ls.store.getOrphan()
   745  	if err != nil {
   746  		log.G(context.TODO()).WithError(err).Error("cannot get orphan layers")
   747  	}
   748  	if len(orphanLayers) > 0 {
   749  		log.G(context.TODO()).Debugf("found %v orphan layers", len(orphanLayers))
   750  	}
   751  	for _, orphan := range orphanLayers {
   752  		log.G(context.TODO()).WithField("cache-id", orphan.cacheID).Debugf("removing orphan layer, chain ID: %v", orphan.chainID)
   753  		err = ls.driver.Remove(orphan.cacheID)
   754  		if err != nil && !os.IsNotExist(err) {
   755  			log.G(context.TODO()).WithError(err).WithField("cache-id", orphan.cacheID).Error("cannot remove orphan layer")
   756  			continue
   757  		}
   758  		err = ls.store.Remove(orphan.chainID, orphan.cacheID)
   759  		if err != nil {
   760  			log.G(context.TODO()).WithError(err).WithField("chain-id", orphan.chainID).Error("cannot remove orphan layer metadata")
   761  		}
   762  	}
   763  	return ls.driver.Cleanup()
   764  }
   765  
   766  func (ls *layerStore) DriverStatus() [][2]string {
   767  	return ls.driver.Status()
   768  }
   769  
   770  func (ls *layerStore) DriverName() string {
   771  	return ls.driver.String()
   772  }
   773  
   774  type naiveDiffPathDriver struct {
   775  	graphdriver.Driver
   776  }
   777  
   778  type fileGetPutter struct {
   779  	storage.FileGetter
   780  	driver graphdriver.Driver
   781  	id     string
   782  }
   783  
   784  func (w *fileGetPutter) Close() error {
   785  	return w.driver.Put(w.id)
   786  }
   787  
   788  func (n *naiveDiffPathDriver) DiffGetter(id string) (graphdriver.FileGetCloser, error) {
   789  	p, err := n.Driver.Get(id, "")
   790  	if err != nil {
   791  		return nil, err
   792  	}
   793  	return &fileGetPutter{storage.NewPathFileGetter(p), n.Driver, id}, nil
   794  }