util_linux.go 2.3 KB

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