Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Linux] psutil.disk_partitions() returns /dev/root on Ubuntu 20.04 on AWS #1999

Closed
albertvaka opened this issue Oct 13, 2021 · 9 comments · Fixed by #2000
Closed

[Linux] psutil.disk_partitions() returns /dev/root on Ubuntu 20.04 on AWS #1999

albertvaka opened this issue Oct 13, 2021 · 9 comments · Fixed by #2000

Comments

@albertvaka
Copy link

albertvaka commented Oct 13, 2021

Summary

  • OS: Ubuntu 20.04
  • Architecture: 64bit
  • Psutil version: 5.8.0
  • Python version: 3.8.10
  • Type: core

Description

On a default AWS instance running Ubuntu 20.04, psutil.disk_partitions() returns /dev/root instead of /dev/xvda1.

This is because /proc/mounts contain this entry:

/dev/root / ext4 rw,relatime,discard 0 0

However, the actual root disk device is /dev/xvda1. Both mount and findmnt do return the right device:

$ mount
/dev/xvda1 on / type ext4 (rw,relatime,discard)
[...]
$ findmnt -n -o SOURCE /
/dev/xvda1

I found some people doing a workaround to call findmnt manually in this case, but I think this should be handled by psutil.

@giampaolo
Copy link
Owner

https://unix.stackexchange.com/questions/295060/why-on-some-linux-systems-does-the-root-filesystem-appear-as-dev-root-instead

In here it says that /dev/root is a link. I guess that if we readlink() it we'll get the real device name? Can you try?

@giampaolo
Copy link
Owner

@giampaolo
Copy link
Owner

giampaolo commented Oct 13, 2021

This should do it:

import os

def get_fs_device(path):
    pmap = {}
    with open("/proc/partitions") as f:
        for line in f.readlines()[2:]:
            fields = line.split()
            major = int(fields[0])
            minor = int(fields[1])
            name = fields[3]
            pmap[(major, minor)] = name

    dev = os.stat(path).st_dev
    name = pmap[(os.major(dev), os.minor(dev))]
    return "/dev/%s" % name

print(get_fs_device("/"))

On my Linux it prints /dev/nvme0n1p2.

@albertvaka
Copy link
Author

albertvaka commented Oct 13, 2021

I can confirm this does return the right device for me (/dev/xvda1 in this case). Also that /dev/root is not a link for me.

Is this something that psutil.disk_partitions() should do before returning the devices, or is this something I should do on my end after calling psutil.disk_partitions()?

@giampaolo
Copy link
Owner

giampaolo commented Oct 13, 2021

Something like this will eventually have to be included in psutil, but in case of error we should probably return "/dev/root" instead of crashing.

Also, I see there are multiple variants of the above code online (read /sys fs, use readlink(), parse /proc/cmdline, ...). We will probably have to implement these variants, and the code should try them all before (silently) giving up.

@giampaolo
Copy link
Owner

Fixed in #2000. Out of curiosity, can you please paste the output of ls -l /dev/root?

@albertvaka
Copy link
Author

That was awesomely fast, thanks a ton!

Here you have the output you requested:

$ ls -l /dev/root
brw------- 1 root root 202, 1 Oct  8 14:04 /dev/root

And the same on the actual disk:

$ ls -l /dev/xvda1 
brw-rw---- 1 root disk 202, 1 Oct  8 14:04 /dev/xvda1

@giampaolo
Copy link
Owner

What about readlink -f /dev/root?

@albertvaka
Copy link
Author

$ readlink -f /dev/root
/dev/root

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants