github.com/kim0/docker@v0.6.2-0.20161130212042-4addda3f07e7/daemon/disk_usage.go (about) 1 package daemon 2 3 import ( 4 "fmt" 5 6 "github.com/Sirupsen/logrus" 7 "github.com/docker/distribution/digest" 8 "github.com/docker/docker/api/types" 9 "github.com/docker/docker/layer" 10 "github.com/docker/docker/pkg/directory" 11 "github.com/docker/docker/volume" 12 ) 13 14 func (daemon *Daemon) getLayerRefs() map[layer.ChainID]int { 15 tmpImages := daemon.imageStore.Map() 16 layerRefs := map[layer.ChainID]int{} 17 for id, img := range tmpImages { 18 dgst := digest.Digest(id) 19 if len(daemon.referenceStore.References(dgst)) == 0 && len(daemon.imageStore.Children(id)) != 0 { 20 continue 21 } 22 23 rootFS := *img.RootFS 24 rootFS.DiffIDs = nil 25 for _, id := range img.RootFS.DiffIDs { 26 rootFS.Append(id) 27 chid := rootFS.ChainID() 28 layerRefs[chid]++ 29 } 30 } 31 32 return layerRefs 33 } 34 35 // SystemDiskUsage returns information about the daemon data disk usage 36 func (daemon *Daemon) SystemDiskUsage() (*types.DiskUsage, error) { 37 // Retrieve container list 38 allContainers, err := daemon.Containers(&types.ContainerListOptions{ 39 Size: true, 40 All: true, 41 }) 42 if err != nil { 43 return nil, fmt.Errorf("failed to retrieve container list: %v", err) 44 } 45 46 // Get all top images with extra attributes 47 allImages, err := daemon.Images("", "", false, true) 48 if err != nil { 49 return nil, fmt.Errorf("failed to retrieve image list: %v", err) 50 } 51 52 // Get all local volumes 53 allVolumes := []*types.Volume{} 54 getLocalVols := func(v volume.Volume) error { 55 name := v.Name() 56 refs := daemon.volumes.Refs(v) 57 58 tv := volumeToAPIType(v) 59 sz, err := directory.Size(v.Path()) 60 if err != nil { 61 logrus.Warnf("failed to determine size of volume %v", name) 62 sz = -1 63 } 64 tv.UsageData = &types.VolumeUsageData{Size: sz, RefCount: int64(len(refs))} 65 allVolumes = append(allVolumes, tv) 66 67 return nil 68 } 69 70 err = daemon.traverseLocalVolumes(getLocalVols) 71 if err != nil { 72 return nil, err 73 } 74 75 // Get total layers size on disk 76 layerRefs := daemon.getLayerRefs() 77 allLayers := daemon.layerStore.Map() 78 var allLayersSize int64 79 for _, l := range allLayers { 80 size, err := l.DiffSize() 81 if err == nil { 82 if _, ok := layerRefs[l.ChainID()]; ok { 83 allLayersSize += size 84 } else { 85 logrus.Warnf("found leaked image layer %v", l.ChainID()) 86 } 87 } else { 88 logrus.Warnf("failed to get diff size for layer %v", l.ChainID()) 89 } 90 91 } 92 93 return &types.DiskUsage{ 94 LayersSize: allLayersSize, 95 Containers: allContainers, 96 Volumes: allVolumes, 97 Images: allImages, 98 }, nil 99 }