From 97f4818ce1e09dd56dc2be820930924e870827e9 Mon Sep 17 00:00:00 2001
From: Giuseppe Scrivano <gscrivan@redhat.com>
Date: Thu, 13 Jun 2019 11:29:01 +0200
Subject: [PATCH 1/2] storage: fix typo

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
---
 pkg/spec/storage.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pkg/spec/storage.go b/pkg/spec/storage.go
index e221b5cb53..056f004caf 100644
--- a/pkg/spec/storage.go
+++ b/pkg/spec/storage.go
@@ -384,7 +384,7 @@ func (config *CreateConfig) getMounts() (map[string]spec.Mount, map[string]*libp
 			}
 			finalNamedVolumes[volume.Dest] = volume
 		default:
-			return nil, nil, errors.Errorf("invalid fylesystem type %q", kv[1])
+			return nil, nil, errors.Errorf("invalid filesystem type %q", kv[1])
 		}
 	}
 

From 23efe4cb819b9fb306155ab25db7e2459aba63bb Mon Sep 17 00:00:00 2001
From: Giuseppe Scrivano <gscrivan@redhat.com>
Date: Thu, 13 Jun 2019 11:28:24 +0200
Subject: [PATCH 2/2] storage: support --mount type=bind,bind-nonrecursive

add support for not recursive bind mounts.

Closes: https://github.com/containers/libpod/issues/3314

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
---
 docs/podman-create.1.md |  1 +
 docs/podman-run.1.md    |  1 +
 pkg/spec/storage.go     |  9 ++++++++-
 pkg/util/mountOpts.go   | 15 ++++++++++++---
 test/e2e/run_test.go    |  8 ++++++++
 5 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/docs/podman-create.1.md b/docs/podman-create.1.md
index 88f8fe8c70..a4eebef4c4 100644
--- a/docs/podman-create.1.md
+++ b/docs/podman-create.1.md
@@ -458,6 +458,7 @@ Current supported mount TYPES are bind, and tmpfs.
        Options specific to bind:
 
               · bind-propagation: shared, slave, private, rshared, rslave, or rprivate(default). See also mount(2).
+              . bind-nonrecursive: do not setup a recursive bind mount.  By default it is recursive.
 
        Options specific to tmpfs:
 
diff --git a/docs/podman-run.1.md b/docs/podman-run.1.md
index 5bf7aeee89..8d7deb99fa 100644
--- a/docs/podman-run.1.md
+++ b/docs/podman-run.1.md
@@ -471,6 +471,7 @@ Current supported mount TYPES are bind, and tmpfs.
        Options specific to bind:
 
 	      · bind-propagation: Z, z, shared, slave, private, rshared, rslave, or rprivate(default). See also mount(2).
+	      . bind-nonrecursive: do not setup a recursive bind mount.  By default it is recursive.
 
        Options specific to tmpfs:
 
diff --git a/pkg/spec/storage.go b/pkg/spec/storage.go
index 056f004caf..283585ef84 100644
--- a/pkg/spec/storage.go
+++ b/pkg/spec/storage.go
@@ -403,6 +403,8 @@ func getBindMount(args []string) (spec.Mount, error) {
 	for _, val := range args {
 		kv := strings.Split(val, "=")
 		switch kv[0] {
+		case "bind-nonrecursive":
+			newMount.Options = append(newMount.Options, "bind")
 		case "ro", "nosuid", "nodev", "noexec":
 			// TODO: detect duplication of these options.
 			// (Is this necessary?)
@@ -574,7 +576,7 @@ func ValidateVolumeCtrDir(ctrDir string) error {
 
 // ValidateVolumeOpts validates a volume's options
 func ValidateVolumeOpts(options []string) error {
-	var foundRootPropagation, foundRWRO, foundLabelChange int
+	var foundRootPropagation, foundRWRO, foundLabelChange, bindType int
 	for _, opt := range options {
 		switch opt {
 		case "rw", "ro":
@@ -592,6 +594,11 @@ func ValidateVolumeOpts(options []string) error {
 			if foundRootPropagation > 1 {
 				return errors.Errorf("invalid options %q, can only specify 1 '[r]shared', '[r]private' or '[r]slave' option", strings.Join(options, ", "))
 			}
+		case "bind", "rbind":
+			bindType++
+			if bindType > 1 {
+				return errors.Errorf("invalid options %q, can only specify 1 '[r]bind' option", strings.Join(options, ", "))
+			}
 		default:
 			return errors.Errorf("invalid option type %q", opt)
 		}
diff --git a/pkg/util/mountOpts.go b/pkg/util/mountOpts.go
index 59459807c9..489e7eeef3 100644
--- a/pkg/util/mountOpts.go
+++ b/pkg/util/mountOpts.go
@@ -17,10 +17,19 @@ var (
 // sensible and follow convention.
 func ProcessOptions(options []string) []string {
 	var (
-		foundrw, foundro bool
-		rootProp         string
+		foundbind, foundrw, foundro bool
+		rootProp                    string
 	)
-	options = append(options, "rbind")
+	for _, opt := range options {
+		switch opt {
+		case "bind", "rbind":
+			foundbind = true
+			break
+		}
+	}
+	if !foundbind {
+		options = append(options, "rbind")
+	}
 	for _, opt := range options {
 		switch opt {
 		case "rw":
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 31720ea04b..3ba3c2bb3f 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -659,6 +659,14 @@ USER mail`
 		Expect(isSharedOnly).Should(BeTrue())
 	})
 
+	It("podman run --mount type=bind,bind-nonrecursive", func() {
+		SkipIfRootless()
+		session := podmanTest.Podman([]string{"run", "--mount", "type=bind,bind-nonrecursive,slave,src=/,target=/host", fedoraMinimal, "findmnt", "-nR", "/host"})
+		session.WaitWithDefaultTimeout()
+		Expect(session.ExitCode()).To(Equal(0))
+		Expect(len(session.OutputToStringArray())).To(Equal(1))
+	})
+
 	It("podman run --pod automatically", func() {
 		session := podmanTest.Podman([]string{"run", "--pod", "new:foobar", ALPINE, "ls"})
 		session.WaitWithDefaultTimeout()