How to find the root device?

How to find which device corresponds to your root filesystem

I recently found something I was looking for for quite a long time. If you use the mount command in Linux, you can see that the root device is not listed like the other mounted filesystems:

/dev/root on / type ext3 (rw)
/dev/mmcblk0p1 on /mmcboot type vfat (rw)
proc on /proc type proc (rw)
none on /sys type sysfs (rw,noexec,nosuid,nodev)
none on /dev type tmpfs (rw,mode=0755)
...

For the / mount point, you are just told that it corresponds to /dev/root, which is not the real device you are looking for.

Of course, you can look at the kernel command line and see on which initial root filesystem Linux was instructed to boot (root parameter):

$ cat /proc/cmdline
mem=512M console=ttyS2,115200n8 root=/dev/mmcblk0p2 rw rootwait

However, this doesn’t mean that what you see is the current root device. Many Linux systems boot on intermediate root filesystems (like initramdisks and initramfs), which are just used to access the final one.

I explored the contents of /proc, but didn’t find any file revealing what the root device is.

Fortunately, I eventually found a command to find the root device:

$ rdev
/dev/mmcblk0p2 /

But how does this work? How could we find such information by ourselves? Use the Source, Luke!

When you ask yourself questions like this one, the best is to look at the BusyBox sources which implement this command. These sources are usually simpler than the ones for the same GNU command.

Here is what BusyBox rdev does… It first runs the stat system call on the / directory. Let’s run the stat command that corresponds to it:

