daemon_linux.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package daemon
  2. import (
  3. "bufio"
  4. "fmt"
  5. "io"
  6. "os"
  7. "regexp"
  8. "strings"
  9. "github.com/docker/docker/pkg/fileutils"
  10. "github.com/docker/docker/pkg/mount"
  11. "github.com/sirupsen/logrus"
  12. )
  13. // On Linux, plugins use a static path for storing execution state,
  14. // instead of deriving path from daemon's exec-root. This is because
  15. // plugin socket files are created here and they cannot exceed max
  16. // path length of 108 bytes.
  17. func getPluginExecRoot(root string) string {
  18. return "/run/docker/plugins"
  19. }
  20. func (daemon *Daemon) cleanupMountsByID(id string) error {
  21. logrus.Debugf("Cleaning up old mountid %s: start.", id)
  22. f, err := os.Open("/proc/self/mountinfo")
  23. if err != nil {
  24. return err
  25. }
  26. defer f.Close()
  27. return daemon.cleanupMountsFromReaderByID(f, id, mount.Unmount)
  28. }
  29. func (daemon *Daemon) cleanupMountsFromReaderByID(reader io.Reader, id string, unmount func(target string) error) error {
  30. if daemon.root == "" {
  31. return nil
  32. }
  33. var errors []string
  34. regexps := getCleanPatterns(id)
  35. sc := bufio.NewScanner(reader)
  36. for sc.Scan() {
  37. if fields := strings.Fields(sc.Text()); len(fields) >= 4 {
  38. if mnt := fields[4]; strings.HasPrefix(mnt, daemon.root) {
  39. for _, p := range regexps {
  40. if p.MatchString(mnt) {
  41. if err := unmount(mnt); err != nil {
  42. logrus.Error(err)
  43. errors = append(errors, err.Error())
  44. }
  45. }
  46. }
  47. }
  48. }
  49. }
  50. if err := sc.Err(); err != nil {
  51. return err
  52. }
  53. if len(errors) > 0 {
  54. return fmt.Errorf("Error cleaning up mounts:\n%v", strings.Join(errors, "\n"))
  55. }
  56. logrus.Debugf("Cleaning up old mountid %v: done.", id)
  57. return nil
  58. }
  59. // cleanupMounts umounts shm/mqueue mounts for old containers
  60. func (daemon *Daemon) cleanupMounts() error {
  61. return daemon.cleanupMountsByID("")
  62. }
  63. func getCleanPatterns(id string) (regexps []*regexp.Regexp) {
  64. var patterns []string
  65. if id == "" {
  66. id = "[0-9a-f]{64}"
  67. patterns = append(patterns, "containers/"+id+"/shm")
  68. }
  69. patterns = append(patterns, "aufs/mnt/"+id+"$", "overlay/"+id+"/merged$", "zfs/graph/"+id+"$")
  70. for _, p := range patterns {
  71. r, err := regexp.Compile(p)
  72. if err == nil {
  73. regexps = append(regexps, r)
  74. }
  75. }
  76. return
  77. }
  78. func getRealPath(path string) (string, error) {
  79. return fileutils.ReadSymlinkedDirectory(path)
  80. }