[lxc-devel] [lxd/master] lxd/storage/btrfs: Fix qgroup handling

stgraber on Github lxc-bot at linuxcontainers.org
Thu Jun 13 15:39:23 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 437 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190613/19e3dd5d/attachment.bin>
-------------- next part --------------
From e277189428c1bad992a33658cb41bdbb0da5be29 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 13 Jun 2019 11:38:21 -0400
Subject: [PATCH] lxd/storage/btrfs: Fix qgroup handling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

We are deleting qgroups but not re-creating them when needed...

Closes #5842

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage_btrfs.go | 63 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 51 insertions(+), 12 deletions(-)

diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 93e0a3c276..611dd5554e 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -16,7 +16,6 @@ import (
 	"github.com/pkg/errors"
 	"golang.org/x/sys/unix"
 
-	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/lxd/migration"
 	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/lxd/util"
@@ -2148,6 +2147,9 @@ func btrfsSubVolumeCreate(subvol string) error {
 	return nil
 }
 
+var btrfsErrNoQuota = fmt.Errorf("Quotas disabled on filesystem")
+var btrfsErrNoQGroup = fmt.Errorf("Unable to find quota group")
+
 func btrfsSubVolumeQGroup(subvol string) (string, error) {
 	output, err := shared.RunCommand(
 		"btrfs",
@@ -2158,7 +2160,7 @@ func btrfsSubVolumeQGroup(subvol string) (string, error) {
 		"-f")
 
 	if err != nil {
-		return "", db.ErrNoSuchObject
+		return "", btrfsErrNoQuota
 	}
 
 	var qgroup string
@@ -2176,7 +2178,7 @@ func btrfsSubVolumeQGroup(subvol string) (string, error) {
 	}
 
 	if qgroup == "" {
-		return "", fmt.Errorf("Unable to find quota group")
+		return "", btrfsErrNoQGroup
 	}
 
 	return qgroup, nil
@@ -2886,17 +2888,54 @@ func (s *storageBtrfs) StorageEntitySetQuota(volumeType int, size int64, data in
 	}
 
 	qgroup, err := btrfsSubVolumeQGroup(subvol)
-	if err != nil {
-		if err != db.ErrNoSuchObject {
-			return err
+	if err != nil && !s.s.OS.RunningInUserNS {
+		var output string
+
+		if err == btrfsErrNoQuota {
+			// Enable quotas
+			poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+
+			output, err = shared.RunCommand("btrfs", "quota", "enable", poolMntPoint)
+			if err != nil {
+				return fmt.Errorf("Failed to enable quotas on BTRFS pool: %s", output)
+			}
+
+			// Retry
+			qgroup, err = btrfsSubVolumeQGroup(subvol)
 		}
 
-		// Enable quotas
-		poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
-		output, err := shared.RunCommand(
-			"btrfs", "quota", "enable", poolMntPoint)
-		if err != nil && !s.s.OS.RunningInUserNS {
-			return fmt.Errorf("Failed to enable quotas on BTRFS pool: %s", output)
+		if err == btrfsErrNoQGroup {
+			// Find the volume ID
+			output, err = shared.RunCommand("btrfs", "subvolume", "show", subvol)
+			if err != nil {
+				return fmt.Errorf("Failed to get subvol information: %s", output)
+			}
+
+			id := ""
+			for _, line := range strings.Split(output, "\n") {
+				line = strings.TrimSpace(line)
+				if strings.HasPrefix(line, "Subvolume ID:") {
+					fields := strings.Split(line, ":")
+					id = strings.TrimSpace(fields[len(fields)-1])
+				}
+			}
+
+			if id == "" {
+				return fmt.Errorf("Failed to find subvolume id")
+			}
+
+			// Create qgroup
+			output, err = shared.RunCommand("btrfs", "qgroup", "create", fmt.Sprintf("0/%s", id), subvol)
+			if err != nil {
+				return fmt.Errorf("Failed to create missing qgroup: %s", output)
+			}
+
+			// Retry
+			qgroup, err = btrfsSubVolumeQGroup(subvol)
+		}
+
+		if err != nil {
+			return err
 		}
 	}
 


More information about the lxc-devel mailing list