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