From d733cdcebbcb6bc8573e1869b11f0d9116a92892 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Thu, 17 Oct 2013 11:16:50 +0200 Subject: [PATCH] Show devicemapper status in "docker info" This shows the current global diskspace use in "docker info" --- api_params.go | 29 +++++++++++--------- commands.go | 6 +++++ devmapper/deviceset_devmapper.go | 46 ++++++++++++++++++++++++++++++++ server.go | 31 ++++++++++++--------- 4 files changed, 88 insertions(+), 24 deletions(-) diff --git a/api_params.go b/api_params.go index 5f1a338057..b685d40566 100644 --- a/api_params.go +++ b/api_params.go @@ -19,18 +19,23 @@ type APIImages struct { } type APIInfo struct { - Debug bool - Containers int - Images int - NFd int `json:",omitempty"` - NGoroutines int `json:",omitempty"` - MemoryLimit bool `json:",omitempty"` - SwapLimit bool `json:",omitempty"` - IPv4Forwarding bool `json:",omitempty"` - LXCVersion string `json:",omitempty"` - NEventsListener int `json:",omitempty"` - KernelVersion string `json:",omitempty"` - IndexServerAddress string `json:",omitempty"` + Debug bool + Containers int + Images int + NFd int `json:",omitempty"` + NGoroutines int `json:",omitempty"` + MemoryLimit bool `json:",omitempty"` + SwapLimit bool `json:",omitempty"` + IPv4Forwarding bool `json:",omitempty"` + LXCVersion string `json:",omitempty"` + NEventsListener int `json:",omitempty"` + KernelVersion string `json:",omitempty"` + IndexServerAddress string `json:",omitempty"` + DevmapperPool string `json:",omitempty"` + DevmapperDataUsed uint64 `json:",omitempty"` + DevmapperDataTotal uint64 `json:",omitempty"` + DevmapperMetadataUsed uint64 `json:",omitempty"` + DevmapperMetadataTotal uint64 `json:",omitempty"` } type APITop struct { diff --git a/commands.go b/commands.go index 7d33b81d0a..b72c2c1516 100644 --- a/commands.go +++ b/commands.go @@ -465,6 +465,11 @@ func (cli *DockerCli) CmdInfo(args ...string) error { fmt.Fprintf(cli.out, "Containers: %d\n", out.Containers) fmt.Fprintf(cli.out, "Images: %d\n", out.Images) + if out.DevmapperDataTotal != 0 { + fmt.Fprintf(cli.out, "Devmapper disk use: Data: %.1f/%.1f Metadata: %.1f/%.1f\n", + float64(out.DevmapperDataUsed)/(1024*1024), float64(out.DevmapperDataTotal)/(1024*1024), + float64(out.DevmapperMetadataUsed)/(1024*1024), float64(out.DevmapperMetadataTotal)/(1024*1024)) + } if out.Debug || os.Getenv("DEBUG") != "" { fmt.Fprintf(cli.out, "Debug mode (server): %v\n", out.Debug) fmt.Fprintf(cli.out, "Debug mode (client): %v\n", os.Getenv("DEBUG") != "") @@ -473,6 +478,7 @@ func (cli *DockerCli) CmdInfo(args ...string) error { fmt.Fprintf(cli.out, "LXC Version: %s\n", out.LXCVersion) fmt.Fprintf(cli.out, "EventsListeners: %d\n", out.NEventsListener) fmt.Fprintf(cli.out, "Kernel Version: %s\n", out.KernelVersion) + fmt.Fprintf(cli.out, "Devmapper pool: %s\n", out.DevmapperPool) } if len(out.IndexServerAddress) != 0 { diff --git a/devmapper/deviceset_devmapper.go b/devmapper/deviceset_devmapper.go index 309a26db79..4037f93136 100644 --- a/devmapper/deviceset_devmapper.go +++ b/devmapper/deviceset_devmapper.go @@ -47,6 +47,19 @@ type DeviceSetDM struct { activeMounts map[string]int } +type DiskUsage struct { + Used uint64 + Total uint64 +} + +type Status struct { + PoolName string + DataLoopback string + MetadataLoopback string + Data DiskUsage + Metadata DiskUsage +} + func getDevName(name string) string { return "/dev/mapper/" + name } @@ -774,6 +787,39 @@ func (devices *DeviceSetDM) SetInitialized(hash string) error { return nil } +func (devices *DeviceSetDM) Status() *Status { + devices.Lock() + defer devices.Unlock() + + status := &Status {} + + if err := devices.ensureInit(); err != nil { + return status + } + + status.PoolName = devices.getPoolName() + status.DataLoopback = path.Join( devices.loopbackDir(), "data") + status.MetadataLoopback = path.Join( devices.loopbackDir(), "metadata") + + _, totalSizeInSectors, _, params, err := getStatus(devices.getPoolName()) + if err == nil { + var transactionId, dataUsed, dataTotal, metadataUsed, metadataTotal uint64 + if _, err := fmt.Sscanf(params, "%d %d/%d %d/%d", &transactionId, &metadataUsed, &metadataTotal, &dataUsed, &dataTotal); err == nil { + // Convert from blocks to bytes + blockSizeInSectors := totalSizeInSectors / dataTotal; + + status.Data.Used = dataUsed * blockSizeInSectors * 512 + status.Data.Total = dataTotal * blockSizeInSectors * 512 + + // metadata blocks are always 4k + status.Metadata.Used = metadataUsed * 4096 + status.Metadata.Total = metadataTotal * 4096 + } + } + + return status +} + func (devices *DeviceSetDM) ensureInit() error { if !devices.initialized { devices.initialized = true diff --git a/server.go b/server.go index 7e6c556a3f..63c67b25ec 100644 --- a/server.go +++ b/server.go @@ -268,19 +268,26 @@ func (srv *Server) DockerInfo() *APIInfo { kernelVersion = kv.String() } + devSetInfo := srv.runtime.deviceSet.Status() + return &APIInfo{ - Containers: len(srv.runtime.List()), - Images: imgcount, - MemoryLimit: srv.runtime.capabilities.MemoryLimit, - SwapLimit: srv.runtime.capabilities.SwapLimit, - IPv4Forwarding: !srv.runtime.capabilities.IPv4ForwardingDisabled, - Debug: os.Getenv("DEBUG") != "", - NFd: utils.GetTotalUsedFds(), - NGoroutines: runtime.NumGoroutine(), - LXCVersion: lxcVersion, - NEventsListener: len(srv.events), - KernelVersion: kernelVersion, - IndexServerAddress: auth.IndexServerAddress(), + Containers: len(srv.runtime.List()), + Images: imgcount, + MemoryLimit: srv.runtime.capabilities.MemoryLimit, + SwapLimit: srv.runtime.capabilities.SwapLimit, + IPv4Forwarding: !srv.runtime.capabilities.IPv4ForwardingDisabled, + Debug: os.Getenv("DEBUG") != "", + NFd: utils.GetTotalUsedFds(), + NGoroutines: runtime.NumGoroutine(), + LXCVersion: lxcVersion, + NEventsListener: len(srv.events), + KernelVersion: kernelVersion, + IndexServerAddress: auth.IndexServerAddress(), + DevmapperPool: devSetInfo.PoolName, + DevmapperDataUsed: devSetInfo.Data.Used, + DevmapperDataTotal: devSetInfo.Data.Total, + DevmapperMetadataUsed: devSetInfo.Metadata.Used, + DevmapperMetadataTotal: devSetInfo.Metadata.Total, } }