Selaa lähdekoodia

Add available space to devicemapper status output

Signed-off-by: Peter Volpe <petervo@redhat.com>
Peter Volpe 10 vuotta sitten
vanhempi
commit
726f89d77a

+ 4 - 0
daemon/graphdriver/devmapper/README.md

@@ -42,8 +42,10 @@ will display something like:
 	 Metadata file: /dev/loop4
 	 Data Space Used: 2.536 GB
 	 Data Space Total: 107.4 GB
+	 Data Space Available: 104.8 GB
 	 Metadata Space Used: 7.93 MB
 	 Metadata Space Total: 2.147 GB
+	 Metadata Space Available: 2.14 GB
 	 Udev Sync Supported: true
 	 Data loop file: /home/docker/devicemapper/devicemapper/data
 	 Metadata loop file: /home/docker/devicemapper/devicemapper/metadata
@@ -60,8 +62,10 @@ status information about the driver.
  *  `Metadata file` blockdevice file used for the devicemapper metadata
  *  `Data Space Used` tells how much of `Data file` is currently used
  *  `Data Space Total` tells max size the `Data file`
+ *  `Data Space Available` tells how much free space there is in the `Data file`
  *  `Metadata Space Used` tells how much of `Metadata file` is currently used
  *  `Metadata Space Total` tells max size the `Metadata file`
+ *  `Metadata Space Available` tells how much free space there is in the `Metadata file`
  *  `Udev Sync Supported` tells whether devicemapper is able to sync with Udev. Should be `true`.
  *  `Data loop file` file attached to `Data file`, if loopback device is used
  *  `Metadata loop file` file attached to `Metadata file`, if loopback device is used

+ 41 - 2
daemon/graphdriver/devmapper/deviceset.go

@@ -100,8 +100,9 @@ type DeviceSet struct {
 }
 
 type DiskUsage struct {
-	Used  uint64
-	Total uint64
+	Used      uint64
+	Total     uint64
+	Available uint64
 }
 
 type Status struct {
@@ -1574,6 +1575,28 @@ func (devices *DeviceSet) MetadataDevicePath() string {
 	return devices.metadataDevice
 }
 
+func (devices *DeviceSet) getUnderlyingAvailableSpace(loopFile string) (uint64, error) {
+	buf := new(syscall.Statfs_t)
+	err := syscall.Statfs(loopFile, buf)
+	if err != nil {
+		log.Warnf("Warning: Couldn't stat loopfile filesystem %v: %v", loopFile, err)
+		return 0, err
+	}
+	return buf.Bfree * uint64(buf.Bsize), nil
+}
+
+func (devices *DeviceSet) isRealFile(loopFile string) (bool, error) {
+	if loopFile != "" {
+		fi, err := os.Stat(loopFile)
+		if err != nil {
+			log.Warnf("Warning: Couldn't stat loopfile %v: %v", loopFile, err)
+			return false, err
+		}
+		return fi.Mode().IsRegular(), nil
+	}
+	return false, nil
+}
+
 // Status returns the current status of this deviceset
 func (devices *DeviceSet) Status() *Status {
 	devices.Lock()
@@ -1595,12 +1618,28 @@ func (devices *DeviceSet) Status() *Status {
 
 		status.Data.Used = dataUsed * blockSizeInSectors * 512
 		status.Data.Total = dataTotal * blockSizeInSectors * 512
+		status.Data.Available = status.Data.Total - status.Data.Used
 
 		// metadata blocks are always 4k
 		status.Metadata.Used = metadataUsed * 4096
 		status.Metadata.Total = metadataTotal * 4096
+		status.Metadata.Available = status.Metadata.Total - status.Metadata.Used
 
 		status.SectorSize = blockSizeInSectors * 512
+
+		if check, _ := devices.isRealFile(devices.dataLoopFile); check {
+			actualSpace, err := devices.getUnderlyingAvailableSpace(devices.dataLoopFile)
+			if err == nil && actualSpace < status.Data.Available {
+				status.Data.Available = actualSpace
+			}
+		}
+
+		if check, _ := devices.isRealFile(devices.metadataLoopFile); check {
+			actualSpace, err := devices.getUnderlyingAvailableSpace(devices.metadataLoopFile)
+			if err == nil && actualSpace < status.Metadata.Available {
+				status.Metadata.Available = actualSpace
+			}
+		}
 	}
 
 	return status

+ 2 - 0
daemon/graphdriver/devmapper/driver.go

@@ -72,8 +72,10 @@ func (d *Driver) Status() [][2]string {
 		{"Metadata file", s.MetadataFile},
 		{"Data Space Used", fmt.Sprintf("%s", units.HumanSize(float64(s.Data.Used)))},
 		{"Data Space Total", fmt.Sprintf("%s", units.HumanSize(float64(s.Data.Total)))},
+		{"Data Space Available", fmt.Sprintf("%s", units.HumanSize(float64(s.Data.Available)))},
 		{"Metadata Space Used", fmt.Sprintf("%s", units.HumanSize(float64(s.Metadata.Used)))},
 		{"Metadata Space Total", fmt.Sprintf("%s", units.HumanSize(float64(s.Metadata.Total)))},
+		{"Metadata Space Available", fmt.Sprintf("%s", units.HumanSize(float64(s.Metadata.Available)))},
 		{"Udev Sync Supported", fmt.Sprintf("%v", s.UdevSyncSupported)},
 	}
 	if len(s.DataLoopback) > 0 {