Mounting Virtual Filesystems Before Chroot | Generated by AI

Home 2026.07

Question: In the recovery flow from my post Recover from a Failed Linux Kernel Boot, why do we run these five mount commands before chroot /mnt? What does each one actually do?

Answer:

The five lines are building a functional copy of your installed system inside /mnt so that chroot /mnt behaves like you actually booted that system. One line mounts your real disk; the other four graft the live USB’s kernel-provided virtual filesystems into it.

The core insight: chroot changes the filesystem view, not the kernel

chroot is a trivially simple syscall — it just changes what a process sees as /. After chroot /mnt, when a program opens /proc/mounts, the kernel resolves that to /mnt/proc/mounts on the real filesystem. But you’re still running the live USB’s kernel. The broken kernel on disk is just files; it’s not executing.

So the problem is: your on-disk root filesystem contains empty directories at /dev, /proc, /sys, /run — those are always populated at runtime by the kernel, never stored on disk. A chroot into a bare disk mount gives you a system that looks right but is deaf and blind: no devices, no process info, no kernel interfaces.

Line by line

sudo mount /dev/nvme0n1pX /mnt

Normal block-device mount. The kernel reads the filesystem (ext4/btrfs) on that NVMe partition and attaches it at /mnt. Now /mnt/boot, /mnt/etc, /mnt/usr are your real installed system. (On Fedora with btrfs defaults you may need -o subvol=root, and a separate mount /dev/nvme0n1pY /mnt/boot plus /mnt/boot/efi — more on that below.)

sudo mount --bind /dev /mnt/dev

A bind mount makes an existing directory tree visible at a second location — same inodes, no copy, like a hardlink for directory trees at the VFS layer. /dev on the live system is a devtmpfs populated by the kernel + udev with device nodes: /dev/nvme0n1, /dev/null, /dev/urandom, /dev/tty.

Why the chrooted tools need it:

Without it: grub2-install: error: cannot find a device for /boot/efi.

sudo mount --bind /proc /mnt/proc

procfs is the kernel’s process/state interface rendered as files. The critical consumer here is /proc/mountsgrub2-mkconfig and dracut read it to figure out what’s mounted where and what the root device is. /proc/cmdline, /proc/filesystems, /proc/cpuinfo also get consulted. Without it, grub2-mkconfig typically dies with /usr/sbin/grub2-probe: error: failed to get canonical path.

sudo mount --bind /sys /mnt/sys

sysfs is the kernel’s device-model tree — every device, driver, and bus as a directory hierarchy. Two critical users:

sudo mount --bind /run /mnt/run

A tmpfs for runtime state. The main reason on Fedora: udev’s device database lives in /run/udev, and dracut/lvm/cryptsetup query it to resolve device properties and UUIDs. Also, Fedora symlinks /etc/resolv.conf → /run/systemd/resolve/..., so binding /run is what gives your chroot working DNS — which you need for dnf reinstall kernel-core.

Mental model

Live USB kernel (running)          Disk (just files)
        │                                │
        ├── /dev  ─── bind ──►  /mnt/dev │
        ├── /proc ─── bind ──►  /mnt/proc├── your broken Fedora
        ├── /sys  ─── bind ──►  /mnt/sys │
        └── /run  ─── bind ──►  /mnt/run │
                                         ▼
                              chroot /mnt = "boot" the disk's
                              userspace on the USB's kernel

You’re doing a Frankenstein boot: the live kernel provides hardware access, the disk provides the userspace (dnf, dracut, grub2-install, your configs). That’s the entire trick.

Two practical upgrades

1. Use --rbind + --make-rslave for /dev and /sys (what Arch’s arch-chroot does):

sudo mount --rbind /dev  /mnt/dev  && sudo mount --make-rslave /mnt/dev
sudo mount --rbind /sys  /mnt/sys  && sudo mount --make-rslave /mnt/sys
sudo mount -t proc /proc /mnt/proc
sudo mount --bind /run   /mnt/run

Plain --bind only grafts the top-level mount, missing submounts like /dev/pts (pseudo-terminals — some scripts hang without it) and /sys/firmware/efi/efivars. --rbind recursively binds the whole subtree; --make-rslave prevents unmounts inside the chroot from propagating back and killing your live session.

2. Don’t forget the boot partitions before chrooting. Fedora splits them, and both matter for kernel + GRUB repair:

# check layout first
lsblk -f
sudo mount /dev/nvme0n1pY /mnt/boot        # ext4 /boot, holds vmlinuz + initramfs
sudo mount /dev/nvme0n1p1 /mnt/boot/efi    # FAT32 ESP, holds grubx64.efi

If /boot isn’t mounted, dnf reinstall kernel and dracut --regenerate-all write kernels into a directory on the root partition that the firmware will never see — the repair “succeeds” and the machine still won’t boot. This is one of the most common silent failures in this exact recovery flow.

Or skip the ceremony entirely: systemd-nspawn -D /mnt (from the live USB) sets up all of this for you and gives a cleaner container-style chroot.

References:


Back Donate