Kaynağa Gözat

Merge pull request #39780 from dmcgowan/fix-overlay-mount-busy

Fix overlay2 busy error on mount
Yong Tang 5 yıl önce
ebeveyn
işleme
2a64e344b7
1 değiştirilmiş dosya ile 29 ekleme ve 6 silme
  1. 29 6
      daemon/graphdriver/overlay2/overlay.go

+ 29 - 6
daemon/graphdriver/overlay2/overlay.go

@@ -446,6 +446,10 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr
 		return err
 		return err
 	}
 	}
 
 
+	if err := ioutil.WriteFile(path.Join(d.dir(parent), "committed"), []byte{}, 0600); err != nil {
+		return err
+	}
+
 	lower, err := d.getLower(parent)
 	lower, err := d.getLower(parent)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
@@ -592,7 +596,20 @@ func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, retErr e
 	for i, s := range splitLowers {
 	for i, s := range splitLowers {
 		absLowers[i] = path.Join(d.home, s)
 		absLowers[i] = path.Join(d.home, s)
 	}
 	}
-	opts := indexOff + "lowerdir=" + strings.Join(absLowers, ":") + ",upperdir=" + diffDir + ",workdir=" + workDir
+	var readonly bool
+	if _, err := os.Stat(path.Join(dir, "committed")); err == nil {
+		readonly = true
+	} else if !os.IsNotExist(err) {
+		return nil, err
+	}
+
+	var opts string
+	if readonly {
+		opts = indexOff + "lowerdir=" + diffDir + ":" + strings.Join(absLowers, ":")
+	} else {
+		opts = indexOff + "lowerdir=" + strings.Join(absLowers, ":") + ",upperdir=" + diffDir + ",workdir=" + workDir
+	}
+
 	mountData := label.FormatMountLabel(opts, mountLabel)
 	mountData := label.FormatMountLabel(opts, mountLabel)
 	mount := unix.Mount
 	mount := unix.Mount
 	mountTarget := mergedDir
 	mountTarget := mergedDir
@@ -612,7 +629,11 @@ func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, retErr e
 	// fit within a page and relative links make the mount data much
 	// fit within a page and relative links make the mount data much
 	// smaller at the expense of requiring a fork exec to chroot.
 	// smaller at the expense of requiring a fork exec to chroot.
 	if len(mountData) > pageSize {
 	if len(mountData) > pageSize {
-		opts = indexOff + "lowerdir=" + string(lowers) + ",upperdir=" + path.Join(id, diffDirName) + ",workdir=" + path.Join(id, workDirName)
+		if readonly {
+			opts = indexOff + "lowerdir=" + path.Join(id, diffDirName) + ":" + string(lowers)
+		} else {
+			opts = indexOff + "lowerdir=" + string(lowers) + ",upperdir=" + path.Join(id, diffDirName) + ",workdir=" + path.Join(id, workDirName)
+		}
 		mountData = label.FormatMountLabel(opts, mountLabel)
 		mountData = label.FormatMountLabel(opts, mountLabel)
 		if len(mountData) > pageSize {
 		if len(mountData) > pageSize {
 			return nil, fmt.Errorf("cannot mount layer, mount label too large %d", len(mountData))
 			return nil, fmt.Errorf("cannot mount layer, mount label too large %d", len(mountData))
@@ -628,10 +649,12 @@ func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, retErr e
 		return nil, fmt.Errorf("error creating overlay mount to %s: %v", mergedDir, err)
 		return nil, fmt.Errorf("error creating overlay mount to %s: %v", mergedDir, err)
 	}
 	}
 
 
-	// chown "workdir/work" to the remapped root UID/GID. Overlay fs inside a
-	// user namespace requires this to move a directory from lower to upper.
-	if err := os.Chown(path.Join(workDir, workDirName), rootUID, rootGID); err != nil {
-		return nil, err
+	if !readonly {
+		// chown "workdir/work" to the remapped root UID/GID. Overlay fs inside a
+		// user namespace requires this to move a directory from lower to upper.
+		if err := os.Chown(path.Join(workDir, workDirName), rootUID, rootGID); err != nil {
+			return nil, err
+		}
 	}
 	}
 
 
 	return containerfs.NewLocalContainerFS(mergedDir), nil
 	return containerfs.NewLocalContainerFS(mergedDir), nil