mounts.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package daemon // import "github.com/docker/docker/daemon"
  2. import (
  3. "context"
  4. "fmt"
  5. "strings"
  6. "github.com/containerd/log"
  7. mounttypes "github.com/docker/docker/api/types/mount"
  8. "github.com/docker/docker/container"
  9. volumesservice "github.com/docker/docker/volume/service"
  10. )
  11. func (daemon *Daemon) prepareMountPoints(container *container.Container) error {
  12. alive := container.IsRunning()
  13. for _, config := range container.MountPoints {
  14. if err := daemon.lazyInitializeVolume(container.ID, config); err != nil {
  15. return err
  16. }
  17. if config.Volume == nil {
  18. // FIXME(thaJeztah): should we check for config.Type here as well? (i.e., skip bind-mounts etc)
  19. continue
  20. }
  21. if alive {
  22. log.G(context.TODO()).WithFields(log.Fields{
  23. "container": container.ID,
  24. "volume": config.Volume.Name(),
  25. }).Debug("Live-restoring volume for alive container")
  26. if err := config.LiveRestore(context.TODO()); err != nil {
  27. return err
  28. }
  29. }
  30. }
  31. return nil
  32. }
  33. func (daemon *Daemon) removeMountPoints(container *container.Container, rm bool) error {
  34. var rmErrors []string
  35. ctx := context.TODO()
  36. for _, m := range container.MountPoints {
  37. if m.Type != mounttypes.TypeVolume || m.Volume == nil {
  38. continue
  39. }
  40. daemon.volumes.Release(ctx, m.Volume.Name(), container.ID)
  41. if !rm {
  42. continue
  43. }
  44. // Do not remove named mountpoints
  45. // these are mountpoints specified like `docker run -v <name>:/foo`
  46. if m.Spec.Source != "" {
  47. continue
  48. }
  49. err := daemon.volumes.Remove(ctx, m.Volume.Name())
  50. // Ignore volume in use errors because having this
  51. // volume being referenced by other container is
  52. // not an error, but an implementation detail.
  53. // This prevents docker from logging "ERROR: Volume in use"
  54. // where there is another container using the volume.
  55. if err != nil && !volumesservice.IsInUse(err) {
  56. rmErrors = append(rmErrors, err.Error())
  57. }
  58. }
  59. if len(rmErrors) > 0 {
  60. return fmt.Errorf("Error removing volumes:\n%v", strings.Join(rmErrors, "\n"))
  61. }
  62. return nil
  63. }