Browse Source

Check kernel version and display warning if too low

Guillaume J. Charmes 12 năm trước cách đây
mục cha
commit
003622c8b6
2 tập tin đã thay đổi với 112 bổ sung1 xóa
  1. 18 1
      runtime.go
  2. 94 0
      utils.go

+ 18 - 1
runtime.go

@@ -6,6 +6,7 @@ import (
 	"github.com/dotcloud/docker/auth"
 	"io"
 	"io/ioutil"
+	"log"
 	"os"
 	"os/exec"
 	"path"
@@ -23,6 +24,7 @@ type Runtime struct {
 	repositories   *TagStore
 	authConfig     *auth.AuthConfig
 	idIndex        *TruncIndex
+	kernelVersion  *KernelVersionInfo
 }
 
 var sysInitPath string
@@ -282,7 +284,22 @@ func (runtime *Runtime) restore() error {
 
 // FIXME: harmonize with NewGraph()
 func NewRuntime() (*Runtime, error) {
-	return NewRuntimeFromDirectory("/var/lib/docker")
+	runtime, err := NewRuntimeFromDirectory("/var/lib/docker")
+	if err != nil {
+		return nil, err
+	}
+
+	k, err := GetKernelVersion()
+	if err != nil {
+		return nil, err
+	}
+	runtime.kernelVersion = k
+
+	if CompareKernelVersion(k, &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}) < 0 {
+		log.Printf("WARNING: You are running linux kernel version %s, which might be unstable running docker. Please upgrade your kernel to 3.8.0.", k.String())
+	}
+
+	return runtime, nil
 }
 
 func NewRuntimeFromDirectory(root string) (*Runtime, error) {

+ 94 - 0
utils.go

@@ -13,8 +13,10 @@ import (
 	"os/exec"
 	"path/filepath"
 	"runtime"
+	"strconv"
 	"strings"
 	"sync"
+	"syscall"
 	"time"
 )
 
@@ -384,3 +386,95 @@ func CopyEscapable(dst io.Writer, src io.ReadCloser) (written int64, err error)
 	}
 	return written, err
 }
+
+type KernelVersionInfo struct {
+	Kernel   int
+	Major    int
+	Minor    int
+	Specific int
+}
+
+func GetKernelVersion() (*KernelVersionInfo, error) {
+	var uts syscall.Utsname
+
+	if err := syscall.Uname(&uts); err != nil {
+		return nil, err
+	}
+
+	release := make([]byte, len(uts.Release))
+
+	i := 0
+	for _, c := range uts.Release {
+		release[i] = byte(c)
+		i++
+	}
+
+	tmp := strings.SplitN(string(release), "-", 2)
+	if len(tmp) != 2 {
+		return nil, fmt.Errorf("Unrecognized kernel version")
+	}
+	tmp2 := strings.SplitN(tmp[0], ".", 3)
+	if len(tmp2) != 3 {
+		return nil, fmt.Errorf("Unrecognized kernel version")
+	}
+
+	kernel, err := strconv.Atoi(tmp2[0])
+	if err != nil {
+		return nil, err
+	}
+
+	major, err := strconv.Atoi(tmp2[1])
+	if err != nil {
+		return nil, err
+	}
+
+	minor, err := strconv.Atoi(tmp2[2])
+	if err != nil {
+		return nil, err
+	}
+
+	specific, err := strconv.Atoi(strings.Split(tmp[1], "-")[0])
+	if err != nil {
+		return nil, err
+	}
+
+	return &KernelVersionInfo{
+		Kernel:   kernel,
+		Major:    major,
+		Minor:    minor,
+		Specific: specific,
+	}, nil
+}
+
+func (k *KernelVersionInfo) String() string {
+	return fmt.Sprintf("%d.%d.%d-%d", k.Kernel, k.Major, k.Minor, k.Specific)
+}
+
+// Compare two KernelVersionInfo struct.
+// Returns -1 if a < b, = if a == b, 1 it a > b
+func CompareKernelVersion(a, b *KernelVersionInfo) int {
+	if a.Kernel < b.Kernel {
+		return -1
+	} else if a.Kernel > b.Kernel {
+		return 1
+	}
+
+	if a.Major < b.Major {
+		return -1
+	} else if a.Major > b.Major {
+		return 1
+	}
+
+	if a.Minor < b.Minor {
+		return -1
+	} else if a.Minor > b.Minor {
+		return 1
+	}
+
+	if a.Specific < b.Specific {
+		return -1
+	} else if a.Specific > b.Specific {
+		return 1
+	}
+	return 0
+}