2

Using unshare -Umr I created a new user, mount namespaces where the calling process is moved into. Then via mount -t tmpfs tmpfs / I mounted a new tmpfs instance on the root / of the directory tree within the new mount namespace.

Since the tmpfs is empty I would expect to see an empty list from the command ls -la /, however here is the output:

ubuntu@ubuntu:~$ unshare -Umr /bin/bash
root@ubuntu:~# mount -t tmpfs tmpfs /
root@ubuntu:~# ls -la /
total 5309704
drwxr-xr-x  24 nobody nogroup       4096 Nov 22  2023 .
drwxrwxrwt   2 root   root            40 Nov 11 15:47 ..
drwxr-xr-x   2 nobody nogroup       4096 Jan 25  2023 bin
drwxr-xr-x   3 nobody nogroup       4096 Jan 25  2023 boot
drwxr-xr-x   2 nobody nogroup       4096 Nov 11  2019 cdrom
drwxr-xr-x  17 nobody nogroup       3820 Aug 22 14:22 dev
drwxr-xr-x 105 nobody nogroup       4096 Mar 14  2024 etc
-rw-r--r--   1 root   root    1688371200 Jan 19  2021 GISO
drwxr-xr-x   3 nobody nogroup       4096 Nov 11  2019 home
lrwxrwxrwx   1 nobody nogroup         34 Jan 25  2023 initrd.img -> boot/initrd.img-4.15.0-202-generic
lrwxrwxrwx   1 nobody nogroup         34 Jan 25  2023 initrd.img.old -> boot/initrd.img-4.15.0-132-generic
drwxr-xr-x  21 nobody nogroup       4096 Jan 25  2023 lib
drwxr-xr-x   2 nobody nogroup       4096 Jan 25  2023 lib64
drwx------   2 nobody nogroup      16384 Nov 11  2019 lost+found
drwxr-xr-x   2 nobody nogroup       4096 Feb 10  2021 media
drwxr-xr-x   2 nobody nogroup       4096 Aug  5  2019 mnt
drwxr-xr-x   3 nobody nogroup       4096 Nov 26  2020 opt
dr-xr-xr-x 123 nobody nogroup          0 Aug 22 12:22 proc
drwx------   4 nobody nogroup       4096 Dec  6  2023 root
drwxr-xr-x  24 nobody nogroup        820 Nov 11 15:20 run
drwxr-xr-x   2 nobody nogroup      12288 Jan 25  2023 sbin
drwxr-xr-x   4 nobody nogroup       4096 Nov 11  2019 snap
drwxr-xr-x   3 nobody nogroup       4096 Jan 24  2020 srv
-rw-------   1 nobody nogroup 3748659200 Nov 11  2019 swap.img
dr-xr-xr-x  13 nobody nogroup          0 Nov 11 15:40 sys
drwxrwxrwt  10 nobody nogroup       4096 Nov 11 15:42 tmp
drwxr-xr-x  10 nobody nogroup       4096 Aug  5  2019 usr
drwxr-xr-x  13 nobody nogroup       4096 Aug  5  2019 var
lrwxrwxrwx   1 nobody nogroup         31 Jan 25  2023 vmlinuz -> boot/vmlinuz-4.15.0-202-generic
lrwxrwxrwx   1 nobody nogroup         31 Jan 25  2023 vmlinuz.old -> boot/vmlinuz-4.15.0-132-generic
root@ubuntu:~#

as in the filesystem mounted as / before the tmpfs was mounted over. Why I am getting this result ?

0

1 Answer 1

2

Overmounting the root filesystem can have surprising results. The short answer is "well don't do that then" :-).

The longer answer is that Linux systems do it every time they start up. It is technically possible, but you have to tread carefully.

How to explain your results

The path / is a special case. It resolves to the root directory of the current process. It does not check if another filesystem has been mounted on top.

Related case: overmounting a non-root directory

Consider resolving a path that does not start with /. In that case, resolution starts from the current directory of the current process. It does not check if another filesystem has been mounted on top of the current directory.

# cd /mnt
# touch old-mnt-file
# ls
old-mnt-file

# mount -t tmpfs tmpfs /mnt
# ls
old-mnt-file

# touch /mnt/new-mnt-file
# ls /mnt
new-mnt-file

path_resolution(7) — Linux manual page

If the pathname starts with the '/' character, the starting lookup directory is the root directory of the calling process

[...]

If the pathname does not start with the '/' character, the starting lookup directory of the resolution process is the current working directory of the process.

Practical ways to change the root directory

The root directory of the current process can be changed. This is called "chroot".

The root directory of the current namespace can be replaced. This is called "pivot_root".

After "pivot_root", it is possible to unmount the previous root filesystem if there are no processes still using it. This is not possible with "chroot".

If you need to, there is a way to overmount a new root directory for the current process. It is useful in the "initramfs":

WARNING: "switch_root" will delete all files and directories on the current root filesystem. Do not run the "switch_root" command on your main filesystem.

(If [initramfs] needs to hand off control it can overmount / with a new root device and exec another init program. See the switch_root utility, below.)

When switching another root device, [an old-style] initrd would pivot_root and then umount the ramdisk. But [nowadays] initramfs is rootfs: you can neither pivot_root rootfs, nor unmount it. Instead delete everything out of rootfs to free up the space (find -xdev / -exec rm '{}' ';'), overmount rootfs with the new root (cd /newmount; mount --move . /; chroot .), attach stdin/stdout/stderr to the new /dev/console, and exec the new init.

Since this is a remarkably persnickety process (and involves deleting commands before you can run them), the klibc package introduced a helper program (utils/run_init.c) to do all this for you. Most other packages (such as busybox) have named this command "switch_root".

-- Documentation/filesystems/ramfs-rootfs-initramfs.rst

A not-so-practical method

If overmounting a new root filesystem does not actually change /, then is there any way to access the overmounted filesytem?

The special case affects /. It also affects /., because path resolution can simply strip . path segments.

However, the path .. does check for mounted filesystems. It seems the same is true for /mnt/... And even /...

It seems that you can use chroot /.. to switch to the overmounted root filesystem. I don't remember this being used anywhere. I recommend using the standard methods from "switch_root" instead. It will be easier for most people to understand. Including us - when we inevitably forget this Q&A and have to look everything up again :-).

20
  • 1
    No evidence is left in mount/findmnt: unix.stackexchange.com/questions/152029/… Commented Nov 12, 2024 at 19:52
  • 1
    / is the root directory of the current process. The root directory of the process is inherited from its parent process, e.g. ls -la inherits the same root directory as bash. I suppose the namespace root is a bit more obscure subject... Commented Nov 26, 2024 at 10:34
  • 1
    No process will see the new tmpfs mounted on /, unless you do the "switch_root" proceedure. Or unless a process re-enters the mount namespace using setns() for some strange reason. Note: I have edited the answer. Commented Nov 26, 2024 at 11:54
  • 1
    Ah ok, you mean whether some process calls setns() after the new tmpfs is mounted over /, it gets it instead of the filesystem previously mounted there. Commented Nov 26, 2024 at 12:27
  • 1
    sorry for typo! I meant to mount /mnt, not / in this example. couldn't easily test as I was responding from Windows. Commented Nov 28, 2024 at 10:14

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.