diff --git a/daemon/daemon.go b/daemon/daemon.go index ef25960c52..1b2d13bb6d 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "os" "path" + "path/filepath" "regexp" "runtime" "strings" @@ -237,6 +238,8 @@ func (daemon *Daemon) register(container *Container, updateSuffixarray bool) err // we'll waste time if we update it for every container daemon.idIndex.Add(container.ID) + container.registerVolumes() + // FIXME: if the container is supposed to be running but is not, auto restart it? // if so, then we need to restart monitor and init a new lock // If the container is supposed to be running, make sure of it @@ -400,10 +403,6 @@ func (daemon *Daemon) restore() error { } } - for _, c := range registeredContainers { - c.registerVolumes() - } - if !debug { fmt.Println() log.Infof("Loading containers: done.") @@ -890,7 +889,7 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine) (*Daemon, error) return nil, err } - volumes, err := volumes.NewRepository(path.Join(config.Root, "volumes"), volumesDriver) + volumes, err := volumes.NewRepository(filepath.Join(config.Root, "volumes"), volumesDriver) if err != nil { return nil, err } diff --git a/daemon/volumes.go b/daemon/volumes.go index fa38b253fa..7b49733839 100644 --- a/daemon/volumes.go +++ b/daemon/volumes.go @@ -119,8 +119,23 @@ func (container *Container) VolumePaths() map[string]struct{} { } func (container *Container) registerVolumes() { - for _, mnt := range container.VolumeMounts() { - mnt.volume.AddContainer(container.ID) + for path := range container.VolumePaths() { + if v := container.daemon.volumes.Get(path); v != nil { + v.AddContainer(container.ID) + continue + } + + // if container was created with an old daemon, this volume may not be registered so we need to make sure it gets registered + writable := true + if rw, exists := container.VolumesRW[path]; exists { + writable = rw + } + v, err := container.daemon.volumes.FindOrCreateVolume(path, writable) + if err != nil { + log.Debugf("error registering volume %s: %v", path, err) + continue + } + v.AddContainer(container.ID) } } diff --git a/integration-cli/docker_cli_daemon_test.go b/integration-cli/docker_cli_daemon_test.go index dbc4d232b6..b7db552b62 100644 --- a/integration-cli/docker_cli_daemon_test.go +++ b/integration-cli/docker_cli_daemon_test.go @@ -317,3 +317,36 @@ func TestDaemonAllocatesListeningPort(t *testing.T) { logDone("daemon - daemon listening port is allocated") } + +// #9629 +func TestDaemonVolumesBindsRefs(t *testing.T) { + d := NewDaemon(t) + + if err := d.StartWithBusybox(); err != nil { + t.Fatal(err) + } + + tmp, err := ioutil.TempDir(os.TempDir(), "") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmp) + + if err := ioutil.WriteFile(tmp+"/test", []byte("testing"), 0655); err != nil { + t.Fatal(err) + } + + if out, err := d.Cmd("create", "-v", tmp+":/foo", "--name=voltest", "busybox"); err != nil { + t.Fatal(err, out) + } + + if err := d.Restart(); err != nil { + t.Fatal(err) + } + + if out, err := d.Cmd("run", "--volumes-from=voltest", "--name=consumer", "busybox", "/bin/sh", "-c", "[ -f /foo/test ]"); err != nil { + t.Fatal(err, out) + } + + logDone("daemon - bind refs in data-containers survive daemon restart") +} diff --git a/volumes/repository.go b/volumes/repository.go index 225148b60e..8219952243 100644 --- a/volumes/repository.go +++ b/volumes/repository.go @@ -87,16 +87,10 @@ func (r *Repository) restore() error { for _, v := range dir { id := v.Name() - path, err := r.driver.Get(id, "") - if err != nil { - log.Debugf("Could not find volume for %s: %v", id, err) - continue - } vol := &Volume{ ID: id, configPath: r.configPath + "/" + id, containers: make(map[string]struct{}), - Path: path, } if err := vol.FromDisk(); err != nil { if !os.IsNotExist(err) {