|
9 | 9 | "path/filepath" |
10 | 10 | "reflect" |
11 | 11 | "strings" |
| 12 | + "syscall" |
12 | 13 | "unicode" |
13 | 14 | "unicode/utf8" |
14 | 15 |
|
@@ -405,13 +406,61 @@ func (v *Validator) CheckLinux() (msgs []string) { |
405 | 406 | rootfsPath = filepath.Join(v.bundlePath, v.spec.Root.Path) |
406 | 407 | } |
407 | 408 | absPath := filepath.Join(rootfsPath, device.Path) |
408 | | - _, err := os.Stat(absPath) |
| 409 | + fi, err := os.Stat(absPath) |
409 | 410 | if os.IsNotExist(err) { |
410 | 411 | devList[device.Path] = true |
411 | 412 | } else if err != nil { |
412 | 413 | msgs = append(msgs, err.Error()) |
413 | 414 | } else { |
414 | | - msgs = append(msgs, fmt.Sprintf("%s already exists in filesystem", device.Path)) |
| 415 | + fStat, ok := fi.Sys().(*syscall.Stat_t) |
| 416 | + if !ok { |
| 417 | + msgs = append(msgs, fmt.Sprintf("cannot determine state for device %s", device.Path)) |
| 418 | + continue |
| 419 | + } |
| 420 | + var devType string |
| 421 | + switch fStat.Mode & syscall.S_IFMT { |
| 422 | + case syscall.S_IFCHR: |
| 423 | + devType = "c" |
| 424 | + case syscall.S_IFBLK: |
| 425 | + devType = "b" |
| 426 | + case syscall.S_IFIFO: |
| 427 | + devType = "p" |
| 428 | + default: |
| 429 | + devType = "unmatched" |
| 430 | + } |
| 431 | + if devType != device.Type || (devType == "c" && device.Type == "u") { |
| 432 | + msgs = append(msgs, fmt.Sprintf("unmatched %s already exists in filesystem", device.Path)) |
| 433 | + continue |
| 434 | + } |
| 435 | + if devType != "p" { |
| 436 | + dev := fStat.Rdev |
| 437 | + major := (dev >> 8) & 0xfff |
| 438 | + minor := (dev & 0xff) | ((dev >> 12) & 0xfff00) |
| 439 | + if int64(major) != device.Major || int64(minor) != device.Minor { |
| 440 | + msgs = append(msgs, fmt.Sprintf("unmatched %s already exists in filesystem", device.Path)) |
| 441 | + continue |
| 442 | + } |
| 443 | + } |
| 444 | + if device.FileMode != nil { |
| 445 | + expectedPerm := *device.FileMode & os.ModePerm |
| 446 | + actualPerm := fi.Mode() & os.ModePerm |
| 447 | + if expectedPerm != actualPerm { |
| 448 | + msgs = append(msgs, fmt.Sprintf("unmatched %s already exists in filesystem", device.Path)) |
| 449 | + continue |
| 450 | + } |
| 451 | + } |
| 452 | + if device.UID != nil { |
| 453 | + if *device.UID != fStat.Uid { |
| 454 | + msgs = append(msgs, fmt.Sprintf("unmatched %s already exists in filesystem", device.Path)) |
| 455 | + continue |
| 456 | + } |
| 457 | + } |
| 458 | + if device.GID != nil { |
| 459 | + if *device.GID != fStat.Gid { |
| 460 | + msgs = append(msgs, fmt.Sprintf("unmatched %s already exists in filesystem", device.Path)) |
| 461 | + continue |
| 462 | + } |
| 463 | + } |
415 | 464 | } |
416 | 465 | } |
417 | 466 |
|
|
0 commit comments