gopkg.in/docker/docker.v20@v20.10.27/layer/layer_store.go (about)

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