github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/layer/layer_store.go (about)

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