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