[lxc-devel] [lxd/master] Storage: Restore dir project quotas on import

tomponline on Github lxc-bot at linuxcontainers.org
Tue May 19 08:15:00 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 345 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200519/e860764c/attachment-0001.bin>
-------------- next part --------------
From aebc3dbbd7f4f5fbd39827ce61b9b577f31f5989 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 19 May 2020 08:54:35 +0100
Subject: [PATCH 1/5] lxd/storage/quota/projectquota: Fixes leaking file
 handles in quota_set_path and quota_get_path

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/quota/projectquota.go | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/lxd/storage/quota/projectquota.go b/lxd/storage/quota/projectquota.go
index c1b6b1ad1b..578b6db57d 100644
--- a/lxd/storage/quota/projectquota.go
+++ b/lxd/storage/quota/projectquota.go
@@ -22,6 +22,7 @@ import (
 #include <fcntl.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 #ifndef FS_XFLAG_PROJINHERIT
 struct fsxattr {
@@ -120,6 +121,7 @@ int quota_set_path(char *path, uint32_t id) {
 
 	ret = ioctl(fd, FS_IOC_FSGETXATTR, &attr);
 	if (ret < 0) {
+		close(fd);
 		return -1;
 	}
 
@@ -128,9 +130,11 @@ int quota_set_path(char *path, uint32_t id) {
 
 	ret = ioctl(fd, FS_IOC_FSSETXATTR, &attr);
 	if (ret < 0) {
+		close(fd);
 		return -1;
 	}
 
+	close(fd);
 	return 0;
 }
 
@@ -145,9 +149,11 @@ int32_t quota_get_path(char *path) {
 
 	ret = ioctl(fd, FS_IOC_FSGETXATTR, &attr);
 	if (ret < 0) {
+		close(fd);
 		return -1;
 	}
 
+	close(fd);
 	return attr.fsx_projid;
 }
 

From 6f5a4f43cd8218aab04e4d1c715f871394fdcc83 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 19 May 2020 08:56:50 +0100
Subject: [PATCH 2/5] lxd/storage/quota/projectquota: Adds inherit argument to
 quota_set_path

Allows disabling FS_XFLAG_PROJINHERIT flag on FS_IOC_FSSETXATTR so project can be set on non-directories.

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/quota/projectquota.go | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/lxd/storage/quota/projectquota.go b/lxd/storage/quota/projectquota.go
index 578b6db57d..a934db687d 100644
--- a/lxd/storage/quota/projectquota.go
+++ b/lxd/storage/quota/projectquota.go
@@ -22,6 +22,7 @@ import (
 #include <fcntl.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <stdbool.h>
 #include <unistd.h>
 
 #ifndef FS_XFLAG_PROJINHERIT
@@ -110,7 +111,7 @@ int quota_set(char *dev_path, uint32_t id, uint64_t hard_bytes) {
 	return 0;
 }
 
-int quota_set_path(char *path, uint32_t id) {
+int quota_set_path(char *path, uint32_t id, bool inherit) {
 	struct fsxattr attr;
 	int fd;
 	int ret;
@@ -125,7 +126,10 @@ int quota_set_path(char *path, uint32_t id) {
 		return -1;
 	}
 
-	attr.fsx_xflags |= FS_XFLAG_PROJINHERIT;
+	if (inherit) {
+		attr.fsx_xflags |= FS_XFLAG_PROJINHERIT;
+	}
+
 	attr.fsx_projid = id;
 
 	ret = ioctl(fd, FS_IOC_FSSETXATTR, &attr);

From 0ee371669945f42f150f4f9b639d0084da004b3a Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 19 May 2020 09:12:18 +0100
Subject: [PATCH 3/5] lxd/storage/quota/projectquota: Updates SetProject to
 recursively set project and support non-directory files

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/quota/projectquota.go | 41 +++++++++++++++++++++++++------
 1 file changed, 33 insertions(+), 8 deletions(-)

diff --git a/lxd/storage/quota/projectquota.go b/lxd/storage/quota/projectquota.go
index a934db687d..134ae259e0 100644
--- a/lxd/storage/quota/projectquota.go
+++ b/lxd/storage/quota/projectquota.go
@@ -4,6 +4,7 @@ import (
 	"bufio"
 	"fmt"
 	"os"
+	"path/filepath"
 	"strings"
 	"unsafe"
 
@@ -232,17 +233,41 @@ func GetProject(path string) (uint32, error) {
 	return uint32(id), nil
 }
 
-// SetProject sets the project quota ID for the given path
+// SetProject recursively sets the project quota ID (and project inherit flag on directories) for the given path.
 func SetProject(path string, id uint32) error {
-	// Call ioctl through CGo
-	cPath := C.CString(path)
-	defer C.free(unsafe.Pointer(cPath))
+	err := filepath.Walk(path, func(filePath string, info os.FileInfo, err error) error {
+		if err != nil {
+			return err
+		}
 
-	if C.quota_set_path(cPath, C.uint32_t(id)) != 0 {
-		return fmt.Errorf("Failed to set project id '%d' on '%s'", id, path)
-	}
+		inherit := false
 
-	return nil
+		if info.IsDir() {
+			inherit = true // Only can set FS_XFLAG_PROJINHERIT on directories.
+		}
+
+		// Call ioctl through CGo.
+		cPath := C.CString(filePath)
+		defer C.free(unsafe.Pointer(cPath))
+
+		if C.quota_set_path(cPath, C.uint32_t(id), C.bool(inherit)) != 0 {
+			// Currently project ID cannot be set on non-regular files after file creation.
+			// However if the parent directory has a project and the inherit flag set on it then
+			// non-regular files do get accounted for under the parent's project, so we do still try
+			// and set the post-create project on non-regular files in case at some point in the future
+			// this inconsistency in behavior is fixed. However because it doesn't work today we will
+			// ignore any errors setting project on non-regular files.
+			if !info.Mode().IsRegular() {
+				return nil
+			}
+
+			return fmt.Errorf(`Failed to set project ID "%d" on %q (inherit %t)`, id, filePath, inherit)
+		}
+
+		return nil
+	})
+
+	return err
 }
 
 // DeleteProject unsets the project id from the path and clears the quota for the project id

From e0577383e5edc10456adf62525bc343a0cb5671c Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 19 May 2020 09:12:59 +0100
Subject: [PATCH 4/5] lxd/storage/drivers/driver/dir/utils: Updates deleteQuota
 to use DeleteProject

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/drivers/driver_dir_utils.go | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/lxd/storage/drivers/driver_dir_utils.go b/lxd/storage/drivers/driver_dir_utils.go
index ba9bd00d2f..055456a308 100644
--- a/lxd/storage/drivers/driver_dir_utils.go
+++ b/lxd/storage/drivers/driver_dir_utils.go
@@ -74,12 +74,7 @@ func (d *dir) deleteQuota(path string, volID int64) error {
 		return nil
 	}
 
-	err = quota.SetProject(path, 0)
-	if err != nil {
-		return err
-	}
-
-	err = quota.SetProjectQuota(path, d.quotaProjectID(volID), 0)
+	err = quota.DeleteProject(path, d.quotaProjectID(volID))
 	if err != nil {
 		return err
 	}

From e8aebb3badf3ae48e9421f3bd6c6936e1a2cbc50 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 19 May 2020 09:13:54 +0100
Subject: [PATCH 5/5] lxd/storage/drivers/driver/dir/volumes: Adds quota revert
 in CreateVolumeFromBackup post hook

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/drivers/driver_dir_volumes.go | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/lxd/storage/drivers/driver_dir_volumes.go b/lxd/storage/drivers/driver_dir_volumes.go
index 1618cd7680..a980940e6e 100644
--- a/lxd/storage/drivers/driver_dir_volumes.go
+++ b/lxd/storage/drivers/driver_dir_volumes.go
@@ -108,11 +108,16 @@ func (d *dir) CreateVolumeFromBackup(vol Volume, srcBackup backup.Info, srcData
 			}
 		}
 
-		_, err := d.setupInitialQuota(vol)
+		revert := revert.New()
+		defer revert.Fail()
+
+		revertQuota, err := d.setupInitialQuota(vol)
 		if err != nil {
 			return err
 		}
+		revert.Add(revertQuota)
 
+		revert.Success()
 		return nil
 	}
 


More information about the lxc-devel mailing list