From b2cbaa03af8b0939596c9ff1595b93c7ba7da307 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Fri, 23 Oct 2015 16:57:57 -0400 Subject: [PATCH] Add capability to specify mount propagation per volume Allow passing mount propagation option shared, slave, or private as volume property. For example. docker run -ti -v /root/mnt-source:/root/mnt-dest:slave fedora bash Signed-off-by: Vivek Goyal --- docs/reference/commandline/create.md | 12 ++--- docs/reference/commandline/run.md | 12 ++--- docs/reference/run.md | 13 +++-- man/docker-create.1.md | 76 +++++++++++++++++++++++++-- man/docker-inspect.1.md | 1 + man/docker-run.1.md | 78 +++++++++++++++++++--------- 6 files changed, 147 insertions(+), 45 deletions(-) diff --git a/docs/reference/commandline/create.md b/docs/reference/commandline/create.md index 06e047f4aa..fae59a59cf 100644 --- a/docs/reference/commandline/create.md +++ b/docs/reference/commandline/create.md @@ -79,12 +79,12 @@ Creates a new container. -u, --user="" Username or UID --ulimit=[] Ulimit options --uts="" UTS namespace to use - -v, --volume=[] Bind mount a volume with: [host-src:]container-dest[:], where - options are comma delimited and selected from [rw|ro] and [z|Z]. - The 'host-src' can either be an absolute path or a name value. - If 'host-src' is missing, then docker creates a new volume. - If neither 'rw' or 'ro' is specified then the volume is mounted - in read-write mode. + -v, --volume=[host-src:]container-dest[:] + Bind mount a volume. The comma-delimited + `options` are [rw|ro], [z|Z], or + [[r]shared|[r]slave|[r]private]. The + 'host-src' is an absolute path or a name + value. --volume-driver="" Container's volume driver --volumes-from=[] Mount volumes from the specified container(s) -w, --workdir="" Working directory inside the container diff --git a/docs/reference/commandline/run.md b/docs/reference/commandline/run.md index 5794b65ba0..57822fbfe6 100644 --- a/docs/reference/commandline/run.md +++ b/docs/reference/commandline/run.md @@ -80,12 +80,12 @@ parent = "smn_cli" -u, --user="" Username or UID (format: [:]) --ulimit=[] Ulimit options --uts="" UTS namespace to use - -v, --volume=[] Bind mount a volume with: [host-src:]container-dest[:], where - options are comma delimited and selected from [rw|ro] and [z|Z]. - The 'host-src' can either be an absolute path or a name value. - If 'host-src' is missing, then docker creates a new volume. - If neither 'rw' or 'ro' is specified then the volume is mounted - in read-write mode. + -v, --volume=[host-src:]container-dest[:] + Bind mount a volume. The comma-delimited + `options` are [rw|ro], [z|Z], or + [[r]shared|[r]slave|[r]private]. The + 'host-src' is an absolute path or a name + value. --volume-driver="" Container's volume driver --volumes-from=[] Mount volumes from the specified container(s) -w, --workdir="" Working directory inside the container diff --git a/docs/reference/run.md b/docs/reference/run.md index 160ad986c7..8e83d2b328 100644 --- a/docs/reference/run.md +++ b/docs/reference/run.md @@ -1330,11 +1330,14 @@ Similarly the operator can set the **hostname** with `-h`. ### VOLUME (shared filesystems) - -v=[]: Create a bind mount with: [host-src:]container-dest[:], where - options are comma delimited and selected from [rw|ro] and [z|Z]. - If 'host-src' is missing, then docker creates a new volume. - If neither 'rw' or 'ro' is specified then the volume is mounted - in read-write mode. + -v, --volume=[host-src:]container-dest[:]: Bind mount a volume. + The comma-delimited `options` are [rw|ro], [z|Z], or + [[r]shared|[r]slave|[r]private]. The 'host-src' is an absolute path or a + name value. + + If neither 'rw' or 'ro' is specified then the volume is mounted in + read-write mode. + --volumes-from="": Mount all volumes from the given container(s) > **Note**: diff --git a/man/docker-create.1.md b/man/docker-create.1.md index 8212c6bd82..bca40cbacc 100644 --- a/man/docker-create.1.md +++ b/man/docker-create.1.md @@ -64,7 +64,7 @@ docker-create - Create a new container [**-u**|**--user**[=*USER*]] [**--ulimit**[=*[]*]] [**--uts**[=*[]*]] -[**-v**|**--volume**[=*[]*]] +[**-v**|**--volume**[=*[[HOST-DIR:]CONTAINER-DIR[:OPTIONS]]*]] [**--volume-driver**[=*DRIVER*]] [**--volumes-from**[=*[]*]] [**-w**|**--workdir**[=*WORKDIR*]] @@ -311,8 +311,78 @@ any options, the systems uses the following options: **host**: use the host's UTS namespace inside the container. Note: the host mode gives the container access to changing the host's hostname and is therefore considered insecure. -**-v**, **--volume**=[] - Bind mount a volume (e.g., from the host: -v /host:/container, from Docker: -v /container) +**-v**|**--volume**[=*[[HOST-DIR:]CONTAINER-DIR[:OPTIONS]]*] + Create a bind mount. If you specify, ` -v /HOST-DIR:/CONTAINER-DIR`, Docker + bind mounts `/HOST-DIR` in the host to `/CONTAINER-DIR` in the Docker + container. If 'HOST-DIR' is omitted, Docker automatically creates the new + volume on the host. The `OPTIONS` are a comma delimited list and can be: + + * [rw|ro] + * [z|Z] + * [`[r]shared`|`[r]slave`|`[r]private`] + +The `CONTAINER-DIR` must be an absolute path such as `/src/docs`. The `HOST-DIR` +can be an absolute path or a `name` value. A `name` value must start with an +alphanumeric character, followed by `a-z0-9`, `_` (underscore), `.` (period) or +`-` (hyphen). An absolute path starts with a `/` (forward slash). + +If you supply a `HOST-DIR` that is an absolute path, Docker bind-mounts to the +path you specify. If you supply a `name`, Docker creates a named volume by that +`name`. For example, you can specify either `/foo` or `foo` for a `HOST-DIR` +value. If you supply the `/foo` value, Docker creates a bind-mount. If you +supply the `foo` specification, Docker creates a named volume. + +You can specify multiple **-v** options to mount one or more mounts to a +container. To use these same mounts in other containers, specify the +**--volumes-from** option also. + +You can add `:ro` or `:rw` suffix to a volume to mount it read-only or +read-write mode, respectively. By default, the volumes are mounted read-write. +See examples. + +Labeling systems like SELinux require that proper labels are placed on volume +content mounted into a container. Without a label, the security system might +prevent the processes running inside the container from using the content. By +default, Docker does not change the labels set by the OS. + +To change a label in the container context, you can add either of two suffixes +`:z` or `:Z` to the volume mount. These suffixes tell Docker to relabel file +objects on the shared volumes. The `z` option tells Docker that two containers +share the volume content. As a result, Docker labels the content with a shared +content label. Shared volume labels allow all containers to read/write content. +The `Z` option tells Docker to label the content with a private unshared label. +Only the current container can use a private volume. + +By default bind mounted volumes are `private`. That means any mounts done +inside container will not be visible on host and vice-a-versa. One can change +this behavior by specifying a volume mount propagation property. Making a +volume `shared` mounts done under that volume inside container will be +visible on host and vice-a-versa. Making a volume `slave` enables only one +way mount propagation and that is mounts done on host under that volume +will be visible inside container but not the other way around. + +To control mount propagation property of volume one can use `:[r]shared`, +`:[r]slave` or `:[r]private` propagation flag. Propagation property can +be specified only for bind mounted volumes and not for internal volumes or +named volumes. For mount propagation to work source mount point (mount point +where source dir is mounted on) has to have right propagation properties. For +shared volumes, source mount point has to be shared. And for slave volumes, +source mount has to be either shared or slave. + +Use `df ` to figure out the source mount and then use +`findmnt -o TARGET,PROPAGATION ` to figure out propagation +properties of source mount. If `findmnt` utility is not available, then one +can look at mount entry for source mount point in `/proc/self/mountinfo`. Look +at `optional fields` and see if any propagaion properties are specified. +`shared:X` means mount is `shared`, `master:X` means mount is `slave` and if +nothing is there that means mount is `private`. + +To change propagation properties of a mount point use `mount` command. For +example, if one wants to bind mount source directory `/foo` one can do +`mount --bind /foo /foo` and `mount --make-private --make-shared /foo`. This +will convert /foo into a `shared` mount point. Alternatively one can directly +change propagation properties of source mount. Say `/` is source mount for +`/foo`, then use `mount --make-shared /` to convert `/` into a `shared` mount. **--volume-driver**="" Container's volume driver. This driver creates volumes specified either from diff --git a/man/docker-inspect.1.md b/man/docker-inspect.1.md index 0975152452..c2e32cfd67 100644 --- a/man/docker-inspect.1.md +++ b/man/docker-inspect.1.md @@ -104,6 +104,7 @@ To get information on a container use its ID or instance name: "Destination": "/data", "Mode": "ro,Z", "RW": false + "Propagation": "" } ], "AppArmorProfile": "", diff --git a/man/docker-run.1.md b/man/docker-run.1.md index 83c901006c..603db39b7f 100644 --- a/man/docker-run.1.md +++ b/man/docker-run.1.md @@ -67,7 +67,7 @@ docker-run - Run a command in a new container [**-u**|**--user**[=*USER*]] [**--ulimit**[=*[]*]] [**--uts**[=*[]*]] -[**-v**|**--volume**[=*[]*]] +[**-v**|**--volume**[=*[[HOST-DIR:]CONTAINER-DIR[:OPTIONS]]*]] [**--volume-driver**[=*DRIVER*]] [**--volumes-from**[=*[]*]] [**-w**|**--workdir**[=*WORKDIR*]] @@ -476,24 +476,34 @@ any options, the systems uses the following options: **--ulimit**=[] Ulimit options -**-v**, **--volume**=[] Create a bind mount - (format: `[host-dir:]container-dir[:]`, where suffix options -are comma delimited and selected from [rw|ro] and [z|Z].) +**-v**|**--volume**[=*[[HOST-DIR:]CONTAINER-DIR[:OPTIONS]]*] + Create a bind mount. If you specify, ` -v /HOST-DIR:/CONTAINER-DIR`, Docker + bind mounts `/HOST-DIR` in the host to `/CONTAINER-DIR` in the Docker + container. If 'HOST-DIR' is omitted, Docker automatically creates the new + volume on the host. The `OPTIONS` are a comma delimited list and can be: - (e.g., using -v /host-dir:/container-dir, bind mounts /host-dir in the -host to /container-dir in the Docker container) + * [rw|ro] + * [z|Z] + * [`[r]shared`|`[r]slave`|`[r]private`] - If 'host-dir' is missing, then docker automatically creates the new volume -on the host. **This auto-creation of the host path has been deprecated in -Release: v1.9.** +The `CONTAINER-DIR` must be an absolute path such as `/src/docs`. The `HOST-DIR` +can be an absolute path or a `name` value. A `name` value must start with an +alphanumeric character, followed by `a-z0-9`, `_` (underscore), `.` (period) or +`-` (hyphen). An absolute path starts with a `/` (forward slash). - The **-v** option can be used one or -more times to add one or more mounts to a container. These mounts can then be -used in other containers using the **--volumes-from** option. +If you supply a `HOST-DIR` that is an absolute path, Docker bind-mounts to the +path you specify. If you supply a `name`, Docker creates a named volume by that +`name`. For example, you can specify either `/foo` or `foo` for a `HOST-DIR` +value. If you supply the `/foo` value, Docker creates a bind-mount. If you +supply the `foo` specification, Docker creates a named volume. - The volume may be optionally suffixed with :ro or :rw to mount the volumes in -read-only or read-write mode, respectively. By default, the volumes are mounted -read-write. See examples. +You can specify multiple **-v** options to mount one or more mounts to a +container. To use these same mounts in other containers, specify the +**--volumes-from** option also. + +You can add `:ro` or `:rw` suffix to a volume to mount it read-only or +read-write mode, respectively. By default, the volumes are mounted read-write. +See examples. Labeling systems like SELinux require that proper labels are placed on volume content mounted into a container. Without a label, the security system might @@ -508,18 +518,36 @@ content label. Shared volume labels allow all containers to read/write content. The `Z` option tells Docker to label the content with a private unshared label. Only the current container can use a private volume. -The `container-dir` must always be an absolute path such as `/src/docs`. -The `host-dir` can either be an absolute path or a `name` value. If you -supply an absolute path for the `host-dir`, Docker bind-mounts to the path -you specify. If you supply a `name`, Docker creates a named volume by that `name`. +By default bind mounted volumes are `private`. That means any mounts done +inside container will not be visible on host and vice-a-versa. One can change +this behavior by specifying a volume mount propagation property. Making a +volume `shared` mounts done under that volume inside container will be +visible on host and vice-a-versa. Making a volume `slave` enables only one +way mount propagation and that is mounts done on host under that volume +will be visible inside container but not the other way around. -A `name` value must start with start with an alphanumeric character, -followed by `a-z0-9`, `_` (underscore), `.` (period) or `-` (hyphen). -An absolute path starts with a `/` (forward slash). +To control mount propagation property of volume one can use `:[r]shared`, +`:[r]slave` or `:[r]private` propagation flag. Propagation property can +be specified only for bind mounted volumes and not for internal volumes or +named volumes. For mount propagation to work source mount point (mount point +where source dir is mounted on) has to have right propagation properties. For +shared volumes, source mount point has to be shared. And for slave volumes, +source mount has to be either shared or slave. -For example, you can specify either `/foo` or `foo` for a `host-dir` value. -If you supply the `/foo` value, Docker creates a bind-mount. If you supply -the `foo` specification, Docker creates a named volume. +Use `df ` to figure out the source mount and then use +`findmnt -o TARGET,PROPAGATION ` to figure out propagation +properties of source mount. If `findmnt` utility is not available, then one +can look at mount entry for source mount point in `/proc/self/mountinfo`. Look +at `optional fields` and see if any propagaion properties are specified. +`shared:X` means mount is `shared`, `master:X` means mount is `slave` and if +nothing is there that means mount is `private`. + +To change propagation properties of a mount point use `mount` command. For +example, if one wants to bind mount source directory `/foo` one can do +`mount --bind /foo /foo` and `mount --make-private --make-shared /foo`. This +will convert /foo into a `shared` mount point. Alternatively one can directly +change propagation properties of source mount. Say `/` is source mount for +`/foo`, then use `mount --make-shared /` to convert `/` into a `shared` mount. **--volume-driver**="" Container's volume driver. This driver creates volumes specified either from