[lxc-devel] [lxd/master] idmap: support skipping directories

brauner on Github lxc-bot at linuxcontainers.org
Wed Jun 27 13:09:03 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 381 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180627/2377e7b6/attachment.bin>
-------------- next part --------------
From 8b5d15294b1a290f2c5e53360ed04c365d8263e9 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 27 Jun 2018 15:07:50 +0200
Subject: [PATCH] idmap: support skipping directories

Closes #4690.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/container_lxc.go           | 25 ++++++++++++++++++++-----
 lxd/storage.go                 |  9 +++++++--
 lxd/storage_btrfs.go           |  3 ++-
 lxd/storage_ceph.go            |  2 +-
 lxd/storage_dir.go             |  2 +-
 lxd/storage_lvm.go             |  2 +-
 lxd/storage_shared.go          |  4 ++--
 lxd/storage_zfs.go             |  2 +-
 shared/idmap/idmapset_linux.go | 29 +++++++++++++++++++++--------
 9 files changed, 56 insertions(+), 22 deletions(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 4284e3a55..1bd4203a8 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -1947,8 +1947,12 @@ func (c *containerLXC) startCommon() (string, error) {
 			return "", err
 		}
 
+		var skipDirs []string
+		if c.Storage().GetStorageType() == storageTypeZfs {
+			skipDirs = []string{"/.zfs/snapshot"}
+		}
 		if lastIdmap != nil {
-			err = lastIdmap.UnshiftRootfs(c.RootfsPath())
+			err = lastIdmap.UnshiftRootfs(c.RootfsPath(), skipDirs)
 			if err != nil {
 				if ourStart {
 					c.StorageStop()
@@ -1958,7 +1962,7 @@ func (c *containerLXC) startCommon() (string, error) {
 		}
 
 		if idmap != nil {
-			err = idmap.ShiftRootfs(c.RootfsPath())
+			err = idmap.ShiftRootfs(c.RootfsPath(), skipDirs)
 			if err != nil {
 				if ourStart {
 					c.StorageStop()
@@ -4819,12 +4823,18 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 	}
 
 	if idmap != nil {
-		if err := idmap.UnshiftRootfs(c.RootfsPath()); err != nil {
+		var skipDirs []string
+		if c.Storage().GetStorageType() == storageTypeZfs {
+			skipDirs = []string{"/.zfs/snapshot"}
+		}
+
+		err := idmap.UnshiftRootfs(c.RootfsPath(), skipDirs)
+		if err != nil {
 			logger.Error("Failed exporting container", ctxMap)
 			return err
 		}
 
-		defer idmap.ShiftRootfs(c.RootfsPath())
+		defer idmap.ShiftRootfs(c.RootfsPath(), skipDirs)
 	}
 
 	// Create the tarball
@@ -5133,7 +5143,12 @@ func (c *containerLXC) Migrate(args *CriuMigrationArgs) error {
 				return err
 			}
 
-			err = idmapset.ShiftRootfs(args.stateDir)
+			var skipDirs []string
+			if c.Storage().GetStorageType() == storageTypeZfs {
+				skipDirs = []string{"/.zfs/snapshot"}
+			}
+
+			err = idmapset.ShiftRootfs(args.stateDir, skipDirs)
 			if ourStart {
 				_, err2 := c.StorageStop()
 				if err != nil {
diff --git a/lxd/storage.go b/lxd/storage.go
index f8656767f..9f24bfc5a 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -489,9 +489,14 @@ func storagePoolVolumeAttachInit(s *state.State, poolName string, volumeName str
 			}()
 		}
 
+		var skipDirs []string
+		if st.GetStorageType() == storageTypeZfs {
+			skipDirs = []string{"/.zfs/snapshot"}
+		}
+
 		// unshift rootfs
 		if lastIdmap != nil {
-			err := lastIdmap.UnshiftRootfs(remapPath)
+			err := lastIdmap.UnshiftRootfs(remapPath, skipDirs)
 			if err != nil {
 				logger.Errorf("Failed to unshift \"%s\"", remapPath)
 				return nil, err
@@ -501,7 +506,7 @@ func storagePoolVolumeAttachInit(s *state.State, poolName string, volumeName str
 
 		// shift rootfs
 		if nextIdmap != nil {
-			err := nextIdmap.ShiftRootfs(remapPath)
+			err := nextIdmap.ShiftRootfs(remapPath, skipDirs)
 			if err != nil {
 				logger.Errorf("Failed to shift \"%s\"", remapPath)
 				return nil, err
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index a0d11605f..54666d2cd 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -830,7 +830,8 @@ func (s *storageBtrfs) ContainerCreateFromImage(container container, fingerprint
 	}
 
 	if !container.IsPrivileged() {
-		if err = s.shiftRootfs(container); err != nil {
+		err := s.shiftRootfs(container, nil)
+		if err != nil {
 			s.ContainerDelete(container)
 			return err
 		}
diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index b3aaab165..e5dfdd15f 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -882,7 +882,7 @@ func (s *storageCeph) ContainerCreateFromImage(container container, fingerprint
 	}
 
 	if !privileged {
-		err := s.shiftRootfs(container)
+		err := s.shiftRootfs(container, nil)
 		if err != nil {
 			logger.Errorf(`Failed to shift rootfs for container "%s": %s`, containerName, err)
 			return err
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index eebf44f73..4462c39e9 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -517,7 +517,7 @@ func (s *storageDir) ContainerCreateFromImage(container container, imageFingerpr
 	}
 
 	if !privileged {
-		err := s.shiftRootfs(container)
+		err := s.shiftRootfs(container, nil)
 		if err != nil {
 			return err
 		}
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index 17296a144..18ea22f44 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -984,7 +984,7 @@ func (s *storageLvm) ContainerCreateFromImage(container container, fingerprint s
 	}
 
 	if !container.IsPrivileged() {
-		err := s.shiftRootfs(container)
+		err := s.shiftRootfs(container, nil)
 		if err != nil {
 			return err
 		}
diff --git a/lxd/storage_shared.go b/lxd/storage_shared.go
index d0e16e470..828065302 100644
--- a/lxd/storage_shared.go
+++ b/lxd/storage_shared.go
@@ -34,7 +34,7 @@ func (s *storageShared) GetStorageTypeVersion() string {
 	return s.sTypeVersion
 }
 
-func (s *storageShared) shiftRootfs(c container) error {
+func (s *storageShared) shiftRootfs(c container, skipDirs []string) error {
 	dpath := c.Path()
 	rpath := c.RootfsPath()
 
@@ -49,7 +49,7 @@ func (s *storageShared) shiftRootfs(c container) error {
 		return fmt.Errorf("IdmapSet of container '%s' is nil", c.Name())
 	}
 
-	err = idmapset.ShiftRootfs(rpath)
+	err = idmapset.ShiftRootfs(rpath, skipDirs)
 	if err != nil {
 		logger.Debugf("Shift of rootfs %s failed: %s", rpath, err)
 		return err
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index dbed998e7..0babd0d4a 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -823,7 +823,7 @@ func (s *storageZfs) ContainerCreateFromImage(container container, fingerprint s
 	}
 
 	if !privileged {
-		err = s.shiftRootfs(container)
+		err = s.shiftRootfs(container, []string{".zfs/snapshot"})
 		if err != nil {
 			return err
 		}
diff --git a/shared/idmap/idmapset_linux.go b/shared/idmap/idmapset_linux.go
index a13572410..9364f5e02 100644
--- a/shared/idmap/idmapset_linux.go
+++ b/shared/idmap/idmapset_linux.go
@@ -13,6 +13,7 @@ import (
 	"strings"
 
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 type IdRange struct {
@@ -467,7 +468,7 @@ func (m IdmapSet) ShiftFromNs(uid int64, gid int64) (int64, int64) {
 	return m.doShiftIntoNs(uid, gid, "out")
 }
 
-func (set *IdmapSet) doUidshiftIntoContainer(dir string, testmode bool, how string) error {
+func (set *IdmapSet) doUidshiftIntoContainer(dir string, testmode bool, how string, skipDirs []string) error {
 	// Expand any symlink before the final path component
 	tmp := filepath.Dir(dir)
 	tmp, err := filepath.EvalSymlinks(tmp)
@@ -483,6 +484,18 @@ func (set *IdmapSet) doUidshiftIntoContainer(dir string, testmode bool, how stri
 			return err
 		}
 
+		if skipDirs != nil && len(skipDirs) > 0 {
+			strippedPath := path
+			if dir != "" {
+				strippedPath = path[len(dir):]
+			}
+
+			if fi.IsDir() && shared.StringInSlice(strippedPath, skipDirs) {
+				logger.Errorf("SKIPPING: %s", strippedPath)
+				return filepath.SkipDir
+			}
+		}
+
 		intUid, intGid, _, _, inode, nlink, err := shared.GetFileStat(path)
 		if err != nil {
 			return err
@@ -534,23 +547,23 @@ func (set *IdmapSet) doUidshiftIntoContainer(dir string, testmode bool, how stri
 }
 
 func (set *IdmapSet) UidshiftIntoContainer(dir string, testmode bool) error {
-	return set.doUidshiftIntoContainer(dir, testmode, "in")
+	return set.doUidshiftIntoContainer(dir, testmode, "in", nil)
 }
 
 func (set *IdmapSet) UidshiftFromContainer(dir string, testmode bool) error {
-	return set.doUidshiftIntoContainer(dir, testmode, "out")
+	return set.doUidshiftIntoContainer(dir, testmode, "out", nil)
 }
 
-func (set *IdmapSet) ShiftRootfs(p string) error {
-	return set.doUidshiftIntoContainer(p, false, "in")
+func (set *IdmapSet) ShiftRootfs(p string, skipDirs []string) error {
+	return set.doUidshiftIntoContainer(p, false, "in", skipDirs)
 }
 
-func (set *IdmapSet) UnshiftRootfs(p string) error {
-	return set.doUidshiftIntoContainer(p, false, "out")
+func (set *IdmapSet) UnshiftRootfs(p string, skipDirs []string) error {
+	return set.doUidshiftIntoContainer(p, false, "out", skipDirs)
 }
 
 func (set *IdmapSet) ShiftFile(p string) error {
-	return set.ShiftRootfs(p)
+	return set.ShiftRootfs(p, nil)
 }
 
 /*


More information about the lxc-devel mailing list