util_linux.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // +build linux
  2. package util
  3. import (
  4. "bufio"
  5. "bytes"
  6. "os"
  7. "os/exec"
  8. "path/filepath"
  9. "strings"
  10. "syscall"
  11. "github.com/SvenDowideit/cpuid"
  12. "github.com/docker/docker/pkg/mount"
  13. "github.com/rancher/os/log"
  14. )
  15. func mountProc() error {
  16. if _, err := os.Stat("/proc/self/mountinfo"); os.IsNotExist(err) {
  17. if _, err := os.Stat("/proc"); os.IsNotExist(err) {
  18. if err = os.Mkdir("/proc", 0755); err != nil {
  19. return err
  20. }
  21. }
  22. if err := syscall.Mount("none", "/proc", "proc", 0, ""); err != nil {
  23. return err
  24. }
  25. }
  26. return nil
  27. }
  28. func Mount(device, target, fsType, options string) error {
  29. if err := mountProc(); err != nil {
  30. return nil
  31. }
  32. bindMount := false
  33. for _, v := range strings.Split(options, ",") {
  34. if v == "bind" {
  35. bindMount = true
  36. break
  37. }
  38. }
  39. if bindMount {
  40. deviceInfo, err := os.Stat(device)
  41. if err != nil {
  42. return err
  43. }
  44. mode := deviceInfo.Mode()
  45. switch {
  46. case mode.IsDir():
  47. if err := os.MkdirAll(target, 0755); err != nil {
  48. return err
  49. }
  50. case mode.IsRegular():
  51. err := os.MkdirAll(filepath.Dir(target), 0755)
  52. if err != nil {
  53. return err
  54. }
  55. file, err := os.OpenFile(target, os.O_CREATE, mode&os.ModePerm)
  56. if err != nil {
  57. return err
  58. }
  59. if err := file.Close(); err != nil {
  60. return err
  61. }
  62. default:
  63. return os.ErrInvalid
  64. }
  65. } else {
  66. err := os.MkdirAll(target, 0755)
  67. if err != nil {
  68. return err
  69. }
  70. if fsType == "auto" || fsType == "" {
  71. inferredType, err := GetFsType(device)
  72. if err != nil {
  73. return err
  74. }
  75. fsType = inferredType
  76. }
  77. }
  78. return mount.Mount(device, target, fsType, options)
  79. }
  80. func Unmount(target string) error {
  81. return mount.Unmount(target)
  82. }
  83. func Blkid(label string) (deviceName, deviceType string) {
  84. // Not all blkid's have `blkid -L label (see busybox/alpine)
  85. cmd := exec.Command("blkid")
  86. cmd.Stderr = os.Stderr
  87. out, err := cmd.Output()
  88. if err != nil {
  89. log.Errorf("Failed to run blkid: %s", err)
  90. return
  91. }
  92. r := bytes.NewReader(out)
  93. s := bufio.NewScanner(r)
  94. for s.Scan() {
  95. line := s.Text()
  96. //log.Debugf("blkid: %s", cmd, line)
  97. if !strings.Contains(line, `LABEL="`+label+`"`) {
  98. continue
  99. }
  100. d := strings.Split(line, ":")
  101. deviceName = d[0]
  102. s1 := strings.Split(line, `TYPE="`)
  103. s2 := strings.Split(s1[1], `"`)
  104. deviceType = s2[0]
  105. log.Debugf("blkid type of %s: %s", deviceName, deviceType)
  106. return
  107. }
  108. return
  109. }
  110. // GetHypervisor tries to detect if we're running in a VM, and returns a string for its type
  111. func GetHypervisor() string {
  112. if cpuid.CPU.HypervisorName == "" {
  113. log.Infof("ros init: No Detected Hypervisor")
  114. } else {
  115. log.Infof("ros init: Detected Hypervisor: %s", cpuid.CPU.HypervisorName)
  116. }
  117. return cpuid.CPU.HypervisorName
  118. }