$ stat /
  File: `/'
  Size: 4096      	Blocks: 8          IO Block: 4096   directory
Device: b302h/45826d	Inode: 2           Links: 23
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2010-07-21 22:00:01.000000000 +0200
Modify: 2010-06-13 15:04:37.000000000 +0200
Change: 2010-06-13 15:04:37.000000000 +0200

What’s interesting is the Device field. It means that the device corresponding to / has the major number b3 in hexadecimal (179 in decimal), and minor number 02. Bingo, this corresponds to /dev/mmcblk0p2:

$ ls -l /dev/mmcblk0p2 
brw-rw---- 1 root disk 179, 2 Jan  1  1970 /dev/mmcblk0p2

Therefore, what BusyBox rdev does is walk through /dev and its subdirectories to find a device file matching the major and minor numbers.

This is not a completely generic solution though. On some very simple embedded systems, you don’t even need to create device files for all existing devices. In particular, the device file for the root filesystem doesn’t have to exist. In such a case, rdev wouldn’t be able to find the root device.

A more generic solution could be to walk through /sys/block which enumerates all the block devices present on a system (even if not all of them have an entry in /dev/. This would allow to find the device with the matching major and minor numbers:

$ cat /sys/block/mmcblk0/mmcblk0p1/dev
179:1

Through this example, you can see how useful it can be to study the sources of system commands to understand how the system works. BusyBox sources, implementing simplified versions of GNU utilities, make this even easier.

Author: Michael Opdenacker

Michael Opdenacker is the founder of Bootlin, and was its CEO until 2021. He is best known for all the free embedded Linux and kernel training materials that he created together with Thomas Petazzoni. He is always looking for ways to increase performance, reduce size and boot time, and to maximize Linux' world domination. More details...

20 thoughts on “How to find the root device?”

  1. Useful info there, thanks – though n.b. it doesn’t work with root mounted over NFS because there’s no entry in sys/block in this case (which is maybe why BusyBox walks /dev).

  2. On some embedded systems the rdev command will fail simply because busybox has been compiled without it. As long as you have a writable device this is not a problem. Simply load a later busybox for your processor from the busybox.net website to that device with a different name and call the command with, for example, /dev/sda/busybox-mipsel rdev.

  3. Hi,

    following your hints I came out with this, maybe simplistic, approach:

    find_linux_root_device() {
    RDEV=$(mountpoint -d /)

    for file in $(find /dev);
    do
    if [ $(stat --printf="%t:%T" "$file") = $RDEV ];
    then
    ROOTDEVICE="$file"
    break;
    fi
    done

    echo "$ROOTDEVICE"
    }

    What do you think about it?

    Thanks,
    Antonio

    1. In the code above I forgot to consider that ‘stat’ prints the major and minor number in hex, while ‘mountpoint’ outputs them in decimal.

      Something like this should be used:


      ...
      CURRENT_DEVICE=$(printf "%d:%d" $(stat --printf="0x%t 0x%T" "$devnode"))
      if [ $CURRENT_DEVICE = $RDEV ];
      ...

      Regards,
      Antonio

  4. #/bin/bash
    find_linux_root_device() {
    RDEV=$(mountpoint -d /)

    for file in /dev/* ; do
    CURRENT_DEVICE=$(stat -c “%t:%T” $file)
    if [ $CURRENT_DEVICE = $RDEV ]; then
    ROOTDEVICE=”$file”
    break;
    fi
    done

    echo “$ROOTDEVICE”
    }

  5. This seems to work for a lot of systems:

    #/bin/bash
    find_linux_root_device() {
    local PDEVICE=`stat -c %04D /`

    for file in $(find /dev -type b 2>/dev/null) ; do
    local CURRENT_DEVICE=$(stat -c “%02t%02T” $file)
    if [ $CURRENT_DEVICE = $PDEVICE ]; then
    ROOTDEVICE=”$file”
    break;
    fi
    done

    echo “$ROOTDEVICE”
    }

  6. Hello Team,

    cat /proc/cmdline
    console=ttyS0,115200 root=/dev/nfs rw nfsroot=192.168.1.100:/home/nfs/IntelCE,nolock ip=dhcp mem=exactmap memmap=1M@0 memmap=639M@1M

    # rdev
    0x000c /

    How can i increase the size of my root partiotion , it is shown as /dev/root.
    Thanks,
    Rashmi

  7. Assuming you have no duplicate partitions mounted nor any single partition mounted twice:

    df -a | grep "`df -a | grep rootfs | cut -d -f2- | sed 's/^ *//g'`" | cut -d -f1 | tail -1

    Basically, run df -a to get stats on what it lists as rootfs and then use that info to scan for what other listing has those stats.

    1. Interesting. What kind of system is this? What distribution is it, or what was used to generate the root filesystem?

      As least, this doesn’t seem to be a standard feature. Ubuntu 13.04 with Linux 3.8 doesn’t have such a link.

      Thanks!

      Michael.

  8. #! /bin/bash

    MAJOR_ROOTFS=$(mountpoint -d / | cut -f 1 -d “:”)
    MINOR_ROOTFS=$(mountpoint -d / | cut -f 2 -d “:”)

    DEV_ROOTFS=$(cat /proc/partitions | awk {‘if ($1 == “‘${MAJOR_ROOTFS}'” && $2 == “‘${MINOR_ROOTFS}'”) print $4 ‘})

    echo /dev/$DEV_ROOTFS

    However, this script doesn’t work when rootfs is an UBI file system. It fails because “mountpoint” returns wrong major/minor numbers. How can this be solved in a more generic way?

  9. I was just investigating a solution to this and found this command that seems useful:
    findmnt


    user@someplace:~# findmnt
    TARGET SOURCE FSTYPE OPTIONS
    / /dev/mmcblk0p2 ext3 rw,relatime,errors=continue,user_x
    |-/dev devtmpfs devtmpfs rw,relatime,size=383868k,nr_inodes
    | `-/dev/pts devpts devpts rw,relatime,gid=5,mode=620
    |-/proc proc proc rw,relatime
    |-/sys sysfs sysfs rw,relatime
    | `-/sys/kernel/debug debugfs debugfs rw,relatime
    |-/run tmpfs tmpfs rw,nosuid,nodev,mode=755
    |-/var/volatile tmpfs tmpfs rw,relatime

    1. Great, that’s exactly what I’ve been looking for. It solved the problem for me on a Raspberry Pi with Raspian Jessie.

  10. Author, can you kindly let me know how to properly read the file system type?

    For instance, I’d like to know my internal and external sdcard file system, but some of the Market apps show types different from what I expect…

    1. That’s a slightly out of topic for Android, but I’m glad to help.

      You can get the excellent “Terminal Emulator for Android” app and then run the mount command. It will tell you what filesystems are in use on your system.

      Cheers,

      Michael.

    1. Sure, that’s the easiest way. However, I was in the perspective of a small embedded Linux system that may not even have a /etc/fstab file and would be mounting its mount points through a simple script…

  11. what is my rootfs device?

    root@ibm#findmnt
    TARGET SOURCE FSTYPE OPTIONS
    / unionfs rw,relatime,dirs=/host/root_rw/image-a=rw:/host/root_ro=ro
    |-/sys sysfs sysfs rw,nosuid,nodev,noexec,relatime
    | |-/sys/fs/cgroup tmpfs rw,relatime,size=4k,mode=755
    | |-/sys/fs/fuse/connections fusectl rw,relatime
    | |-/sys/kernel/debug debugfs rw,relatime
    | `-/sys/kernel/security securityfs rw,relatime
    |-/proc proc proc rw,nosuid,nodev,noexec,relatime
    |-/dev udev devtmpfs rw,relatime,size=122448k,nr_inodes=30612,mode=755
    | `-/dev/pts devpts devpts rw,nosuid,noexec,relatime,gid=5,mode=620
    |-/run tmpfs tmpfs rw,nosuid,relatime,size=101952k,mode=755
    | |-/run/lock tmpfs rw,nosuid,nodev,noexec,relatime,size=5120k
    | |-/run/shm tmpfs rw,nosuid,nodev,relatime
    | `-/run/user tmpfs rw,nosuid,nodev,noexec,relatime,size=102400k,mode=755
    |-/mnt/ro /dev/mmcblk0p3 ext4 ro,relatime,data=ordered
    `-/mnt/rw /dev/mmcblk0p4 ext4 rw,relatime,data=ordered

Leave a Reply to Michael Opdenacker Cancel reply