Filesystem mounted on top of â/â is inaccessible - so why can it be unmounted with âumount /â?
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
1
down vote
favorite
$ unshare -rm
# mount --bind /tmp /
# awk ' if ($2 == "/") print $0; ' < /proc/mounts
/dev/mapper/alan_dell_2016-fedora / ext4 rw,seclabel,relatime 0 0
tmpfs / tmpfs rw,seclabel,nosuid,nodev 0 0
This new mount does not change the physical directory which /
refers to. See also /proc/self/root
. Changing the per-process root directory is what what chroot
does. When I access /
, it still shows the contents of my ext4 root filesystem, not the tmpfs:
# stat -f /tmp --format %T
tmpfs
# stat -f / --format %T
ext2/ext3
# ls -l -d -i /tmp
22161 drwxrwxrwt. 44 nfsnobody nfsnobody 1000 Jul 19 09:49 /tmp
# ls -l -d -i /
2 dr-xr-xr-x. 19 nfsnobody nfsnobody 4096 Jul 7 09:21 /
Except that umount
operates on the tmpfs mount. How does this work - what is the difference between these two types of operation?
# umount /
# awk ' if ($2 == "/") print $0; ' < /proc/mounts
/dev/mapper/alan_dell_2016-fedora / ext4 rw,seclabel,relatime 0 0
Environment
$ uname -r # Kernel version
4.17.3-200.fc28.x86_64
System call trace
I tried repeating this with umount /
run under strace -f
, but it doesn't show anything more illuminating. umount
just calls umount2()
, and it doesn't pass any flags (the second parameter is zero).
# strace -f umount /
...
statfs("/", f_type=EXT2_SUPER_MAGIC, f_bsize=4096, f_blocks=10288440, f_bfree=2384614, f_bavail=1856230, f_files=2621440, f_ffree=2253065, f_fsid=val=[1557883181, 1665775425], f_namelen=255, f_frsize=4096, f_flags=ST_VALID) = 0
stat("/sbin/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
stat("/sbin/fs.d/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
stat("/sbin/fs/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
umount2("/", 0) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
linux mount
add a comment |Â
up vote
1
down vote
favorite
$ unshare -rm
# mount --bind /tmp /
# awk ' if ($2 == "/") print $0; ' < /proc/mounts
/dev/mapper/alan_dell_2016-fedora / ext4 rw,seclabel,relatime 0 0
tmpfs / tmpfs rw,seclabel,nosuid,nodev 0 0
This new mount does not change the physical directory which /
refers to. See also /proc/self/root
. Changing the per-process root directory is what what chroot
does. When I access /
, it still shows the contents of my ext4 root filesystem, not the tmpfs:
# stat -f /tmp --format %T
tmpfs
# stat -f / --format %T
ext2/ext3
# ls -l -d -i /tmp
22161 drwxrwxrwt. 44 nfsnobody nfsnobody 1000 Jul 19 09:49 /tmp
# ls -l -d -i /
2 dr-xr-xr-x. 19 nfsnobody nfsnobody 4096 Jul 7 09:21 /
Except that umount
operates on the tmpfs mount. How does this work - what is the difference between these two types of operation?
# umount /
# awk ' if ($2 == "/") print $0; ' < /proc/mounts
/dev/mapper/alan_dell_2016-fedora / ext4 rw,seclabel,relatime 0 0
Environment
$ uname -r # Kernel version
4.17.3-200.fc28.x86_64
System call trace
I tried repeating this with umount /
run under strace -f
, but it doesn't show anything more illuminating. umount
just calls umount2()
, and it doesn't pass any flags (the second parameter is zero).
# strace -f umount /
...
statfs("/", f_type=EXT2_SUPER_MAGIC, f_bsize=4096, f_blocks=10288440, f_bfree=2384614, f_bavail=1856230, f_files=2621440, f_ffree=2253065, f_fsid=val=[1557883181, 1665775425], f_namelen=255, f_frsize=4096, f_flags=ST_VALID) = 0
stat("/sbin/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
stat("/sbin/fs.d/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
stat("/sbin/fs/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
umount2("/", 0) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
linux mount
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
$ unshare -rm
# mount --bind /tmp /
# awk ' if ($2 == "/") print $0; ' < /proc/mounts
/dev/mapper/alan_dell_2016-fedora / ext4 rw,seclabel,relatime 0 0
tmpfs / tmpfs rw,seclabel,nosuid,nodev 0 0
This new mount does not change the physical directory which /
refers to. See also /proc/self/root
. Changing the per-process root directory is what what chroot
does. When I access /
, it still shows the contents of my ext4 root filesystem, not the tmpfs:
# stat -f /tmp --format %T
tmpfs
# stat -f / --format %T
ext2/ext3
# ls -l -d -i /tmp
22161 drwxrwxrwt. 44 nfsnobody nfsnobody 1000 Jul 19 09:49 /tmp
# ls -l -d -i /
2 dr-xr-xr-x. 19 nfsnobody nfsnobody 4096 Jul 7 09:21 /
Except that umount
operates on the tmpfs mount. How does this work - what is the difference between these two types of operation?
# umount /
# awk ' if ($2 == "/") print $0; ' < /proc/mounts
/dev/mapper/alan_dell_2016-fedora / ext4 rw,seclabel,relatime 0 0
Environment
$ uname -r # Kernel version
4.17.3-200.fc28.x86_64
System call trace
I tried repeating this with umount /
run under strace -f
, but it doesn't show anything more illuminating. umount
just calls umount2()
, and it doesn't pass any flags (the second parameter is zero).
# strace -f umount /
...
statfs("/", f_type=EXT2_SUPER_MAGIC, f_bsize=4096, f_blocks=10288440, f_bfree=2384614, f_bavail=1856230, f_files=2621440, f_ffree=2253065, f_fsid=val=[1557883181, 1665775425], f_namelen=255, f_frsize=4096, f_flags=ST_VALID) = 0
stat("/sbin/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
stat("/sbin/fs.d/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
stat("/sbin/fs/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
umount2("/", 0) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
linux mount
$ unshare -rm
# mount --bind /tmp /
# awk ' if ($2 == "/") print $0; ' < /proc/mounts
/dev/mapper/alan_dell_2016-fedora / ext4 rw,seclabel,relatime 0 0
tmpfs / tmpfs rw,seclabel,nosuid,nodev 0 0
This new mount does not change the physical directory which /
refers to. See also /proc/self/root
. Changing the per-process root directory is what what chroot
does. When I access /
, it still shows the contents of my ext4 root filesystem, not the tmpfs:
# stat -f /tmp --format %T
tmpfs
# stat -f / --format %T
ext2/ext3
# ls -l -d -i /tmp
22161 drwxrwxrwt. 44 nfsnobody nfsnobody 1000 Jul 19 09:49 /tmp
# ls -l -d -i /
2 dr-xr-xr-x. 19 nfsnobody nfsnobody 4096 Jul 7 09:21 /
Except that umount
operates on the tmpfs mount. How does this work - what is the difference between these two types of operation?
# umount /
# awk ' if ($2 == "/") print $0; ' < /proc/mounts
/dev/mapper/alan_dell_2016-fedora / ext4 rw,seclabel,relatime 0 0
Environment
$ uname -r # Kernel version
4.17.3-200.fc28.x86_64
System call trace
I tried repeating this with umount /
run under strace -f
, but it doesn't show anything more illuminating. umount
just calls umount2()
, and it doesn't pass any flags (the second parameter is zero).
# strace -f umount /
...
statfs("/", f_type=EXT2_SUPER_MAGIC, f_bsize=4096, f_blocks=10288440, f_bfree=2384614, f_bavail=1856230, f_files=2621440, f_ffree=2253065, f_fsid=val=[1557883181, 1665775425], f_namelen=255, f_frsize=4096, f_flags=ST_VALID) = 0
stat("/sbin/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
stat("/sbin/fs.d/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
stat("/sbin/fs/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
umount2("/", 0) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
linux mount
edited Jul 19 at 12:10
asked Jul 19 at 10:15
sourcejedi
18k22375
18k22375
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
Looking inside Linux v4.17, I think we can say umount
on /
is equivalent to umount
on /..
. And /..
accesses the "top of [the] mountpoint pile".
# stat -f / --format %T
ext2/ext3
# stat -f /.. --format %T
tmpfs
This obscure behaviour of ..
seems to be permitted by POSIX. It only says "As a special case, in the root directory, dot-dot may refer to the root directory itself." (POSIX.1-2017, section 4.13 "Pathname Resolution").
If you want to generalize this and define the behaviour implemented by umount
on other mount points, making a comparison with ..
does not work so well. The term "top of [the] mountpoint pile" still applies, although it doesn't sound like a very formal definition :).
Kernel source code
https://elixir.bootlin.com/linux/v4.17/source/fs/namei.c
See where path_mountpoint()
calls follow_mount()
.
/**
* path_mountpoint - look up a path to be umounted
* @nd: lookup context
* @flags: lookup flags
* @path: pointer to container for result
*
* Look up the given name, but don't attempt to revalidate the last component.
* Returns 0 and "path" will be valid on success; Returns error otherwise.
*/
static int
path_mountpoint(struct nameidata *nd, unsigned flags, struct path *path)
const char *s = path_init(nd, flags);
int err;
if (IS_ERR(s))
return PTR_ERR(s);
while (!(err = link_path_walk(s, nd)) &&
(err = mountpoint_last(nd)) > 0)
s = trailing_symlink(nd);
if (IS_ERR(s))
err = PTR_ERR(s);
break;
if (!err)
*path = nd->path;
nd->path.mnt = NULL;
nd->path.dentry = NULL;
follow_mount(path);
terminate_walk(nd);
return err;
The comment for follow_mount()
sounded like it was relevant to the question. And it mentions follow_dotdot()
as the main user, which suggested this line of investigation.
/*
* Skip to top of mountpoint pile in refwalk mode for follow_dotdot()
*/
static void follow_mount(struct path *path)
while (d_mountpoint(path->dentry))
struct vfsmount *mounted = lookup_mnt(path);
if (!mounted)
break;
dput(path->dentry);
mntput(path->mnt);
path->mnt = mounted;
path->dentry = dget(mounted->mnt_root);
static int follow_dotdot(struct nameidata *nd)
I had been thinking about how ..
("dotdot") could traverse from a mount point to its parent, e.g. /tmp/..
. But I hadn't previously considered that doing so might "skip to [the] top of [the] mountpoint pile". This happens even if the top mount isn't the one that contains the original /tmp
directory!
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
Looking inside Linux v4.17, I think we can say umount
on /
is equivalent to umount
on /..
. And /..
accesses the "top of [the] mountpoint pile".
# stat -f / --format %T
ext2/ext3
# stat -f /.. --format %T
tmpfs
This obscure behaviour of ..
seems to be permitted by POSIX. It only says "As a special case, in the root directory, dot-dot may refer to the root directory itself." (POSIX.1-2017, section 4.13 "Pathname Resolution").
If you want to generalize this and define the behaviour implemented by umount
on other mount points, making a comparison with ..
does not work so well. The term "top of [the] mountpoint pile" still applies, although it doesn't sound like a very formal definition :).
Kernel source code
https://elixir.bootlin.com/linux/v4.17/source/fs/namei.c
See where path_mountpoint()
calls follow_mount()
.
/**
* path_mountpoint - look up a path to be umounted
* @nd: lookup context
* @flags: lookup flags
* @path: pointer to container for result
*
* Look up the given name, but don't attempt to revalidate the last component.
* Returns 0 and "path" will be valid on success; Returns error otherwise.
*/
static int
path_mountpoint(struct nameidata *nd, unsigned flags, struct path *path)
const char *s = path_init(nd, flags);
int err;
if (IS_ERR(s))
return PTR_ERR(s);
while (!(err = link_path_walk(s, nd)) &&
(err = mountpoint_last(nd)) > 0)
s = trailing_symlink(nd);
if (IS_ERR(s))
err = PTR_ERR(s);
break;
if (!err)
*path = nd->path;
nd->path.mnt = NULL;
nd->path.dentry = NULL;
follow_mount(path);
terminate_walk(nd);
return err;
The comment for follow_mount()
sounded like it was relevant to the question. And it mentions follow_dotdot()
as the main user, which suggested this line of investigation.
/*
* Skip to top of mountpoint pile in refwalk mode for follow_dotdot()
*/
static void follow_mount(struct path *path)
while (d_mountpoint(path->dentry))
struct vfsmount *mounted = lookup_mnt(path);
if (!mounted)
break;
dput(path->dentry);
mntput(path->mnt);
path->mnt = mounted;
path->dentry = dget(mounted->mnt_root);
static int follow_dotdot(struct nameidata *nd)
I had been thinking about how ..
("dotdot") could traverse from a mount point to its parent, e.g. /tmp/..
. But I hadn't previously considered that doing so might "skip to [the] top of [the] mountpoint pile". This happens even if the top mount isn't the one that contains the original /tmp
directory!
add a comment |Â
up vote
2
down vote
accepted
Looking inside Linux v4.17, I think we can say umount
on /
is equivalent to umount
on /..
. And /..
accesses the "top of [the] mountpoint pile".
# stat -f / --format %T
ext2/ext3
# stat -f /.. --format %T
tmpfs
This obscure behaviour of ..
seems to be permitted by POSIX. It only says "As a special case, in the root directory, dot-dot may refer to the root directory itself." (POSIX.1-2017, section 4.13 "Pathname Resolution").
If you want to generalize this and define the behaviour implemented by umount
on other mount points, making a comparison with ..
does not work so well. The term "top of [the] mountpoint pile" still applies, although it doesn't sound like a very formal definition :).
Kernel source code
https://elixir.bootlin.com/linux/v4.17/source/fs/namei.c
See where path_mountpoint()
calls follow_mount()
.
/**
* path_mountpoint - look up a path to be umounted
* @nd: lookup context
* @flags: lookup flags
* @path: pointer to container for result
*
* Look up the given name, but don't attempt to revalidate the last component.
* Returns 0 and "path" will be valid on success; Returns error otherwise.
*/
static int
path_mountpoint(struct nameidata *nd, unsigned flags, struct path *path)
const char *s = path_init(nd, flags);
int err;
if (IS_ERR(s))
return PTR_ERR(s);
while (!(err = link_path_walk(s, nd)) &&
(err = mountpoint_last(nd)) > 0)
s = trailing_symlink(nd);
if (IS_ERR(s))
err = PTR_ERR(s);
break;
if (!err)
*path = nd->path;
nd->path.mnt = NULL;
nd->path.dentry = NULL;
follow_mount(path);
terminate_walk(nd);
return err;
The comment for follow_mount()
sounded like it was relevant to the question. And it mentions follow_dotdot()
as the main user, which suggested this line of investigation.
/*
* Skip to top of mountpoint pile in refwalk mode for follow_dotdot()
*/
static void follow_mount(struct path *path)
while (d_mountpoint(path->dentry))
struct vfsmount *mounted = lookup_mnt(path);
if (!mounted)
break;
dput(path->dentry);
mntput(path->mnt);
path->mnt = mounted;
path->dentry = dget(mounted->mnt_root);
static int follow_dotdot(struct nameidata *nd)
I had been thinking about how ..
("dotdot") could traverse from a mount point to its parent, e.g. /tmp/..
. But I hadn't previously considered that doing so might "skip to [the] top of [the] mountpoint pile". This happens even if the top mount isn't the one that contains the original /tmp
directory!
add a comment |Â
up vote
2
down vote
accepted
up vote
2
down vote
accepted
Looking inside Linux v4.17, I think we can say umount
on /
is equivalent to umount
on /..
. And /..
accesses the "top of [the] mountpoint pile".
# stat -f / --format %T
ext2/ext3
# stat -f /.. --format %T
tmpfs
This obscure behaviour of ..
seems to be permitted by POSIX. It only says "As a special case, in the root directory, dot-dot may refer to the root directory itself." (POSIX.1-2017, section 4.13 "Pathname Resolution").
If you want to generalize this and define the behaviour implemented by umount
on other mount points, making a comparison with ..
does not work so well. The term "top of [the] mountpoint pile" still applies, although it doesn't sound like a very formal definition :).
Kernel source code
https://elixir.bootlin.com/linux/v4.17/source/fs/namei.c
See where path_mountpoint()
calls follow_mount()
.
/**
* path_mountpoint - look up a path to be umounted
* @nd: lookup context
* @flags: lookup flags
* @path: pointer to container for result
*
* Look up the given name, but don't attempt to revalidate the last component.
* Returns 0 and "path" will be valid on success; Returns error otherwise.
*/
static int
path_mountpoint(struct nameidata *nd, unsigned flags, struct path *path)
const char *s = path_init(nd, flags);
int err;
if (IS_ERR(s))
return PTR_ERR(s);
while (!(err = link_path_walk(s, nd)) &&
(err = mountpoint_last(nd)) > 0)
s = trailing_symlink(nd);
if (IS_ERR(s))
err = PTR_ERR(s);
break;
if (!err)
*path = nd->path;
nd->path.mnt = NULL;
nd->path.dentry = NULL;
follow_mount(path);
terminate_walk(nd);
return err;
The comment for follow_mount()
sounded like it was relevant to the question. And it mentions follow_dotdot()
as the main user, which suggested this line of investigation.
/*
* Skip to top of mountpoint pile in refwalk mode for follow_dotdot()
*/
static void follow_mount(struct path *path)
while (d_mountpoint(path->dentry))
struct vfsmount *mounted = lookup_mnt(path);
if (!mounted)
break;
dput(path->dentry);
mntput(path->mnt);
path->mnt = mounted;
path->dentry = dget(mounted->mnt_root);
static int follow_dotdot(struct nameidata *nd)
I had been thinking about how ..
("dotdot") could traverse from a mount point to its parent, e.g. /tmp/..
. But I hadn't previously considered that doing so might "skip to [the] top of [the] mountpoint pile". This happens even if the top mount isn't the one that contains the original /tmp
directory!
Looking inside Linux v4.17, I think we can say umount
on /
is equivalent to umount
on /..
. And /..
accesses the "top of [the] mountpoint pile".
# stat -f / --format %T
ext2/ext3
# stat -f /.. --format %T
tmpfs
This obscure behaviour of ..
seems to be permitted by POSIX. It only says "As a special case, in the root directory, dot-dot may refer to the root directory itself." (POSIX.1-2017, section 4.13 "Pathname Resolution").
If you want to generalize this and define the behaviour implemented by umount
on other mount points, making a comparison with ..
does not work so well. The term "top of [the] mountpoint pile" still applies, although it doesn't sound like a very formal definition :).
Kernel source code
https://elixir.bootlin.com/linux/v4.17/source/fs/namei.c
See where path_mountpoint()
calls follow_mount()
.
/**
* path_mountpoint - look up a path to be umounted
* @nd: lookup context
* @flags: lookup flags
* @path: pointer to container for result
*
* Look up the given name, but don't attempt to revalidate the last component.
* Returns 0 and "path" will be valid on success; Returns error otherwise.
*/
static int
path_mountpoint(struct nameidata *nd, unsigned flags, struct path *path)
const char *s = path_init(nd, flags);
int err;
if (IS_ERR(s))
return PTR_ERR(s);
while (!(err = link_path_walk(s, nd)) &&
(err = mountpoint_last(nd)) > 0)
s = trailing_symlink(nd);
if (IS_ERR(s))
err = PTR_ERR(s);
break;
if (!err)
*path = nd->path;
nd->path.mnt = NULL;
nd->path.dentry = NULL;
follow_mount(path);
terminate_walk(nd);
return err;
The comment for follow_mount()
sounded like it was relevant to the question. And it mentions follow_dotdot()
as the main user, which suggested this line of investigation.
/*
* Skip to top of mountpoint pile in refwalk mode for follow_dotdot()
*/
static void follow_mount(struct path *path)
while (d_mountpoint(path->dentry))
struct vfsmount *mounted = lookup_mnt(path);
if (!mounted)
break;
dput(path->dentry);
mntput(path->mnt);
path->mnt = mounted;
path->dentry = dget(mounted->mnt_root);
static int follow_dotdot(struct nameidata *nd)
I had been thinking about how ..
("dotdot") could traverse from a mount point to its parent, e.g. /tmp/..
. But I hadn't previously considered that doing so might "skip to [the] top of [the] mountpoint pile". This happens even if the top mount isn't the one that contains the original /tmp
directory!
edited Jul 19 at 12:00
answered Jul 19 at 11:23
sourcejedi
18k22375
18k22375
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f457173%2ffilesystem-mounted-on-top-of-is-inaccessible-so-why-can-it-be-unmounted-wi%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password