kernel.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // +build !windows
  2. package kernel
  3. import (
  4. "bytes"
  5. "errors"
  6. "fmt"
  7. )
  8. type KernelVersionInfo struct {
  9. Kernel int
  10. Major int
  11. Minor int
  12. Flavor string
  13. }
  14. func (k *KernelVersionInfo) String() string {
  15. return fmt.Sprintf("%d.%d.%d%s", k.Kernel, k.Major, k.Minor, k.Flavor)
  16. }
  17. // Compare two KernelVersionInfo struct.
  18. // Returns -1 if a < b, 0 if a == b, 1 it a > b
  19. func CompareKernelVersion(a, b *KernelVersionInfo) int {
  20. if a.Kernel < b.Kernel {
  21. return -1
  22. } else if a.Kernel > b.Kernel {
  23. return 1
  24. }
  25. if a.Major < b.Major {
  26. return -1
  27. } else if a.Major > b.Major {
  28. return 1
  29. }
  30. if a.Minor < b.Minor {
  31. return -1
  32. } else if a.Minor > b.Minor {
  33. return 1
  34. }
  35. return 0
  36. }
  37. func GetKernelVersion() (*KernelVersionInfo, error) {
  38. var (
  39. err error
  40. )
  41. uts, err := uname()
  42. if err != nil {
  43. return nil, err
  44. }
  45. release := make([]byte, len(uts.Release))
  46. i := 0
  47. for _, c := range uts.Release {
  48. release[i] = byte(c)
  49. i++
  50. }
  51. // Remove the \x00 from the release for Atoi to parse correctly
  52. release = release[:bytes.IndexByte(release, 0)]
  53. return ParseRelease(string(release))
  54. }
  55. func ParseRelease(release string) (*KernelVersionInfo, error) {
  56. var (
  57. kernel, major, minor, parsed int
  58. flavor, partial string
  59. )
  60. // Ignore error from Sscanf to allow an empty flavor. Instead, just
  61. // make sure we got all the version numbers.
  62. parsed, _ = fmt.Sscanf(release, "%d.%d%s", &kernel, &major, &partial)
  63. if parsed < 2 {
  64. return nil, errors.New("Can't parse kernel version " + release)
  65. }
  66. // sometimes we have 3.12.25-gentoo, but sometimes we just have 3.12-1-amd64
  67. parsed, _ = fmt.Sscanf(partial, ".%d%s", &minor, &flavor)
  68. if parsed < 1 {
  69. flavor = partial
  70. }
  71. return &KernelVersionInfo{
  72. Kernel: kernel,
  73. Major: major,
  74. Minor: minor,
  75. Flavor: flavor,
  76. }, nil
  77. }