Browse Source

Allow root non-userns metadata backwards compatibility

Instead of creating a "0.0" subdirectory and migrating graphroot
metadata into it when user namespaces are available in the daemon
(currently only in experimental), change the graphroot dir permissions
to only include the execute bit for "other" users.

This allows easy migration to and from user namespaces and will allow
easier integration of user namespace support into the master build.

Docker-DCO-1.1-Signed-off-by: Phil Estes <estesp@linux.vnet.ibm.com> (github: estesp)
Phil Estes 9 years ago
parent
commit
e8532023f2

+ 19 - 37
daemon/daemon_experimental.go

@@ -10,7 +10,6 @@ import (
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/pkg/directory"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/idtools"
 )
 )
 
 
@@ -48,53 +47,36 @@ func setupRemappedRoot(config *Config) ([]idtools.IDMap, []idtools.IDMap, error)
 }
 }
 
 
 func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error {
 func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error {
-	// the main docker root needs to be accessible by all users, as user namespace support
-	// will create subdirectories owned by either a) the real system root (when no remapping
-	// is setup) or b) the remapped root host ID (when --root=uid:gid is used)
-	// for "first time" users of user namespaces, we need to migrate the current directory
-	// contents to the "0.0" (root == root "namespace" daemon root)
-	nsRoot := "0.0"
+	config.Root = rootDir
+	// the docker root metadata directory needs to have execute permissions for all users (o+x)
+	// so that syscalls executing as non-root, operating on subdirectories of the graph root
+	// (e.g. mounted layers of a container) can traverse this path.
+	// The user namespace support will create subdirectories for the remapped root host uid:gid
+	// pair owned by that same uid:gid pair for proper write access to those needed metadata and
+	// layer content subtrees.
 	if _, err := os.Stat(rootDir); err == nil {
 	if _, err := os.Stat(rootDir); err == nil {
-		// root current exists; we need to check for a prior migration
-		if _, err := os.Stat(filepath.Join(rootDir, nsRoot)); err != nil && os.IsNotExist(err) {
-			// need to migrate current root to "0.0" subroot
-			// 1. create non-usernamespaced root as "0.0"
-			if err := os.Mkdir(filepath.Join(rootDir, nsRoot), 0700); err != nil {
-				return fmt.Errorf("Cannot create daemon root %q: %v", filepath.Join(rootDir, nsRoot), err)
-			}
-			// 2. move current root content to "0.0" new subroot
-			if err := directory.MoveToSubdir(rootDir, nsRoot); err != nil {
-				return fmt.Errorf("Cannot migrate current daemon root %q for user namespaces: %v", rootDir, err)
-			}
-			// 3. chmod outer root to 755
-			if chmodErr := os.Chmod(rootDir, 0755); chmodErr != nil {
-				return chmodErr
-			}
-		}
-	} else if os.IsNotExist(err) {
-		// no root exists yet, create it 0755 with root:root ownership
-		if err := os.MkdirAll(rootDir, 0755); err != nil {
+		// root current exists; verify the access bits are correct by setting them
+		if err = os.Chmod(rootDir, 0701); err != nil {
 			return err
 			return err
 		}
 		}
-		// create the "0.0" subroot (so no future "migration" happens of the root)
-		if err := os.Mkdir(filepath.Join(rootDir, nsRoot), 0700); err != nil {
+	} else if os.IsNotExist(err) {
+		// no root exists yet, create it 0701 with root:root ownership
+		if err := os.MkdirAll(rootDir, 0701); err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}
 
 
-	// for user namespaces we will create a subtree underneath the specified root
+	// if user namespaces are enabled we will create a subtree underneath the specified root
 	// with any/all specified remapped root uid/gid options on the daemon creating
 	// with any/all specified remapped root uid/gid options on the daemon creating
 	// a new subdirectory with ownership set to the remapped uid/gid (so as to allow
 	// a new subdirectory with ownership set to the remapped uid/gid (so as to allow
 	// `chdir()` to work for containers namespaced to that uid/gid)
 	// `chdir()` to work for containers namespaced to that uid/gid)
 	if config.RemappedRoot != "" {
 	if config.RemappedRoot != "" {
-		nsRoot = fmt.Sprintf("%d.%d", rootUID, rootGID)
-	}
-	config.Root = filepath.Join(rootDir, nsRoot)
-	logrus.Debugf("Creating actual daemon root: %s", config.Root)
-
-	// Create the root directory if it doesn't exists
-	if err := idtools.MkdirAllAs(config.Root, 0700, rootUID, rootGID); err != nil {
-		return fmt.Errorf("Cannot create daemon root: %s: %v", config.Root, err)
+		config.Root = filepath.Join(rootDir, fmt.Sprintf("%d.%d", rootUID, rootGID))
+		logrus.Debugf("Creating user namespaced daemon root: %s", config.Root)
+		// Create the root directory if it doesn't exists
+		if err := idtools.MkdirAllAs(config.Root, 0700, rootUID, rootGID); err != nil {
+			return fmt.Errorf("Cannot create daemon root: %s: %v", config.Root, err)
+		}
 	}
 	}
 	return nil
 	return nil
 }
 }

+ 2 - 2
daemon/graphdriver/aufs/aufs.go

@@ -123,7 +123,7 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
 	// Create the root aufs driver dir and return
 	// Create the root aufs driver dir and return
 	// if it already exists
 	// if it already exists
 	// If not populate the dir structure
 	// If not populate the dir structure
-	if err := idtools.MkdirAllAs(root, 0755, rootUID, rootGID); err != nil {
+	if err := idtools.MkdirAllAs(root, 0700, rootUID, rootGID); err != nil {
 		if os.IsExist(err) {
 		if os.IsExist(err) {
 			return a, nil
 			return a, nil
 		}
 		}
@@ -136,7 +136,7 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
 
 
 	// Populate the dir structure
 	// Populate the dir structure
 	for _, p := range paths {
 	for _, p := range paths {
-		if err := idtools.MkdirAllAs(path.Join(root, p), 0755, rootUID, rootGID); err != nil {
+		if err := idtools.MkdirAllAs(path.Join(root, p), 0700, rootUID, rootGID); err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
 	}
 	}

+ 1 - 1
daemon/graphdriver/overlay/overlay.go

@@ -146,7 +146,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
 		return nil, err
 		return nil, err
 	}
 	}
 	// Create the driver home dir
 	// Create the driver home dir
-	if err := idtools.MkdirAllAs(home, 0755, rootUID, rootGID); err != nil && !os.IsExist(err) {
+	if err := idtools.MkdirAllAs(home, 0700, rootUID, rootGID); err != nil && !os.IsExist(err) {
 		return nil, err
 		return nil, err
 	}
 	}