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