| ... | ... |
@@ -6,6 +6,7 @@ import ( |
| 6 | 6 |
"github.com/dotcloud/docker/auth" |
| 7 | 7 |
"io" |
| 8 | 8 |
"io/ioutil" |
| 9 |
+ "log" |
|
| 9 | 10 |
"os" |
| 10 | 11 |
"os/exec" |
| 11 | 12 |
"path" |
| ... | ... |
@@ -23,6 +24,7 @@ type Runtime struct {
|
| 23 | 23 |
repositories *TagStore |
| 24 | 24 |
authConfig *auth.AuthConfig |
| 25 | 25 |
idIndex *TruncIndex |
| 26 |
+ kernelVersion *KernelVersionInfo |
|
| 26 | 27 |
} |
| 27 | 28 |
|
| 28 | 29 |
var sysInitPath string |
| ... | ... |
@@ -282,7 +284,22 @@ func (runtime *Runtime) restore() error {
|
| 282 | 282 |
|
| 283 | 283 |
// FIXME: harmonize with NewGraph() |
| 284 | 284 |
func NewRuntime() (*Runtime, error) {
|
| 285 |
- return NewRuntimeFromDirectory("/var/lib/docker")
|
|
| 285 |
+ runtime, err := NewRuntimeFromDirectory("/var/lib/docker")
|
|
| 286 |
+ if err != nil {
|
|
| 287 |
+ return nil, err |
|
| 288 |
+ } |
|
| 289 |
+ |
|
| 290 |
+ k, err := GetKernelVersion() |
|
| 291 |
+ if err != nil {
|
|
| 292 |
+ return nil, err |
|
| 293 |
+ } |
|
| 294 |
+ runtime.kernelVersion = k |
|
| 295 |
+ |
|
| 296 |
+ if CompareKernelVersion(k, &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}) < 0 {
|
|
| 297 |
+ 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())
|
|
| 298 |
+ } |
|
| 299 |
+ |
|
| 300 |
+ return runtime, nil |
|
| 286 | 301 |
} |
| 287 | 302 |
|
| 288 | 303 |
func NewRuntimeFromDirectory(root string) (*Runtime, error) {
|
| ... | ... |
@@ -13,8 +13,10 @@ import ( |
| 13 | 13 |
"os/exec" |
| 14 | 14 |
"path/filepath" |
| 15 | 15 |
"runtime" |
| 16 |
+ "strconv" |
|
| 16 | 17 |
"strings" |
| 17 | 18 |
"sync" |
| 19 |
+ "syscall" |
|
| 18 | 20 |
"time" |
| 19 | 21 |
) |
| 20 | 22 |
|
| ... | ... |
@@ -384,3 +386,95 @@ func CopyEscapable(dst io.Writer, src io.ReadCloser) (written int64, err error) |
| 384 | 384 |
} |
| 385 | 385 |
return written, err |
| 386 | 386 |
} |
| 387 |
+ |
|
| 388 |
+type KernelVersionInfo struct {
|
|
| 389 |
+ Kernel int |
|
| 390 |
+ Major int |
|
| 391 |
+ Minor int |
|
| 392 |
+ Specific int |
|
| 393 |
+} |
|
| 394 |
+ |
|
| 395 |
+func GetKernelVersion() (*KernelVersionInfo, error) {
|
|
| 396 |
+ var uts syscall.Utsname |
|
| 397 |
+ |
|
| 398 |
+ if err := syscall.Uname(&uts); err != nil {
|
|
| 399 |
+ return nil, err |
|
| 400 |
+ } |
|
| 401 |
+ |
|
| 402 |
+ release := make([]byte, len(uts.Release)) |
|
| 403 |
+ |
|
| 404 |
+ i := 0 |
|
| 405 |
+ for _, c := range uts.Release {
|
|
| 406 |
+ release[i] = byte(c) |
|
| 407 |
+ i++ |
|
| 408 |
+ } |
|
| 409 |
+ |
|
| 410 |
+ tmp := strings.SplitN(string(release), "-", 2) |
|
| 411 |
+ if len(tmp) != 2 {
|
|
| 412 |
+ return nil, fmt.Errorf("Unrecognized kernel version")
|
|
| 413 |
+ } |
|
| 414 |
+ tmp2 := strings.SplitN(tmp[0], ".", 3) |
|
| 415 |
+ if len(tmp2) != 3 {
|
|
| 416 |
+ return nil, fmt.Errorf("Unrecognized kernel version")
|
|
| 417 |
+ } |
|
| 418 |
+ |
|
| 419 |
+ kernel, err := strconv.Atoi(tmp2[0]) |
|
| 420 |
+ if err != nil {
|
|
| 421 |
+ return nil, err |
|
| 422 |
+ } |
|
| 423 |
+ |
|
| 424 |
+ major, err := strconv.Atoi(tmp2[1]) |
|
| 425 |
+ if err != nil {
|
|
| 426 |
+ return nil, err |
|
| 427 |
+ } |
|
| 428 |
+ |
|
| 429 |
+ minor, err := strconv.Atoi(tmp2[2]) |
|
| 430 |
+ if err != nil {
|
|
| 431 |
+ return nil, err |
|
| 432 |
+ } |
|
| 433 |
+ |
|
| 434 |
+ specific, err := strconv.Atoi(strings.Split(tmp[1], "-")[0]) |
|
| 435 |
+ if err != nil {
|
|
| 436 |
+ return nil, err |
|
| 437 |
+ } |
|
| 438 |
+ |
|
| 439 |
+ return &KernelVersionInfo{
|
|
| 440 |
+ Kernel: kernel, |
|
| 441 |
+ Major: major, |
|
| 442 |
+ Minor: minor, |
|
| 443 |
+ Specific: specific, |
|
| 444 |
+ }, nil |
|
| 445 |
+} |
|
| 446 |
+ |
|
| 447 |
+func (k *KernelVersionInfo) String() string {
|
|
| 448 |
+ return fmt.Sprintf("%d.%d.%d-%d", k.Kernel, k.Major, k.Minor, k.Specific)
|
|
| 449 |
+} |
|
| 450 |
+ |
|
| 451 |
+// Compare two KernelVersionInfo struct. |
|
| 452 |
+// Returns -1 if a < b, = if a == b, 1 it a > b |
|
| 453 |
+func CompareKernelVersion(a, b *KernelVersionInfo) int {
|
|
| 454 |
+ if a.Kernel < b.Kernel {
|
|
| 455 |
+ return -1 |
|
| 456 |
+ } else if a.Kernel > b.Kernel {
|
|
| 457 |
+ return 1 |
|
| 458 |
+ } |
|
| 459 |
+ |
|
| 460 |
+ if a.Major < b.Major {
|
|
| 461 |
+ return -1 |
|
| 462 |
+ } else if a.Major > b.Major {
|
|
| 463 |
+ return 1 |
|
| 464 |
+ } |
|
| 465 |
+ |
|
| 466 |
+ if a.Minor < b.Minor {
|
|
| 467 |
+ return -1 |
|
| 468 |
+ } else if a.Minor > b.Minor {
|
|
| 469 |
+ return 1 |
|
| 470 |
+ } |
|
| 471 |
+ |
|
| 472 |
+ if a.Specific < b.Specific {
|
|
| 473 |
+ return -1 |
|
| 474 |
+ } else if a.Specific > b.Specific {
|
|
| 475 |
+ return 1 |
|
| 476 |
+ } |
|
| 477 |
+ return 0 |
|
| 478 |
+} |