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.

About Michael Opdenacker

Michael Opdenacker is the founder of Free Electrons. 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...
This entry was posted in Technical and tagged , , . Bookmark the permalink.

10 Responses to How to find the root device?

  1. Neil Newell says:

    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. Jim says:

    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. ao2 says:

    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

    • ao2 says:

      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. Meier says:

    #/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. Meier says:

    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. john endeavor says:

    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. BrainwreckedTech says:

    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.

  8. kernc says:

    on my system, /dev/root is a symlink to /dev/sda1, which is where the system was booted from.

    • 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.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>