github.com/opencontainers/runc@v1.2.0-rc.1.0.20240520010911-492dc558cdd6/tests/integration/mounts_sshfs.bats (about)

     1  #!/usr/bin/env bats
     2  
     3  load helpers
     4  
     5  function setup() {
     6  	setup_busybox
     7  }
     8  
     9  function teardown() {
    10  	if [ -v DIR ]; then
    11  		# Some distros do not have fusermount installed
    12  		# as a dependency of fuse-sshfs, and good ol' umount works.
    13  		fusermount -u "$DIR" || umount "$DIR"
    14  		unset DIR
    15  	fi
    16  
    17  	teardown_bundle
    18  }
    19  
    20  function sshfs_has_flag() {
    21  	if [ -v DIR ]; then
    22  		awk '$2 == "'"$DIR"'" { print $4 }' </proc/self/mounts | grep -E "\b$1\b"
    23  		return "$?"
    24  	fi
    25  }
    26  
    27  function setup_sshfs() {
    28  	# Create a fuse-sshfs mount (or, failing that, a tmpfs mount).
    29  	local sshfs="sshfs
    30  		-o UserKnownHostsFile=/dev/null
    31  		-o StrictHostKeyChecking=no
    32  		-o PasswordAuthentication=no"
    33  
    34  	if ! [ -v DIR ]; then
    35  		DIR="$BATS_RUN_TMPDIR/fuse-sshfs"
    36  		mkdir -p "$DIR"
    37  		# Make sure we clear all superblock flags to make sure bind-mounts can
    38  		# unset these flags.
    39  		if ! $sshfs -o rw,suid,dev,exec,atime rootless@localhost: "$DIR"; then
    40  			# fallback to tmpfs if running in without sshfs
    41  			mount -t tmpfs -o rw,suid,dev,exec,diratime,strictatime tmpfs "$DIR"
    42  		fi
    43  	fi
    44  	# Reset atime flags. "diratime" is quite a strange flag, so we need to make
    45  	# sure it's cleared before we apply the requested flags.
    46  	mount --bind -o remount,diratime,atime,strictatime "$DIR"
    47  	# We need to set the mount flags separately on the mount because some mount
    48  	# flags (such as "ro") are set on the superblock if you do them in the
    49  	# initial mount, which means that they cannot be cleared by bind-mounts.
    50  	#
    51  	# This also lets us reconfigure the per-mount settings on each call.
    52  	mount --bind -o "remount,$1" "$DIR"
    53  	echo "configured $DIR with mount --bind -o remount,$1" >&2
    54  	awk '$2 == "'"$DIR"'"' </proc/self/mounts >&2
    55  }
    56  
    57  function setup_sshfs_bind_flags() {
    58  	host_flags="$1" # ro,nodev,nosuid
    59  	bind_flags="$2" # ro,nosuid,bind
    60  
    61  	setup_sshfs "$host_flags"
    62  
    63  	cat >"rootfs/find-tmp.awk" <<-'EOF'
    64  		#!/bin/awk -f
    65  		$2 == "/mnt" { print $4 }
    66  	EOF
    67  	chmod +x "rootfs/find-tmp.awk"
    68  
    69  	update_config '.process.args = ["sh", "-c", "/find-tmp.awk </proc/self/mounts"]'
    70  	update_config '.mounts = (.mounts | map(select(.destination != "/mnt"))) + [{
    71  			"source": "'"$DIR"'",
    72  			"destination": "/mnt",
    73  			"type": "bind",
    74  			"options": '"$(jq -cRM 'split(",")' <<<"$bind_flags")"'
    75  		}]'
    76  }
    77  
    78  function pass_sshfs_bind_flags() {
    79  	setup_sshfs_bind_flags "$@"
    80  
    81  	runc run test_busybox
    82  	[ "$status" -eq 0 ]
    83  	mnt_flags="$output"
    84  }
    85  
    86  function fail_sshfs_bind_flags() {
    87  	setup_sshfs_bind_flags "$@"
    88  
    89  	runc run test_busybox
    90  	[ "$status" -ne 0 ]
    91  	[[ "$output" == *"runc run failed: unable to start container process: error during container init: error mounting"*"operation not permitted"* ]]
    92  }
    93  
    94  @test "runc run [mount(8)-like behaviour: --bind with no options]" {
    95  	requires root
    96  
    97  	pass_sshfs_bind_flags "ro,noexec,nosymfollow,nodiratime" "bind"
    98  	# If no flags were specified alongside bind, we keep all existing flags.
    99  	# Unspecified flags must be cleared (rw default).
   100  	run -0 grep -wq ro <<<"$mnt_flags"
   101  	run ! grep -wq rw <<<"$mnt_flags"
   102  	run -0 grep -wq noexec <<<"$mnt_flags"
   103  	run -0 grep -wq nodiratime <<<"$mnt_flags"
   104  	# On old systems, mount doesn't know about nosymfollow, which turns the
   105  	# flag into a data argument (which is ignored by MS_REMOUNT).
   106  	if sshfs_has_flag nosymfollow; then run -0 grep -wq nosymfollow <<<"$mnt_flags"; fi
   107  
   108  	# Now try with a user namespace. The results should be the same as above.
   109  	update_config ' .linux.namespaces += [{"type": "user"}]
   110  		| .linux.uidMappings += [{"hostID": 100000, "containerID": 0, "size": 65534}]
   111  		| .linux.gidMappings += [{"hostID": 100000, "containerID": 0, "size": 65534}] '
   112  
   113  	pass_sshfs_bind_flags "ro,noexec,nosymfollow,nodiratime" "bind"
   114  	# If no flags were specified alongside bind, we keep all existing flags.
   115  	# Unspecified flags must be cleared (rw default).
   116  	run -0 grep -wq ro <<<"$mnt_flags"
   117  	run ! grep -wq rw <<<"$mnt_flags"
   118  	run -0 grep -wq noexec <<<"$mnt_flags"
   119  	run -0 grep -wq nodiratime <<<"$mnt_flags"
   120  	# On old systems, mount doesn't know about nosymfollow, which turns the
   121  	# flag into a data argument (which is ignored by MS_REMOUNT).
   122  	if sshfs_has_flag nosymfollow; then run -0 grep -wq nosymfollow <<<"$mnt_flags"; fi
   123  }
   124  
   125  # This behaviour does not match mount(8), but is preferable to the alternative.
   126  # See <https://github.com/util-linux/util-linux/issues/2433>.
   127  @test "runc run [mount(8)-unlike behaviour: --bind with clearing flag]" {
   128  	requires root
   129  
   130  	pass_sshfs_bind_flags "ro,noexec,nosymfollow,nodiratime" "bind,dev"
   131  	# Unspecified flags must be cleared as well.
   132  	run ! grep -wq ro <<<"$mnt_flags"
   133  	run -0 grep -wq rw <<<"$mnt_flags"
   134  	run ! grep -wq noexec <<<"$mnt_flags"
   135  	run ! grep -wq nosymfollow <<<"$mnt_flags"
   136  	# FIXME FIXME: As with mount(8), trying to clear an atime flag the "naive"
   137  	# way will be ignored!
   138  	run -0 grep -wq nodiratime <<<"$mnt_flags"
   139  
   140  	# Now try with a user namespace.
   141  	update_config ' .linux.namespaces += [{"type": "user"}]
   142  		| .linux.uidMappings += [{"hostID": 100000, "containerID": 0, "size": 65534}]
   143  		| .linux.gidMappings += [{"hostID": 100000, "containerID": 0, "size": 65534}] '
   144  
   145  	pass_sshfs_bind_flags "ro,noexec,nosymfollow,nodiratime" "bind,dev"
   146  	# Lockable flags must be kept, because we didn't request them explicitly.
   147  	run -0 grep -wq ro <<<"$mnt_flags"
   148  	run ! grep -wq rw <<<"$mnt_flags"
   149  	run -0 grep -wq noexec <<<"$mnt_flags"
   150  	run -0 grep -wq nodiratime <<<"$mnt_flags"
   151  	# nosymfollow is not lockable, so it must be cleared.
   152  	run ! grep -wq nosymfollow <<<"$mnt_flags"
   153  }
   154  
   155  @test "runc run [implied-rw bind mount of a ro fuse sshfs mount]" {
   156  	requires root
   157  
   158  	pass_sshfs_bind_flags "ro" "bind,nosuid,nodev,rprivate"
   159  	# Unspecified flags must be cleared (rw default).
   160  	run ! grep -wq ro <<<"$mnt_flags"
   161  	run -0 grep -wq rw <<<"$mnt_flags"
   162  	# The new flags must be applied.
   163  	run -0 grep -wq nosuid <<<"$mnt_flags"
   164  	run -0 grep -wq nodev <<<"$mnt_flags"
   165  
   166  	# Now try with a user namespace. The results should be the same as above.
   167  	update_config ' .linux.namespaces += [{"type": "user"}]
   168  		| .linux.uidMappings += [{"hostID": 100000, "containerID": 0, "size": 65534}]
   169  		| .linux.gidMappings += [{"hostID": 100000, "containerID": 0, "size": 65534}] '
   170  
   171  	pass_sshfs_bind_flags "ro" "bind,nosuid,nodev,rprivate"
   172  	# "ro" must still be set (inherited).
   173  	run -0 grep -wq ro <<<"$mnt_flags"
   174  	# The new flags must be applied.
   175  	run -0 grep -wq nosuid <<<"$mnt_flags"
   176  	run -0 grep -wq nodev <<<"$mnt_flags"
   177  }
   178  
   179  @test "runc run [explicit-rw bind mount of a ro fuse sshfs mount]" {
   180  	requires root
   181  
   182  	# Try to overwrite MS_RDONLY. As we are running in a userns-less container,
   183  	# we can overwrite MNT_LOCKED flags.
   184  	pass_sshfs_bind_flags "ro" "bind,rw,nosuid,nodev,rprivate"
   185  	# "ro" must be cleared and replaced with "rw".
   186  	run ! grep -wq ro <<<"$mnt_flags"
   187  	run -0 grep -wq rw <<<"$mnt_flags"
   188  	# The new flags must be applied.
   189  	run -0 grep -wq nosuid <<<"$mnt_flags"
   190  	run -0 grep -wq nodev <<<"$mnt_flags"
   191  
   192  	# Now try with a user namespace.
   193  	update_config ' .linux.namespaces += [{"type": "user"}]
   194  		| .linux.uidMappings += [{"hostID": 100000, "containerID": 0, "size": 65534}]
   195  		| .linux.gidMappings += [{"hostID": 100000, "containerID": 0, "size": 65534}] '
   196  
   197  	# This must fail because we explicitly requested a mount with a MNT_LOCKED
   198  	# mount option cleared (when the source mount has those mounts enabled),
   199  	# namely MS_RDONLY.
   200  	fail_sshfs_bind_flags "ro" "bind,rw,nosuid,nodev,rprivate"
   201  }
   202  
   203  @test "runc run [dev,exec,suid,atime bind mount of a nodev,nosuid,noexec,noatime fuse sshfs mount]" {
   204  	requires root
   205  
   206  	# When running without userns, overwriting host flags should work.
   207  	pass_sshfs_bind_flags "nosuid,nodev,noexec,noatime" "bind,dev,suid,exec,atime"
   208  	# Unspecified flags must be cleared (rw default).
   209  	run ! grep -wq ro <<<"$mnt_flags"
   210  	run -0 grep -wq rw <<<"$mnt_flags"
   211  	# Check that the flags were actually cleared by the mount.
   212  	run ! grep -wq nosuid <<<"$mnt_flags"
   213  	run ! grep -wq nodev <<<"$mnt_flags"
   214  	run ! grep -wq noexec <<<"$mnt_flags"
   215  	# FIXME FIXME: As with mount(8), trying to clear an atime flag the "naive"
   216  	# way will be ignored!
   217  	run -0 grep -wq noatime <<<"$mnt_flags"
   218  
   219  	# Now try with a user namespace.
   220  	update_config ' .linux.namespaces += [{"type": "user"}]
   221  		| .linux.uidMappings += [{"hostID": 100000, "containerID": 0, "size": 65534}]
   222  		| .linux.gidMappings += [{"hostID": 100000, "containerID": 0, "size": 65534}] '
   223  
   224  	# This must fail because we explicitly requested a mount with MNT_LOCKED
   225  	# mount options cleared (when the source mount has those mounts enabled).
   226  	fail_sshfs_bind_flags "nodev,nosuid,nosuid,noatime" "bind,dev,suid,exec,atime"
   227  }
   228  
   229  # Test to ensure we don't regress bind-mounting /etc/resolv.conf with
   230  # containerd <https://github.com/containerd/containerd/pull/8309>.
   231  @test "runc run [ro bind mount of a nodev,nosuid,noexec fuse sshfs mount]" {
   232  	requires root
   233  
   234  	# Setting flags that are not locked should work.
   235  	pass_sshfs_bind_flags "rw,nodev,nosuid,nodev,noexec,noatime" "bind,ro"
   236  	# The flagset should be the union of the two.
   237  	run -0 grep -wq ro <<<"$mnt_flags"
   238  	# Unspecified flags must be cleared.
   239  	run ! grep -wq nosuid <<<"$mnt_flags"
   240  	run ! grep -wq nodev <<<"$mnt_flags"
   241  	run ! grep -wq noexec <<<"$mnt_flags"
   242  
   243  	# Now try with a user namespace.
   244  	update_config ' .linux.namespaces += [{"type": "user"}]
   245  		| .linux.uidMappings += [{"hostID": 100000, "containerID": 0, "size": 65534}]
   246  		| .linux.gidMappings += [{"hostID": 100000, "containerID": 0, "size": 65534}] '
   247  
   248  	# Setting flags that are not locked should work.
   249  	pass_sshfs_bind_flags "rw,nodev,nosuid,nodev,noexec,noatime" "bind,ro"
   250  	# The flagset should be the union of the two.
   251  	run -0 grep -wq ro <<<"$mnt_flags"
   252  	# (Unspecified MNT_LOCKED flags are inherited.)
   253  	run -0 grep -wq nosuid <<<"$mnt_flags"
   254  	run -0 grep -wq nodev <<<"$mnt_flags"
   255  	run -0 grep -wq noexec <<<"$mnt_flags"
   256  }
   257  
   258  @test "runc run [ro,symfollow bind mount of a rw,nodev,nosymfollow fuse sshfs mount]" {
   259  	requires root
   260  
   261  	pass_sshfs_bind_flags "rw,nodev,nosymfollow" "bind,ro,symfollow"
   262  	# Must switch to ro.
   263  	run -0 grep -wq ro <<<"$mnt_flags"
   264  	run ! grep -wq rw <<<"$mnt_flags"
   265  	# Unspecified flags must be cleared.
   266  	run ! grep -wq nodev <<<"$mnt_flags"
   267  	# nosymfollow must also be cleared.
   268  	run ! grep -wq nosymfollow <<<"$mnt_flags"
   269  
   270  	# Now try with a user namespace.
   271  	update_config ' .linux.namespaces += [{"type": "user"}]
   272  		| .linux.uidMappings += [{"hostID": 100000, "containerID": 0, "size": 65534}]
   273  		| .linux.gidMappings += [{"hostID": 100000, "containerID": 0, "size": 65534}] '
   274  
   275  	# Unsetting flags that are not lockable should work.
   276  	pass_sshfs_bind_flags "rw,nodev,nosymfollow" "bind,ro,symfollow"
   277  	# The flagset should be the union of the two.
   278  	run -0 grep -wq ro <<<"$mnt_flags"
   279  	run -0 grep -wq nodev <<<"$mnt_flags"
   280  	# nosymfollow is not lockable, so it must be cleared.
   281  	run ! grep -wq nosymfollow <<<"$mnt_flags"
   282  
   283  	# Implied unsetting of non-lockable flags should also work.
   284  	pass_sshfs_bind_flags "rw,nodev,nosymfollow" "bind,rw"
   285  	# The flagset should be the union of the two.
   286  	run -0 grep -wq rw <<<"$mnt_flags"
   287  	run -0 grep -wq nodev <<<"$mnt_flags"
   288  	# nosymfollow is not lockable, so it must be cleared.
   289  	run ! grep -wq nosymfollow <<<"$mnt_flags"
   290  }
   291  
   292  @test "runc run [ro,noexec bind mount of a nosuid,noatime fuse sshfs mount]" {
   293  	requires root
   294  
   295  	# Setting flags that are not locked should work.
   296  	pass_sshfs_bind_flags "nodev,nosuid,noatime" "bind,ro,exec"
   297  	# The flagset must match the requested set.
   298  	run -0 grep -wq ro <<<"$mnt_flags"
   299  	run ! grep -wq noexec <<<"$mnt_flags"
   300  	# Unspecified flags must be cleared.
   301  	run ! grep -wq nosuid <<<"$mnt_flags"
   302  	run ! grep -wq nodev <<<"$mnt_flags"
   303  	# FIXME: As with mount(8), runc keeps the old atime setting by default.
   304  	run -0 grep -wq noatime <<<"$mnt_flags"
   305  
   306  	# Now try with a user namespace.
   307  	update_config ' .linux.namespaces += [{"type": "user"}]
   308  		| .linux.uidMappings += [{"hostID": 100000, "containerID": 0, "size": 65534}]
   309  		| .linux.gidMappings += [{"hostID": 100000, "containerID": 0, "size": 65534}] '
   310  
   311  	# Setting flags that are not locked should work.
   312  	pass_sshfs_bind_flags "nodev,nosuid,noatime" "bind,ro,exec"
   313  	# The flagset should be the union of the two.
   314  	run -0 grep -wq ro <<<"$mnt_flags"
   315  	run ! grep -wq noexec <<<"$mnt_flags"
   316  	# (Unspecified MNT_LOCKED flags are inherited.)
   317  	run -0 grep -wq nosuid <<<"$mnt_flags"
   318  	run -0 grep -wq nodev <<<"$mnt_flags"
   319  	run -0 grep -wq noatime <<<"$mnt_flags"
   320  }
   321  
   322  @test "runc run [bind mount {no,rel,strict}atime semantics]" {
   323  	requires root
   324  
   325  	function is_strictatime() {
   326  		# There is no "strictatime" in /proc/self/mounts.
   327  		run ! grep -wq noatime <<<"${1:-$mnt_flags}"
   328  		run ! grep -wq relatime <<<"${1:-$mnt_flags}"
   329  		run ! grep -wq nodiratime <<<"${1:-$mnt_flags}"
   330  	}
   331  
   332  	# FIXME: As with mount(8), runc keeps the old atime setting by default.
   333  	pass_sshfs_bind_flags "noatime" "bind"
   334  	run -0 grep -wq noatime <<<"$mnt_flags"
   335  	run ! grep -wq relatime <<<"$mnt_flags"
   336  
   337  	# FIXME: As with mount(8), runc keeps the old atime setting by default.
   338  	pass_sshfs_bind_flags "noatime" "bind,norelatime"
   339  	run -0 grep -wq noatime <<<"$mnt_flags"
   340  	run ! grep -wq relatime <<<"$mnt_flags"
   341  
   342  	# FIXME FIXME: As with mount(8), trying to clear an atime flag the "naive"
   343  	# way will be ignored!
   344  	pass_sshfs_bind_flags "noatime" "bind,atime"
   345  	run -0 grep -wq noatime <<<"$mnt_flags"
   346  	run ! grep -wq relatime <<<"$mnt_flags"
   347  
   348  	# ... but explicitly setting a different flag works.
   349  	pass_sshfs_bind_flags "noatime" "bind,relatime"
   350  	run ! grep -wq noatime <<<"$mnt_flags"
   351  	run -0 grep -wq relatime <<<"$mnt_flags"
   352  
   353  	# Setting a flag that mount(8) would combine should result in only the
   354  	# requested flag being set.
   355  	pass_sshfs_bind_flags "noatime" "bind,nodiratime"
   356  	run ! grep -wq noatime <<<"$mnt_flags"
   357  	run -0 grep -wq nodiratime <<<"$mnt_flags"
   358  	# MS_DIRATIME implies MS_RELATIME by default.
   359  	run -0 grep -wq relatime <<<"$mnt_flags"
   360  
   361  	# Clearing flags that mount(8) would not clear works.
   362  	pass_sshfs_bind_flags "nodiratime" "bind,strictatime"
   363  	is_strictatime "$mnt_flags"
   364  
   365  	# nodiratime is a little weird -- it implies relatime unless you set
   366  	# another option (noatime or strictatime). But, runc also has norelatime --
   367  	# so nodiratime,norelatime should _probably_ result in the same thing as
   368  	# nodiratime,strictatime.
   369  	pass_sshfs_bind_flags "noatime" "bind,nodiratime,strictatime"
   370  	run ! grep -wq noatime <<<"$mnt_flags"
   371  	run -0 grep -wq nodiratime <<<"$mnt_flags"
   372  	run ! grep -wq relatime <<<"$mnt_flags"
   373  	# FIXME FIXME: relatime should not be set in this case.
   374  	pass_sshfs_bind_flags "noatime" "bind,nodiratime,norelatime"
   375  	run ! grep -wq noatime <<<"$mnt_flags"
   376  	run -0 grep -wq nodiratime <<<"$mnt_flags"
   377  	run -0 grep -wq relatime <<<"$mnt_flags"
   378  
   379  	# Now try with a user namespace.
   380  	update_config ' .linux.namespaces += [{"type": "user"}]
   381  		| .linux.uidMappings += [{"hostID": 100000, "containerID": 0, "size": 65534}]
   382  		| .linux.gidMappings += [{"hostID": 100000, "containerID": 0, "size": 65534}] '
   383  
   384  	# Requesting a mount without specifying any preference for atime works, and
   385  	# inherits the original flags.
   386  
   387  	pass_sshfs_bind_flags "strictatime" "bind"
   388  	is_strictatime "$mnt_flags"
   389  
   390  	pass_sshfs_bind_flags "relatime" "bind"
   391  	run -0 grep -wq relatime <<<"$mnt_flags"
   392  
   393  	pass_sshfs_bind_flags "nodiratime" "bind"
   394  	run -0 grep -wq nodiratime <<<"$mnt_flags"
   395  	# MS_DIRATIME implies MS_RELATIME by default.
   396  	# Let's check either relatime is set or no other option that removes
   397  	# relatime semantics is set.
   398  	# The latter case is needed in debian. For more info, see issue: #4093
   399  	run -0 grep -wq relatime <<<"$mnt_flags" ||
   400  		(run ! grep -wqE 'strictatime|norelatime|noatime' <<<"$mnt_flags")
   401  
   402  	pass_sshfs_bind_flags "noatime,nodiratime" "bind"
   403  	run -0 grep -wq noatime <<<"$mnt_flags"
   404  	run -0 grep -wq nodiratime <<<"$mnt_flags"
   405  
   406  	# An unrelated clear flag has no effect.
   407  	pass_sshfs_bind_flags "noatime,nodiratime" "bind,norelatime"
   408  	run -0 grep -wq noatime <<<"$mnt_flags"
   409  	run -0 grep -wq nodiratime <<<"$mnt_flags"
   410  
   411  	# Attempting to change most *atime flags will fail with user namespaces
   412  	# because *atime flags are all MNT_LOCKED.
   413  	fail_sshfs_bind_flags "nodiratime" "bind,strictatime"
   414  	fail_sshfs_bind_flags "relatime" "bind,strictatime"
   415  	fail_sshfs_bind_flags "noatime" "bind,strictatime"
   416  	fail_sshfs_bind_flags "nodiratime" "bind,noatime"
   417  	fail_sshfs_bind_flags "relatime" "bind,noatime"
   418  	fail_sshfs_bind_flags "relatime" "bind,nodiratime"
   419  	# Make sure strictatime sources are correctly handled by runc (the kernel
   420  	# ignores some other mount flags when passing MS_STRICTATIME). See
   421  	# remount() in rootfs_linux.go for details.
   422  	fail_sshfs_bind_flags "strictatime" "bind,relatime"
   423  	fail_sshfs_bind_flags "strictatime" "bind,noatime"
   424  	fail_sshfs_bind_flags "strictatime" "bind,nodiratime"
   425  	# Make sure that runc correctly handles the MS_NOATIME|MS_RELATIME kernel
   426  	# bug. See remount() in rootfs_linux.go for more details.
   427  	fail_sshfs_bind_flags "noatime" "bind,relatime"
   428  
   429  	# Attempting to bind-mount a mount with a request to clear the atime
   430  	# setting that would normally inherited must not work.
   431  	# FIXME FIXME: All of these cases should fail.
   432  	pass_sshfs_bind_flags "strictatime" "bind,nostrictatime"
   433  	is_strictatime "$mnt_flags"
   434  	pass_sshfs_bind_flags "nodiratime" "bind,diratime"
   435  	run -0 grep -wq nodiratime <<<"$mnt_flags"
   436  	pass_sshfs_bind_flags "nodiratime" "bind,norelatime" # MS_DIRATIME implies MS_RELATIME
   437  	run -0 grep -wq nodiratime <<<"$mnt_flags"
   438  	pass_sshfs_bind_flags "relatime" "bind,norelatime"
   439  	run -0 grep -wq relatime <<<"$mnt_flags"
   440  	pass_sshfs_bind_flags "noatime" "bind,atime"
   441  	run -0 grep -wq noatime <<<"$mnt_flags"
   442  	pass_sshfs_bind_flags "noatime,nodiratime" "bind,atime"
   443  	run -0 grep -wq noatime <<<"$mnt_flags"
   444  	run -0 grep -wq nodiratime <<<"$mnt_flags"
   445  }