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 }