浏览代码

Merge pull request #6098 from crosbymichael/retry-mount

Handle EBUSY on remount
Victor Marmol 11 年之前
父节点
当前提交
f65f1660c0
共有 1 个文件被更改,包括 17 次插入10 次删除
  1. 17 10
      pkg/libcontainer/security/restrict/restrict.go

+ 17 - 10
pkg/libcontainer/security/restrict/restrict.go

@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"os"
 	"syscall"
+	"time"
 
 	"github.com/dotcloud/docker/pkg/system"
 )
@@ -13,20 +14,25 @@ import (
 const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV
 
 func mountReadonly(path string) error {
-	if err := system.Mount("", path, "", syscall.MS_REMOUNT|syscall.MS_RDONLY, ""); err != nil {
-		if err == syscall.EINVAL {
-			// Probably not a mountpoint, use bind-mount
-			if err := system.Mount(path, path, "", syscall.MS_BIND, ""); err != nil {
+	for i := 0; i < 5; i++ {
+		if err := system.Mount("", path, "", syscall.MS_REMOUNT|syscall.MS_RDONLY, ""); err != nil {
+			switch err {
+			case syscall.EINVAL:
+				// Probably not a mountpoint, use bind-mount
+				if err := system.Mount(path, path, "", syscall.MS_BIND, ""); err != nil {
+					return err
+				}
+				return system.Mount(path, path, "", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC|defaultMountFlags, "")
+			case syscall.EBUSY:
+				time.Sleep(100 * time.Millisecond)
+				continue
+			default:
 				return err
 			}
-			if err := system.Mount(path, path, "", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC|defaultMountFlags, ""); err != nil {
-				return err
-			}
-		} else {
-			return err
 		}
+		return nil
 	}
-	return nil
+	return fmt.Errorf("unable to mount %s as readonly max retries reached", path)
 }
 
 // This has to be called while the container still has CAP_SYS_ADMIN (to be able to perform mounts).
@@ -38,6 +44,7 @@ func Restrict(mounts ...string) error {
 			return fmt.Errorf("unable to remount %s readonly: %s", dest, err)
 		}
 	}
+
 	if err := system.Mount("/dev/null", "/proc/kcore", "", syscall.MS_BIND, ""); err != nil && !os.IsNotExist(err) {
 		return fmt.Errorf("unable to bind-mount /dev/null over /proc/kcore: %s", err)
 	}