github.com/xdlianrong208/docker-ce-comments@v17.12.1-ce-rc2+incompatible/components/engine/layer/layer_store.go (about) 1 package layer 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "strings" 9 "sync" 10 11 "github.com/docker/distribution" 12 "github.com/docker/docker/daemon/graphdriver" 13 "github.com/docker/docker/pkg/idtools" 14 "github.com/docker/docker/pkg/plugingetter" 15 "github.com/docker/docker/pkg/stringid" 16 "github.com/docker/docker/pkg/system" 17 "github.com/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 MetadataStore 32 driver graphdriver.Driver 33 34 layerMap map[ChainID]*roLayer 35 layerL sync.Mutex 36 37 mounts map[string]*mountedLayer 38 mountL sync.Mutex 39 40 useTarSplit bool 41 42 os string 43 } 44 45 // StoreOptions are the options used to create a new Store instance 46 type StoreOptions struct { 47 StorePath string 48 MetadataStorePathTemplate string 49 GraphDriver string 50 GraphDriverOptions []string 51 IDMappings *idtools.IDMappings 52 PluginGetter plugingetter.PluginGetter 53 ExperimentalEnabled bool 54 OS string 55 } 56 57 // NewStoreFromOptions creates a new Store instance 58 func NewStoreFromOptions(options StoreOptions) (Store, error) { 59 driver, err := graphdriver.New(options.GraphDriver, options.PluginGetter, graphdriver.Options{ 60 Root: options.StorePath, 61 DriverOptions: options.GraphDriverOptions, 62 UIDMaps: options.IDMappings.UIDs(), 63 GIDMaps: options.IDMappings.GIDs(), 64 ExperimentalEnabled: options.ExperimentalEnabled, 65 }) 66 if err != nil { 67 return nil, fmt.Errorf("error initializing graphdriver: %v", err) 68 } 69 logrus.Debugf("Using graph driver %s", driver) 70 71 fms, err := NewFSMetadataStore(fmt.Sprintf(options.MetadataStorePathTemplate, driver)) 72 if err != nil { 73 return nil, err 74 } 75 76 return NewStoreFromGraphDriver(fms, driver, options.OS) 77 } 78 79 // NewStoreFromGraphDriver creates a new Store instance using the provided 80 // metadata store and graph driver. The metadata store will be used to restore 81 // the Store. 82 func NewStoreFromGraphDriver(store MetadataStore, driver graphdriver.Driver, os string) (Store, error) { 83 caps := graphdriver.Capabilities{} 84 if capDriver, ok := driver.(graphdriver.CapabilityDriver); ok { 85 caps = capDriver.Capabilities() 86 } 87 88 ls := &layerStore{ 89 store: store, 90 driver: driver, 91 layerMap: map[ChainID]*roLayer{}, 92 mounts: map[string]*mountedLayer{}, 93 useTarSplit: !caps.ReproducesExactDiffs, 94 os: os, 95 } 96 97 ids, mounts, err := store.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) loadLayer(layer ChainID) (*roLayer, error) { 123 cl, ok := ls.layerMap[layer] 124 if ok { 125 return cl, nil 126 } 127 128 diff, err := ls.store.GetDiffID(layer) 129 if err != nil { 130 return nil, fmt.Errorf("failed to get diff id for %s: %s", layer, err) 131 } 132 133 size, err := ls.store.GetSize(layer) 134 if err != nil { 135 return nil, fmt.Errorf("failed to get size for %s: %s", layer, err) 136 } 137 138 cacheID, err := ls.store.GetCacheID(layer) 139 if err != nil { 140 return nil, fmt.Errorf("failed to get cache id for %s: %s", layer, err) 141 } 142 143 parent, err := ls.store.GetParent(layer) 144 if err != nil { 145 return nil, fmt.Errorf("failed to get parent for %s: %s", layer, err) 146 } 147 148 descriptor, err := ls.store.GetDescriptor(layer) 149 if err != nil { 150 return nil, fmt.Errorf("failed to get descriptor for %s: %s", layer, err) 151 } 152 153 os, err := ls.store.GetOS(layer) 154 if err != nil { 155 return nil, fmt.Errorf("failed to get operating system for %s: %s", layer, err) 156 } 157 158 cl = &roLayer{ 159 chainID: layer, 160 diffID: diff, 161 size: size, 162 cacheID: cacheID, 163 layerStore: ls, 164 references: map[Layer]struct{}{}, 165 descriptor: descriptor, 166 os: os, 167 } 168 169 if parent != "" { 170 p, err := ls.loadLayer(parent) 171 if err != nil { 172 return nil, err 173 } 174 cl.parent = p 175 } 176 177 ls.layerMap[cl.chainID] = cl 178 179 return cl, nil 180 } 181 182 func (ls *layerStore) loadMount(mount string) error { 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 MetadataTransaction, 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 if err != nil { 248 return err 249 } 250 251 // Discard trailing data but ensure metadata is picked up to reconstruct stream 252 io.Copy(ioutil.Discard, rdr) // ignore error as reader may be closed 253 254 layer.size = applySize 255 layer.diffID = DiffID(digester.Digest()) 256 257 logrus.Debugf("Applied tar %s to %s, size: %d", layer.diffID, layer.cacheID, applySize) 258 259 return nil 260 } 261 262 func (ls *layerStore) Register(ts io.Reader, parent ChainID, os OS) (Layer, error) { 263 return ls.registerWithDescriptor(ts, parent, os, distribution.Descriptor{}) 264 } 265 266 func (ls *layerStore) registerWithDescriptor(ts io.Reader, parent ChainID, os OS, descriptor distribution.Descriptor) (Layer, error) { 267 // err is used to hold the error which will always trigger 268 // cleanup of creates sources but may not be an error returned 269 // to the caller (already exists). 270 var err error 271 var pid string 272 var p *roLayer 273 274 // Integrity check - ensure we are creating something for the correct operating system 275 if system.LCOWSupported() { 276 if strings.ToLower(ls.os) != strings.ToLower(string(os)) { 277 return nil, fmt.Errorf("cannot create entry for operating system %q in layer store for operating system %q", os, ls.os) 278 } 279 } 280 281 if string(parent) != "" { 282 p = ls.get(parent) 283 if p == nil { 284 return nil, ErrLayerDoesNotExist 285 } 286 pid = p.cacheID 287 // Release parent chain if error 288 defer func() { 289 if err != nil { 290 ls.layerL.Lock() 291 ls.releaseLayer(p) 292 ls.layerL.Unlock() 293 } 294 }() 295 if p.depth() >= maxLayerDepth { 296 err = ErrMaxDepthExceeded 297 return nil, err 298 } 299 } 300 301 // Create new roLayer 302 layer := &roLayer{ 303 parent: p, 304 cacheID: stringid.GenerateRandomID(), 305 referenceCount: 1, 306 layerStore: ls, 307 references: map[Layer]struct{}{}, 308 descriptor: descriptor, 309 os: os, 310 } 311 312 if err = ls.driver.Create(layer.cacheID, pid, nil); err != nil { 313 return nil, err 314 } 315 316 tx, err := ls.store.StartTransaction() 317 if err != nil { 318 return nil, err 319 } 320 321 defer func() { 322 if err != nil { 323 logrus.Debugf("Cleaning up layer %s: %v", layer.cacheID, err) 324 if err := ls.driver.Remove(layer.cacheID); err != nil { 325 logrus.Errorf("Error cleaning up cache layer %s: %v", layer.cacheID, err) 326 } 327 if err := tx.Cancel(); err != nil { 328 logrus.Errorf("Error canceling metadata transaction %q: %s", tx.String(), err) 329 } 330 } 331 }() 332 333 if err = ls.applyTar(tx, ts, pid, layer); err != nil { 334 return nil, err 335 } 336 337 if layer.parent == nil { 338 layer.chainID = ChainID(layer.diffID) 339 } else { 340 layer.chainID = createChainIDFromParent(layer.parent.chainID, layer.diffID) 341 } 342 343 if err = storeLayer(tx, layer); err != nil { 344 return nil, err 345 } 346 347 ls.layerL.Lock() 348 defer ls.layerL.Unlock() 349 350 if existingLayer := ls.getWithoutLock(layer.chainID); existingLayer != nil { 351 // Set error for cleanup, but do not return the error 352 err = errors.New("layer already exists") 353 return existingLayer.getReference(), nil 354 } 355 356 if err = tx.Commit(layer.chainID); err != nil { 357 return nil, err 358 } 359 360 ls.layerMap[layer.chainID] = layer 361 362 return layer.getReference(), nil 363 } 364 365 func (ls *layerStore) getWithoutLock(layer ChainID) *roLayer { 366 l, ok := ls.layerMap[layer] 367 if !ok { 368 return nil 369 } 370 371 l.referenceCount++ 372 373 return l 374 } 375 376 func (ls *layerStore) get(l ChainID) *roLayer { 377 ls.layerL.Lock() 378 defer ls.layerL.Unlock() 379 return ls.getWithoutLock(l) 380 } 381 382 func (ls *layerStore) Get(l ChainID) (Layer, error) { 383 ls.layerL.Lock() 384 defer ls.layerL.Unlock() 385 386 layer := ls.getWithoutLock(l) 387 if layer == nil { 388 return nil, ErrLayerDoesNotExist 389 } 390 391 return layer.getReference(), nil 392 } 393 394 func (ls *layerStore) Map() map[ChainID]Layer { 395 ls.layerL.Lock() 396 defer ls.layerL.Unlock() 397 398 layers := map[ChainID]Layer{} 399 400 for k, v := range ls.layerMap { 401 layers[k] = v 402 } 403 404 return layers 405 } 406 407 func (ls *layerStore) deleteLayer(layer *roLayer, metadata *Metadata) error { 408 err := ls.driver.Remove(layer.cacheID) 409 if err != nil { 410 return err 411 } 412 err = ls.store.Remove(layer.chainID) 413 if err != nil { 414 return err 415 } 416 metadata.DiffID = layer.diffID 417 metadata.ChainID = layer.chainID 418 metadata.Size, err = 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 var metadata Metadata 446 if err := ls.deleteLayer(l, &metadata); err != nil { 447 return nil, err 448 } 449 450 delete(ls.layerMap, l.chainID) 451 removed = append(removed, metadata) 452 453 if l.parent == nil { 454 return removed, nil 455 } 456 457 depth++ 458 l = l.parent 459 } 460 } 461 462 func (ls *layerStore) Release(l Layer) ([]Metadata, error) { 463 ls.layerL.Lock() 464 defer ls.layerL.Unlock() 465 layer, ok := ls.layerMap[l.ChainID()] 466 if !ok { 467 return []Metadata{}, nil 468 } 469 if !layer.hasReference(l) { 470 return nil, ErrLayerNotRetained 471 } 472 473 layer.deleteReference(l) 474 475 return ls.releaseLayer(layer) 476 } 477 478 func (ls *layerStore) CreateRWLayer(name string, parent ChainID, opts *CreateRWLayerOpts) (RWLayer, error) { 479 var ( 480 storageOpt map[string]string 481 initFunc MountInit 482 mountLabel string 483 ) 484 485 if opts != nil { 486 mountLabel = opts.MountLabel 487 storageOpt = opts.StorageOpt 488 initFunc = opts.InitFunc 489 } 490 491 ls.mountL.Lock() 492 defer ls.mountL.Unlock() 493 m, ok := ls.mounts[name] 494 if ok { 495 return nil, ErrMountNameConflict 496 } 497 498 var err error 499 var pid string 500 var p *roLayer 501 if string(parent) != "" { 502 p = ls.get(parent) 503 if p == nil { 504 return nil, ErrLayerDoesNotExist 505 } 506 pid = p.cacheID 507 508 // Release parent chain if error 509 defer func() { 510 if err != nil { 511 ls.layerL.Lock() 512 ls.releaseLayer(p) 513 ls.layerL.Unlock() 514 } 515 }() 516 } 517 518 m = &mountedLayer{ 519 name: name, 520 parent: p, 521 mountID: ls.mountID(name), 522 layerStore: ls, 523 references: map[RWLayer]*referencedRWLayer{}, 524 } 525 526 if initFunc != nil { 527 pid, err = ls.initMount(m.mountID, pid, mountLabel, initFunc, storageOpt) 528 if err != nil { 529 return nil, err 530 } 531 m.initID = pid 532 } 533 534 createOpts := &graphdriver.CreateOpts{ 535 StorageOpt: storageOpt, 536 } 537 538 if err = ls.driver.CreateReadWrite(m.mountID, pid, createOpts); err != nil { 539 return nil, err 540 } 541 if err = ls.saveMount(m); err != nil { 542 return nil, err 543 } 544 545 return m.getReference(), nil 546 } 547 548 func (ls *layerStore) GetRWLayer(id string) (RWLayer, error) { 549 ls.mountL.Lock() 550 defer ls.mountL.Unlock() 551 mount, ok := ls.mounts[id] 552 if !ok { 553 return nil, ErrMountDoesNotExist 554 } 555 556 return mount.getReference(), nil 557 } 558 559 func (ls *layerStore) GetMountID(id string) (string, error) { 560 ls.mountL.Lock() 561 defer ls.mountL.Unlock() 562 mount, ok := ls.mounts[id] 563 if !ok { 564 return "", ErrMountDoesNotExist 565 } 566 logrus.Debugf("GetMountID id: %s -> mountID: %s", id, mount.mountID) 567 568 return mount.mountID, nil 569 } 570 571 func (ls *layerStore) ReleaseRWLayer(l RWLayer) ([]Metadata, error) { 572 ls.mountL.Lock() 573 defer ls.mountL.Unlock() 574 m, ok := ls.mounts[l.Name()] 575 if !ok { 576 return []Metadata{}, nil 577 } 578 579 if err := m.deleteReference(l); err != nil { 580 return nil, err 581 } 582 583 if m.hasReferences() { 584 return []Metadata{}, nil 585 } 586 587 if err := ls.driver.Remove(m.mountID); err != nil { 588 logrus.Errorf("Error removing mounted layer %s: %s", m.name, err) 589 m.retakeReference(l) 590 return nil, err 591 } 592 593 if m.initID != "" { 594 if err := ls.driver.Remove(m.initID); err != nil { 595 logrus.Errorf("Error removing init layer %s: %s", m.name, err) 596 m.retakeReference(l) 597 return nil, err 598 } 599 } 600 601 if err := ls.store.RemoveMount(m.name); err != nil { 602 logrus.Errorf("Error removing mount metadata: %s: %s", m.name, err) 603 m.retakeReference(l) 604 return nil, err 605 } 606 607 delete(ls.mounts, m.Name()) 608 609 ls.layerL.Lock() 610 defer ls.layerL.Unlock() 611 if m.parent != nil { 612 return ls.releaseLayer(m.parent) 613 } 614 615 return []Metadata{}, nil 616 } 617 618 func (ls *layerStore) saveMount(mount *mountedLayer) error { 619 if err := ls.store.SetMountID(mount.name, mount.mountID); err != nil { 620 return err 621 } 622 623 if mount.initID != "" { 624 if err := ls.store.SetInitID(mount.name, mount.initID); err != nil { 625 return err 626 } 627 } 628 629 if mount.parent != nil { 630 if err := ls.store.SetMountParent(mount.name, mount.parent.chainID); err != nil { 631 return err 632 } 633 } 634 635 ls.mounts[mount.name] = mount 636 637 return nil 638 } 639 640 func (ls *layerStore) initMount(graphID, parent, mountLabel string, initFunc MountInit, storageOpt map[string]string) (string, error) { 641 // Use "<graph-id>-init" to maintain compatibility with graph drivers 642 // which are expecting this layer with this special name. If all 643 // graph drivers can be updated to not rely on knowing about this layer 644 // then the initID should be randomly generated. 645 initID := fmt.Sprintf("%s-init", graphID) 646 647 createOpts := &graphdriver.CreateOpts{ 648 MountLabel: mountLabel, 649 StorageOpt: storageOpt, 650 } 651 652 if err := ls.driver.CreateReadWrite(initID, parent, createOpts); err != nil { 653 return "", err 654 } 655 p, err := ls.driver.Get(initID, "") 656 if err != nil { 657 return "", err 658 } 659 660 if err := initFunc(p); err != nil { 661 ls.driver.Put(initID) 662 return "", err 663 } 664 665 if err := ls.driver.Put(initID); err != nil { 666 return "", err 667 } 668 669 return initID, nil 670 } 671 672 func (ls *layerStore) getTarStream(rl *roLayer) (io.ReadCloser, error) { 673 if !ls.useTarSplit { 674 var parentCacheID string 675 if rl.parent != nil { 676 parentCacheID = rl.parent.cacheID 677 } 678 679 return ls.driver.Diff(rl.cacheID, parentCacheID) 680 } 681 682 r, err := ls.store.TarSplitReader(rl.chainID) 683 if err != nil { 684 return nil, err 685 } 686 687 pr, pw := io.Pipe() 688 go func() { 689 err := ls.assembleTarTo(rl.cacheID, r, nil, pw) 690 if err != nil { 691 pw.CloseWithError(err) 692 } else { 693 pw.Close() 694 } 695 }() 696 697 return pr, nil 698 } 699 700 func (ls *layerStore) assembleTarTo(graphID string, metadata io.ReadCloser, size *int64, w io.Writer) error { 701 diffDriver, ok := ls.driver.(graphdriver.DiffGetterDriver) 702 if !ok { 703 diffDriver = &naiveDiffPathDriver{ls.driver} 704 } 705 706 defer metadata.Close() 707 708 // get our relative path to the container 709 fileGetCloser, err := diffDriver.DiffGetter(graphID) 710 if err != nil { 711 return err 712 } 713 defer fileGetCloser.Close() 714 715 metaUnpacker := storage.NewJSONUnpacker(metadata) 716 upackerCounter := &unpackSizeCounter{metaUnpacker, size} 717 logrus.Debugf("Assembling tar data for %s", graphID) 718 return asm.WriteOutputTarStream(fileGetCloser, upackerCounter, w) 719 } 720 721 func (ls *layerStore) Cleanup() error { 722 return ls.driver.Cleanup() 723 } 724 725 func (ls *layerStore) DriverStatus() [][2]string { 726 return ls.driver.Status() 727 } 728 729 func (ls *layerStore) DriverName() string { 730 return ls.driver.String() 731 } 732 733 type naiveDiffPathDriver struct { 734 graphdriver.Driver 735 } 736 737 type fileGetPutter struct { 738 storage.FileGetter 739 driver graphdriver.Driver 740 id string 741 } 742 743 func (w *fileGetPutter) Close() error { 744 return w.driver.Put(w.id) 745 } 746 747 func (n *naiveDiffPathDriver) DiffGetter(id string) (graphdriver.FileGetCloser, error) { 748 p, err := n.Driver.Get(id, "") 749 if err != nil { 750 return nil, err 751 } 752 return &fileGetPutter{storage.NewPathFileGetter(p.Path()), n.Driver, id}, nil 753 }