Merge pull request #20526 from tiborvass/1.10.2-cherrypicks

1.10.2 cherrypicks
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4ee73c4..4f0e862 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,35 @@
 https://docs.docker.com/misc/deprecated/ where target removal dates can also
 be found.
 
+## 1.10.2 (2016-02-22)
+
+### Runtime
+
+- Prevent systemd from deleting containers' cgroups when its configuration is reloaded [#20518](https://github.com/docker/docker/pull/20518)
+- Fix SELinux issues by disregarding `--read-only` when mounting `/dev/mqueue` [#20333](https://github.com/docker/docker/pull/20333)
+- Fix chown permissions used during `docker cp` when userns is used [#20446](https://github.com/docker/docker/pull/20446)
+- Fix configuration loading issue with all booleans defaulting to `true` [#20471](https://github.com/docker/docker/pull/20471)
+- Fix occasional panic with `docker logs -f` [#20522](https://github.com/docker/docker/pull/20522)
+
+### Distribution
+
+- Keep layer reference if deletion failed to avoid a badly inconsistent state [#20513](https://github.com/docker/docker/pull/20513)
+- Handle gracefully a corner case when canceling migration [#20372](https://github.com/docker/docker/pull/20372)
+- Fix docker import on compressed data [#20367](https://github.com/docker/docker/pull/20367)
+- Fix tar-split files corruption during migration that later cause docker push and docker save to fail [#20458](https://github.com/docker/docker/pull/20458)
+
+### Networking
+
+- Fix daemon crash if embedded DNS is sent garbage [#20510](https://github.com/docker/docker/pull/20510)
+
+### Volumes
+
+- Fix issue with multiple volume references with same name [#20381](https://github.com/docker/docker/pull/20381)
+
+### Security
+
+- Fix potential cache corruption and delegation conflict issues [#20523](https://github.com/docker/docker/pull/20523)
+
 ## 1.10.1 (2016-02-11)
 
 ### Runtime
diff --git a/daemon/archive.go b/daemon/archive.go
index 4ac667d..ee4442b 100644
--- a/daemon/archive.go
+++ b/daemon/archive.go
@@ -248,13 +248,13 @@
 		return ErrRootFSReadOnly
 	}
 
+	uid, gid := daemon.GetRemappedUIDGID()
 	options := &archive.TarOptions{
-		ChownOpts: &archive.TarChownOptions{
-			UID: 0, GID: 0, // TODO: use config.User? Remap to userns root?
-		},
 		NoOverwriteDirNonDir: noOverwriteDirNonDir,
+		ChownOpts: &archive.TarChownOptions{
+			UID: uid, GID: gid, // TODO: should all ownership be set to root (either real or remapped)?
+		},
 	}
-
 	if err := chrootarchive.Untar(content, resolvedPath, options); err != nil {
 		return err
 	}
diff --git a/daemon/config.go b/daemon/config.go
index 77bf6cf..8e063c0 100644
--- a/daemon/config.go
+++ b/daemon/config.go
@@ -151,14 +151,20 @@
 }
 
 // ReloadConfiguration reads the configuration in the host and reloads the daemon and server.
-func ReloadConfiguration(configFile string, flags *flag.FlagSet, reload func(*Config)) {
+func ReloadConfiguration(configFile string, flags *flag.FlagSet, reload func(*Config)) error {
 	logrus.Infof("Got signal to reload configuration, reloading from: %s", configFile)
 	newConfig, err := getConflictFreeConfiguration(configFile, flags)
 	if err != nil {
-		logrus.Error(err)
-	} else {
-		reload(newConfig)
+		return err
 	}
+	reload(newConfig)
+	return nil
+}
+
+// boolValue is an interface that boolean value flags implement
+// to tell the command line how to make -name equivalent to -name=true.
+type boolValue interface {
+	IsBoolFlag() bool
 }
 
 // MergeDaemonConfigurations reads a configuration file,
@@ -203,6 +209,36 @@
 			return nil, err
 		}
 
+		// Override flag values to make sure the values set in the config file with nullable values, like `false`,
+		// are not overriden by default truthy values from the flags that were not explicitly set.
+		// See https://github.com/docker/docker/issues/20289 for an example.
+		//
+		// TODO: Rewrite configuration logic to avoid same issue with other nullable values, like numbers.
+		namedOptions := make(map[string]interface{})
+		for key, value := range configSet {
+			f := flags.Lookup("-" + key)
+			if f == nil { // ignore named flags that don't match
+				namedOptions[key] = value
+				continue
+			}
+
+			if _, ok := f.Value.(boolValue); ok {
+				f.Value.Set(fmt.Sprintf("%v", value))
+			}
+		}
+		if len(namedOptions) > 0 {
+			// set also default for mergeVal flags that are boolValue at the same time.
+			flags.VisitAll(func(f *flag.Flag) {
+				if opt, named := f.Value.(opts.NamedOption); named {
+					v, set := namedOptions[opt.Name()]
+					_, boolean := f.Value.(boolValue)
+					if set && boolean {
+						f.Value.Set(fmt.Sprintf("%v", v))
+					}
+				}
+			})
+		}
+
 		config.valuesSet = configSet
 	}
 
@@ -242,14 +278,16 @@
 
 	// 2. Discard values that implement NamedOption.
 	// Their configuration name differs from their flag name, like `labels` and `label`.
-	unknownNamedConflicts := func(f *flag.Flag) {
-		if namedOption, ok := f.Value.(opts.NamedOption); ok {
-			if _, valid := unknownKeys[namedOption.Name()]; valid {
-				delete(unknownKeys, namedOption.Name())
+	if len(unknownKeys) > 0 {
+		unknownNamedConflicts := func(f *flag.Flag) {
+			if namedOption, ok := f.Value.(opts.NamedOption); ok {
+				if _, valid := unknownKeys[namedOption.Name()]; valid {
+					delete(unknownKeys, namedOption.Name())
+				}
 			}
 		}
+		flags.VisitAll(unknownNamedConflicts)
 	}
-	flags.VisitAll(unknownNamedConflicts)
 
 	if len(unknownKeys) > 0 {
 		var unknown []string
diff --git a/daemon/execdriver/native/create.go b/daemon/execdriver/native/create.go
index 4cc1453..e3f56d9 100644
--- a/daemon/execdriver/native/create.go
+++ b/daemon/execdriver/native/create.go
@@ -103,7 +103,7 @@
 	if container.Readonlyfs {
 		for i := range container.Mounts {
 			switch container.Mounts[i].Destination {
-			case "/proc", "/dev", "/dev/pts":
+			case "/proc", "/dev", "/dev/pts", "/dev/mqueue":
 				continue
 			}
 			container.Mounts[i].Flags |= syscall.MS_RDONLY
diff --git a/daemon/import.go b/daemon/import.go
index c04e8a3..4961a30 100644
--- a/daemon/import.go
+++ b/daemon/import.go
@@ -11,6 +11,7 @@
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/layer"
+	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/httputils"
 	"github.com/docker/docker/pkg/progress"
 	"github.com/docker/docker/pkg/streamformatter"
@@ -24,13 +25,13 @@
 // the repo and tag arguments, respectively.
 func (daemon *Daemon) ImportImage(src string, newRef reference.Named, msg string, inConfig io.ReadCloser, outStream io.Writer, config *container.Config) error {
 	var (
-		sf      = streamformatter.NewJSONStreamFormatter()
-		archive io.ReadCloser
-		resp    *http.Response
+		sf   = streamformatter.NewJSONStreamFormatter()
+		rc   io.ReadCloser
+		resp *http.Response
 	)
 
 	if src == "-" {
-		archive = inConfig
+		rc = inConfig
 	} else {
 		inConfig.Close()
 		u, err := url.Parse(src)
@@ -48,15 +49,20 @@
 			return err
 		}
 		progressOutput := sf.NewProgressOutput(outStream, true)
-		archive = progress.NewProgressReader(resp.Body, progressOutput, resp.ContentLength, "", "Importing")
+		rc = progress.NewProgressReader(resp.Body, progressOutput, resp.ContentLength, "", "Importing")
 	}
 
-	defer archive.Close()
+	defer rc.Close()
 	if len(msg) == 0 {
 		msg = "Imported from " + src
 	}
+
+	inflatedLayerData, err := archive.DecompressStream(rc)
+	if err != nil {
+		return err
+	}
 	// TODO: support windows baselayer?
-	l, err := daemon.layerStore.Register(archive, "")
+	l, err := daemon.layerStore.Register(inflatedLayerData, "")
 	if err != nil {
 		return err
 	}
diff --git a/docker/daemon_test.go b/docker/daemon_test.go
index 5afdfb3..1be2ab8 100644
--- a/docker/daemon_test.go
+++ b/docker/daemon_test.go
@@ -291,3 +291,80 @@
 		t.Fatalf("expected log tag `test`, got %s", tag)
 	}
 }
+
+func TestLoadDaemonConfigWithTrueDefaultValues(t *testing.T) {
+	c := &daemon.Config{}
+	common := &cli.CommonFlags{}
+	flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
+	flags.BoolVar(&c.EnableUserlandProxy, []string{"-userland-proxy"}, true, "")
+
+	f, err := ioutil.TempFile("", "docker-config-")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if err := flags.ParseFlags([]string{}, false); err != nil {
+		t.Fatal(err)
+	}
+
+	configFile := f.Name()
+	f.Write([]byte(`{
+		"userland-proxy": false
+}`))
+	f.Close()
+
+	loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if loadedConfig == nil {
+		t.Fatal("expected configuration, got nil")
+	}
+
+	if loadedConfig.EnableUserlandProxy {
+		t.Fatal("expected userland proxy to be disabled, got enabled")
+	}
+
+	// make sure reloading doesn't generate configuration
+	// conflicts after normalizing boolean values.
+	err = daemon.ReloadConfiguration(configFile, flags, func(reloadedConfig *daemon.Config) {
+		if reloadedConfig.EnableUserlandProxy {
+			t.Fatal("expected userland proxy to be disabled, got enabled")
+		}
+	})
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestLoadDaemonConfigWithTrueDefaultValuesLeaveDefaults(t *testing.T) {
+	c := &daemon.Config{}
+	common := &cli.CommonFlags{}
+	flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
+	flags.BoolVar(&c.EnableUserlandProxy, []string{"-userland-proxy"}, true, "")
+
+	f, err := ioutil.TempFile("", "docker-config-")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if err := flags.ParseFlags([]string{}, false); err != nil {
+		t.Fatal(err)
+	}
+
+	configFile := f.Name()
+	f.Write([]byte(`{}`))
+	f.Close()
+
+	loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if loadedConfig == nil {
+		t.Fatal("expected configuration, got nil")
+	}
+
+	if !loadedConfig.EnableUserlandProxy {
+		t.Fatal("expected userland proxy to be enabled, got disabled")
+	}
+}
diff --git a/docker/daemon_unix.go b/docker/daemon_unix.go
index eba0bee..ef90970 100644
--- a/docker/daemon_unix.go
+++ b/docker/daemon_unix.go
@@ -8,6 +8,7 @@
 	"os/signal"
 	"syscall"
 
+	"github.com/Sirupsen/logrus"
 	apiserver "github.com/docker/docker/api/server"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/pkg/mflag"
@@ -59,7 +60,9 @@
 	signal.Notify(c, syscall.SIGHUP)
 	go func() {
 		for range c {
-			daemon.ReloadConfiguration(configFile, flags, reload)
+			if err := daemon.ReloadConfiguration(configFile, flags, reload); err != nil {
+				logrus.Error(err)
+			}
 		}
 	}()
 }
diff --git a/docker/daemon_windows.go b/docker/daemon_windows.go
index 307bbcc..52649da 100644
--- a/docker/daemon_windows.go
+++ b/docker/daemon_windows.go
@@ -50,7 +50,9 @@
 			logrus.Debugf("Config reload - waiting signal at %s", ev)
 			for {
 				syscall.WaitForSingleObject(h, syscall.INFINITE)
-				daemon.ReloadConfiguration(configFile, flags, reload)
+				if err := daemon.ReloadConfiguration(configFile, flags, reload); err != nil {
+					logrus.Error(err)
+				}
 			}
 		}
 	}()
diff --git a/integration-cli/docker_cli_cp_to_container_unix_test.go b/integration-cli/docker_cli_cp_to_container_unix_test.go
new file mode 100644
index 0000000..45d85ba
--- /dev/null
+++ b/integration-cli/docker_cli_cp_to_container_unix_test.go
@@ -0,0 +1,39 @@
+// +build !windows
+
+package main
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+
+	"github.com/docker/docker/pkg/integration/checker"
+	"github.com/docker/docker/pkg/system"
+	"github.com/go-check/check"
+)
+
+// Check ownership is root, both in non-userns and userns enabled modes
+func (s *DockerSuite) TestCpCheckDestOwnership(c *check.C) {
+	testRequires(c, DaemonIsLinux, SameHostDaemon)
+	tmpVolDir := getTestDir(c, "test-cp-tmpvol")
+	containerID := makeTestContainer(c,
+		testContainerOptions{volumes: []string{fmt.Sprintf("%s:/tmpvol", tmpVolDir)}})
+
+	tmpDir := getTestDir(c, "test-cp-to-check-ownership")
+	defer os.RemoveAll(tmpDir)
+
+	makeTestContentInDir(c, tmpDir)
+
+	srcPath := cpPath(tmpDir, "file1")
+	dstPath := containerCpPath(containerID, "/tmpvol", "file1")
+
+	err := runDockerCp(c, srcPath, dstPath)
+	c.Assert(err, checker.IsNil)
+
+	stat, err := system.Stat(filepath.Join(tmpVolDir, "file1"))
+	c.Assert(err, checker.IsNil)
+	uid, gid, err := getRootUIDGID()
+	c.Assert(err, checker.IsNil)
+	c.Assert(stat.UID(), checker.Equals, uint32(uid), check.Commentf("Copied file not owned by container root UID"))
+	c.Assert(stat.GID(), checker.Equals, uint32(gid), check.Commentf("Copied file not owned by container root GID"))
+}
diff --git a/integration-cli/docker_cli_import_test.go b/integration-cli/docker_cli_import_test.go
index 4352817..9420daf 100644
--- a/integration-cli/docker_cli_import_test.go
+++ b/integration-cli/docker_cli_import_test.go
@@ -2,6 +2,7 @@
 
 import (
 	"bufio"
+	"compress/gzip"
 	"io/ioutil"
 	"os"
 	"os/exec"
@@ -59,6 +60,31 @@
 	c.Assert(out, checker.Equals, "", check.Commentf("command output should've been nothing."))
 }
 
+func (s *DockerSuite) TestImportGzipped(c *check.C) {
+	testRequires(c, DaemonIsLinux)
+	dockerCmd(c, "run", "--name", "test-import", "busybox", "true")
+
+	temporaryFile, err := ioutil.TempFile("", "exportImportTest")
+	c.Assert(err, checker.IsNil, check.Commentf("failed to create temporary file"))
+	defer os.Remove(temporaryFile.Name())
+
+	runCmd := exec.Command(dockerBinary, "export", "test-import")
+	w := gzip.NewWriter(temporaryFile)
+	runCmd.Stdout = w
+
+	_, err = runCommand(runCmd)
+	c.Assert(err, checker.IsNil, check.Commentf("failed to export a container"))
+	err = w.Close()
+	c.Assert(err, checker.IsNil, check.Commentf("failed to close gzip writer"))
+	temporaryFile.Close()
+	out, _ := dockerCmd(c, "import", temporaryFile.Name())
+	c.Assert(out, checker.Count, "\n", 1, check.Commentf("display is expected 1 '\\n' but didn't"))
+	image := strings.TrimSpace(out)
+
+	out, _ = dockerCmd(c, "run", "--rm", image, "true")
+	c.Assert(out, checker.Equals, "", check.Commentf("command output should've been nothing."))
+}
+
 func (s *DockerSuite) TestImportFileWithMessage(c *check.C) {
 	testRequires(c, DaemonIsLinux)
 	dockerCmd(c, "run", "--name", "test-import", "busybox", "true")
diff --git a/integration-cli/docker_utils.go b/integration-cli/docker_utils.go
index 9b76892..30c8454 100644
--- a/integration-cli/docker_utils.go
+++ b/integration-cli/docker_utils.go
@@ -1720,3 +1720,20 @@
 	args = append(args, defaultSleepCommand...)
 	return dockerCmd(c, args...)
 }
+
+func getRootUIDGID() (int, int, error) {
+	uidgid := strings.Split(filepath.Base(dockerBasePath), ".")
+	if len(uidgid) == 1 {
+		//user namespace remapping is not turned on; return 0
+		return 0, 0, nil
+	}
+	uid, err := strconv.Atoi(uidgid[0])
+	if err != nil {
+		return 0, 0, err
+	}
+	gid, err := strconv.Atoi(uidgid[1])
+	if err != nil {
+		return 0, 0, err
+	}
+	return uid, gid, nil
+}
diff --git a/layer/layer_store.go b/layer/layer_store.go
index 619c1a3..229ba6a 100644
--- a/layer/layer_store.go
+++ b/layer/layer_store.go
@@ -498,18 +498,21 @@
 
 	if err := ls.driver.Remove(m.mountID); err != nil {
 		logrus.Errorf("Error removing mounted layer %s: %s", m.name, err)
+		m.retakeReference(l)
 		return nil, err
 	}
 
 	if m.initID != "" {
 		if err := ls.driver.Remove(m.initID); err != nil {
 			logrus.Errorf("Error removing init layer %s: %s", m.name, err)
+			m.retakeReference(l)
 			return nil, err
 		}
 	}
 
 	if err := ls.store.RemoveMount(m.name); err != nil {
 		logrus.Errorf("Error removing mount metadata: %s: %s", m.name, err)
+		m.retakeReference(l)
 		return nil, err
 	}
 
diff --git a/layer/migration.go b/layer/migration.go
index ac0f006..b45c310 100644
--- a/layer/migration.go
+++ b/layer/migration.go
@@ -127,6 +127,7 @@
 	}
 	defer f.Close()
 	mfz := gzip.NewWriter(f)
+	defer mfz.Close()
 	metaPacker := storage.NewJSONPacker(mfz)
 
 	packerCounter := &packSizeCounter{metaPacker, &size}
diff --git a/layer/mounted_layer.go b/layer/mounted_layer.go
index b3d6568..bf662e9 100644
--- a/layer/mounted_layer.go
+++ b/layer/mounted_layer.go
@@ -96,6 +96,13 @@
 	return nil
 }
 
+func (ml *mountedLayer) retakeReference(r RWLayer) {
+	if ref, ok := r.(*referencedRWLayer); ok {
+		ref.activityCount = 0
+		ml.references[ref] = ref
+	}
+}
+
 type referencedRWLayer struct {
 	*mountedLayer
 
diff --git a/man/docker-exec.1.md b/man/docker-exec.1.md
index 49f6dbc..16a061d 100644
--- a/man/docker-exec.1.md
+++ b/man/docker-exec.1.md
@@ -27,10 +27,10 @@
 
 # OPTIONS
 **-d**, **--detach**=*true*|*false*
-    Override the key sequence for detaching a container. Format is a single character `[a-Z]` or `ctrl-<value>` where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`.
+   Detached mode: run command in the background. The default is *false*.
 
 **--detach-keys**=""
-  Define the key sequence which detaches the container.
+  Override the key sequence for detaching a container. Format is a single character `[a-Z]` or `ctrl-<value>` where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`.
 
 **--help**
   Print usage statement
diff --git a/migrate/v1/migratev1.go b/migrate/v1/migratev1.go
index b7ce75b..aa9d48c 100644
--- a/migrate/v1/migratev1.go
+++ b/migrate/v1/migratev1.go
@@ -160,7 +160,12 @@
 		return err
 	}
 
-	if err := ioutil.WriteFile(filepath.Join(graphDir, id, migrationDiffIDFileName), []byte(diffID), 0600); err != nil {
+	tmpFile := filepath.Join(graphDir, id, migrationDiffIDFileName+".tmp")
+	if err := ioutil.WriteFile(tmpFile, []byte(diffID), 0600); err != nil {
+		return err
+	}
+
+	if err := os.Rename(tmpFile, filepath.Join(graphDir, id, migrationDiffIDFileName)); err != nil {
 		return err
 	}
 
@@ -423,7 +428,11 @@
 		history = parentImg.History
 	}
 
-	diffID, err := ioutil.ReadFile(filepath.Join(root, graphDirName, id, migrationDiffIDFileName))
+	diffIDData, err := ioutil.ReadFile(filepath.Join(root, graphDirName, id, migrationDiffIDFileName))
+	if err != nil {
+		return err
+	}
+	diffID, err := digest.ParseDigest(string(diffIDData))
 	if err != nil {
 		return err
 	}
diff --git a/volume/store/store.go b/volume/store/store.go
index 0d227ae..7387d27 100644
--- a/volume/store/store.go
+++ b/volume/store/store.go
@@ -291,16 +291,14 @@
 
 	s.globalLock.Lock()
 	defer s.globalLock.Unlock()
-	refs, exists := s.refs[v.Name()]
-	if !exists {
-		return
-	}
+	var refs []string
 
-	for i, r := range refs {
-		if r == ref {
-			s.refs[v.Name()] = append(s.refs[v.Name()][:i], s.refs[v.Name()][i+1:]...)
+	for _, r := range s.refs[v.Name()] {
+		if r != ref {
+			refs = append(refs, r)
 		}
 	}
+	s.refs[v.Name()] = refs
 }
 
 // Refs gets the current list of refs for the given volume
diff --git a/volume/store/store_test.go b/volume/store/store_test.go
index 83d4982..7c3f730 100644
--- a/volume/store/store_test.go
+++ b/volume/store/store_test.go
@@ -157,3 +157,22 @@
 		t.Fatalf("expected used volume fake1, got %s", used[0].Name())
 	}
 }
+
+func TestDerefMultipleOfSameRef(t *testing.T) {
+	volumedrivers.Register(vt.NewFakeDriver("fake"), "fake")
+
+	s := New()
+	v, err := s.CreateWithRef("fake1", "fake", "volReference", nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if _, err := s.GetWithRef("fake1", "fake", "volReference"); err != nil {
+		t.Fatal(err)
+	}
+
+	s.Dereference(v, "volReference")
+	if err := s.Remove(v); err != nil {
+		t.Fatal(err)
+	}
+}