[lxc-devel] [lxd/master] lxd/storage/ceph: Rework df handling

stgraber on Github lxc-bot at linuxcontainers.org
Sat Feb 16 03:33:36 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 370 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190215/e2a8a647/attachment-0001.bin>
-------------- next part --------------
From 70cea30d57c4ebfafd90ad0872c04f5d2824a1bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 15 Feb 2019 22:21:01 -0500
Subject: [PATCH] lxd/storage/ceph: Rework df handling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Closes #5495

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage_ceph.go       | 66 +++++++++++++++++----------------------
 lxd/storage_ceph_utils.go | 29 -----------------
 2 files changed, 29 insertions(+), 66 deletions(-)

diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index dd7323871c..0e379a6bdb 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -1,6 +1,7 @@
 package main
 
 import (
+	"encoding/json"
 	"fmt"
 	"io"
 	"io/ioutil"
@@ -2544,61 +2545,52 @@ func (s *storageCeph) StoragePoolResources() (*api.ResourcesStoragePool, error)
 		"ceph",
 		"--name", fmt.Sprintf("client.%s", s.UserName),
 		"--cluster", s.ClusterName,
-		"df")
+		"df",
+		"-f", "json")
 	if err != nil {
 		return nil, err
 	}
 
-	msg := string(buf)
-	idx := strings.Index(msg, "GLOBAL:")
-	if idx < 0 {
-		return nil, fmt.Errorf(`Output did not contain expected ` +
-			`"GLOBAL:" string`)
+	// Temporary structs for parsing
+	type cephDfPoolStats struct {
+		BytesUsed      int64 `json:"bytes_used"`
+		BytesAvailable int64 `json:"max_avail"`
 	}
 
-	msg = msg[len("GLOBAL:")+1:]
-	msg = strings.TrimSpace(msg)
-
-	if !strings.HasPrefix(msg, "SIZE") {
-		return nil, fmt.Errorf(`Output "%s" did not contain expected `+
-			`"SIZE" string`, msg)
-	}
-
-	lines := strings.Split(msg, "\n")
-	if len(lines) < 2 {
-		return nil, fmt.Errorf(`Output did not contain expected ` +
-			`resource information`)
-	}
-
-	properties := strings.Fields(lines[1])
-	if len(properties) < 3 {
-		return nil, fmt.Errorf(`Output is missing size properties`)
+	type cephDfPool struct {
+		Name  string          `json:"name"`
+		Stats cephDfPoolStats `json:"stats"`
 	}
 
-	totalStr := strings.TrimSpace(properties[0])
-	usedStr := strings.TrimSpace(properties[2])
-
-	if totalStr == "" {
-		return nil, fmt.Errorf(`Failed to detect space available to ` +
-			`the Ceph cluster`)
+	type cephDf struct {
+		Pools []cephDfPool `json:"pools"`
 	}
 
-	total, err := parseCephSize(totalStr)
+	// Parse the JSON output
+	df := cephDf{}
+	err = json.Unmarshal([]byte(buf), &df)
 	if err != nil {
 		return nil, err
 	}
 
-	used := uint64(0)
-	if usedStr != "" {
-		used, err = parseCephSize(usedStr)
-		if err != nil {
-			return nil, err
+	var pool *cephDfPool
+	for _, entry := range df.Pools {
+		if entry.Name == s.OSDPoolName {
+			pool = &entry
+			break
 		}
 	}
 
+	if pool == nil {
+		return nil, fmt.Errorf("OSD pool missing in df output")
+	}
+
+	spaceUsed := uint64(pool.Stats.BytesUsed)
+	spaceAvailable := uint64(pool.Stats.BytesAvailable)
+
 	res := api.ResourcesStoragePool{}
-	res.Space.Total = total
-	res.Space.Used = used
+	res.Space.Total = spaceAvailable + spaceUsed
+	res.Space.Used = spaceUsed
 
 	return &res, nil
 }
diff --git a/lxd/storage_ceph_utils.go b/lxd/storage_ceph_utils.go
index 73ad4b4052..d39da395d2 100644
--- a/lxd/storage_ceph_utils.go
+++ b/lxd/storage_ceph_utils.go
@@ -1542,35 +1542,6 @@ func (s *storageCeph) rbdGrow(path string, size int64, fsType string,
 	return growFileSystem(fsType, path, fsMntPoint)
 }
 
-func parseCephSize(numStr string) (uint64, error) {
-	if numStr == "" {
-		return 0, fmt.Errorf("Empty string is not valid input")
-	}
-
-	lxdSuffix := "GB"
-	cephSuffix := numStr[(len(numStr) - 1):]
-	switch cephSuffix {
-	case "M":
-		lxdSuffix = "MB"
-	case "K":
-		lxdSuffix = "KB"
-	}
-
-	_, err := strconv.Atoi(cephSuffix)
-	if err != nil {
-		numStr = numStr[:(len(numStr) - 1)]
-		numStr = strings.TrimSpace(numStr)
-	}
-	numStr = fmt.Sprintf("%s%s", numStr, lxdSuffix)
-
-	size, err := shared.ParseByteSizeString(numStr)
-	if err != nil {
-		return 0, err
-	}
-
-	return uint64(size), nil
-}
-
 // copyWithSnapshots creates a non-sparse copy of a container including its
 // snapshots
 // This does not introduce a dependency relation between the source RBD storage


More information about the lxc-devel mailing list