[lxc-devel] [lxd/master] storage/lvm: Adds spaced used reporting for LVM thinpools

tomponline on Github lxc-bot at linuxcontainers.org
Wed Jul 3 10:17:39 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 488 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190703/91dcd6b1/attachment.bin>
-------------- next part --------------
From 881700734d8bc12be8946fd74d2ca9c6898032f4 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 3 Jul 2019 11:15:48 +0100
Subject: [PATCH] storage/lvm: Adds spaced used reporting for LVM thinpools

Also optimises volume group reporting to avoid running lvs twice by retrieving both fields needed in one go.

Fixes #5868

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage_lvm.go | 73 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 52 insertions(+), 21 deletions(-)

diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index 30505c41a6..7e7942c46d 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -2160,34 +2160,65 @@ func (s *storageLvm) StorageEntitySetQuota(volumeType int, size int64, data inte
 }
 
 func (s *storageLvm) StoragePoolResources() (*api.ResourcesStoragePool, error) {
-	args := []string{s.pool.Config["lvm.vg_name"], "--noheadings",
-		"--units", "b", "--nosuffix", "-o"}
+	res := api.ResourcesStoragePool{}
 
-	totalBuf, err := shared.TryRunCommand("vgs", append(args, "vg_size")...)
-	if err != nil {
-		return nil, err
-	}
+	// Thinpools will always report zero free space on the volume group, so calculate approx
+	// used space using the thinpool logical volumne allocated (data and meta) percentages.
+	if s.useThinpool {
+		args := []string{fmt.Sprintf("%s/%s", s.vgName, s.thinPoolName), "--noheadings",
+			"--units", "b", "--nosuffix", "--separator", ",", "-o", "lv_size,data_percent,metadata_percent"}
 
-	totalStr := string(totalBuf)
-	totalStr = strings.TrimSpace(totalStr)
-	total, err := strconv.ParseUint(totalStr, 10, 64)
-	if err != nil {
-		return nil, err
-	}
+		out, err := shared.TryRunCommand("lvs", args...)
+		if err != nil {
+			return nil, err
+		}
 
-	res := api.ResourcesStoragePool{}
-	res.Space.Total = total
+		parts := strings.Split(strings.TrimSpace(out), ",")
+		if len(parts) < 3 {
+			return nil, fmt.Errorf("Unexpected output from lvs command")
+		}
+
+		total, err := strconv.ParseUint(parts[0], 10, 64)
+		if err != nil {
+			return nil, err
+		}
+
+		res.Space.Total = total
+
+		dataPerc, err := strconv.ParseFloat(parts[1], 64)
+		if err != nil {
+			return nil, err
+		}
+
+		metaPerc, err := strconv.ParseFloat(parts[2], 64)
+		if err != nil {
+			return nil, err
+		}
+
+		res.Space.Used = uint64(float64(total) * ((dataPerc + metaPerc) / 100))
+	} else {
+		// If thinpools are not in use, calculate used space in volume group.
+		args := []string{s.vgName, "--noheadings",
+			"--units", "b", "--nosuffix", "--separator", ",", "-o", "vg_size,vg_free"}
 
-	// Thinpools will always report zero free space so no use in calculating
-	// a used count. It'll be useless information for the user.
-	if !s.useThinpool {
-		freeBuf, err := shared.TryRunCommand("vgs", append(args, "vg_free")...)
+		out, err := shared.TryRunCommand("vgs", args...)
 		if err != nil {
 			return nil, err
 		}
-		freeStr := string(freeBuf)
-		freeStr = strings.TrimSpace(freeStr)
-		free, err := strconv.ParseUint(freeStr, 10, 64)
+
+		parts := strings.Split(strings.TrimSpace(out), ",")
+		if len(parts) < 2 {
+			return nil, fmt.Errorf("Unexpected output from vgs command")
+		}
+
+		total, err := strconv.ParseUint(parts[0], 10, 64)
+		if err != nil {
+			return nil, err
+		}
+
+		res.Space.Total = total
+
+		free, err := strconv.ParseUint(parts[1], 10, 64)
 		if err != nil {
 			return nil, err
 		}


More information about the lxc-devel mailing list