Skip to content

Commit

Permalink
Support recursive read-only (RRO) mounts: `nerdctl run -v /foo:/bar:r…
Browse files Browse the repository at this point in the history
…ro,rprivate`

`nerdctl run -v /foo:/bar:rro,rprivate` appends "rro" (in addition to "ro") to the OCI mount option string slice.

Requires crun >= 1.4 or runc >= 1.1 (opencontainers/runc PR 3272).
Older version of runc just ignores "rro" option.

The "rro" option string conforms to the proposal in util-linux/util-linux Issue 1501.

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
  • Loading branch information
AkihiroSuda committed Nov 17, 2021
1 parent 24168f0 commit c103287
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 7 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ Major:
- [On-demand image pulling (lazy-pulling) using Stargz Snapshotter](./docs/stargz.md): `nerdctl --snapshotter=stargz run IMAGE` .
- [Image encryption and decryption using ocicrypt (imgcrypt)](./docs/ocicrypt.md): `nerdctl image (encrypt|decrypt) SRC DST`
- [P2P image distribution using IPFS](./docs/ipfs.md): `nerdctl run ipfs://CID`
- Recursive read-only (RRO) bind-mount: `nerdctl run -v /mnt:/mnt:rro` (make children such as `/mnt/usb` to be read-only, too).
Requires kernel >= 5.12, and crun >= 1.4 or runc >= 1.1 (PR [#3272](https://github.com/opencontainers/runc/pull/3272)).

Minor:
- Namespacing: `nerdctl --namespace=<NS> ps` .
Expand Down Expand Up @@ -339,7 +341,13 @@ Runtime flags:
- :whale: `--sysctl`: Sysctl options, e.g \"net.ipv4.ip_forward=1\"

Volume flags:
- :whale: :blue_square: `-v, --volume`: Bind mount a volume
- :whale: :blue_square: `-v, --volume <SRC>:<DST>[:<OPT>]`: Bind mount a volume, e.g., `-v /mnt:/mnt:rro,rprivate`
- :whale: option `rw` : Read/Write (when writable)
- :whale: option `ro` : Non-recursive read-only
- :nerd_face: option `rro`: Recursive read-only. Should be used in conjunction with `rprivate`. e.g., `-v /mnt:/mnt:rro,rprivate` makes children such as `/mnt/usb` to be read-only, too.
Requires kernel >= 5.12, and crun >= 1.4 or runc >= 1.1 (PR [#3272](https://github.com/opencontainers/runc/pull/3272)). With older runc, `rro` just works as `ro`.
- :whale: option `shared`, `slave`, `private`: Non-recursive "shared" / "slave" / "private" propagation
- :whale: option `rshared`, `rslave`, `rprivate`: Recursive "shared" / "slave" / "private" propagation
- :whale: `--tmpfs`: Mount a tmpfs directory

Rootfs flags:
Expand Down
25 changes: 19 additions & 6 deletions pkg/mountutil/mountutil_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,7 @@ func parseVolumeOptionsWithMountInfo(vType, src, optsRaw string, getMountInfoFun
)
for _, opt := range strings.Split(optsRaw, ",") {
switch opt {
case "rw":
writeModeRawOpts = append(writeModeRawOpts, opt)
case "ro":
case "rw", "ro", "rro":
writeModeRawOpts = append(writeModeRawOpts, opt)
case "private", "rprivate", "shared", "rshared", "slave", "rslave":
propagationRawOpts = append(propagationRawOpts, opt)
Expand All @@ -112,9 +110,24 @@ func parseVolumeOptionsWithMountInfo(vType, src, optsRaw string, getMountInfoFun

if len(writeModeRawOpts) > 1 {
return nil, nil, fmt.Errorf("duplicated read/write volume option: %+v", writeModeRawOpts)
} else if len(writeModeRawOpts) > 0 && writeModeRawOpts[0] == "ro" {
opts = append(opts, "ro")
} // No need to return option when "rw"
} else if len(writeModeRawOpts) > 0 {
switch writeModeRawOpts[0] {
case "ro":
opts = append(opts, "ro")
case "rro":
// Mount option "rro" is supported since crun v1.4 / runc v1.1 (https://github.com/opencontainers/runc/pull/3272), with kernel >= 5.12.
// Older version of runc just ignores "rro", so we have to add "ro" too, to our best effort.
opts = append(opts, "ro", "rro")
if len(propagationRawOpts) != 1 || propagationRawOpts[0] != "rprivate" {
logrus.Warn("Mount option \"rro\" should be used in conjunction with \"rprivate\"")
}
case "rw":
// NOP
default:
// NOTREACHED
return nil, nil, fmt.Errorf("unexpected writeModeRawOpts[0]=%q", writeModeRawOpts[0])
}
}

if len(propagationRawOpts) > 1 {
return nil, nil, fmt.Errorf("duplicated volume propagation option: %+v", propagationRawOpts)
Expand Down

0 comments on commit c103287

Please sign in to comment.