Get /dev/disk/by-id element from /dev/sd* element

7.3k views Asked by At

I know that there is /dev/disk/by-id/ folder which contains links to /dev/sd* elements. I'd like to know, is there any way to get by-id element pointing to, for example, /dev/sda.

P.S.: yeah, I know that I can loop through elements in by-id folder and /dev/sd*, so that I can compare serial numbers and match them. But is there any better way?

EDIT: sorry for my mistake. It should be done in C/C++. UUID's were mentioned. That would be great, they are unique and so on, but how can I collect all the UUID's of one hdd? I mean the main, pointing to sda, for example, and partition UUID's, pointing to sda1, sda2 and so on.

3

There are 3 answers

0
cheetahfm On BEST ANSWER

I'm sorry for late answer.

My question was wrong, I did not need /dev/sd* element to get /dev/disk/by-id/ elements.

I've used libudev and got these elements:

#include <libudev.h>

...

struct udev *udev;
udev = udev_new();

udev_enumerate *enumerate;
enumerate = udev_enumerate_new(udev);

udev_list_entry *udev_entries;
udev_list_entry *dev_list_entry;
udev_device *dev;

udev_enumerate_add_match_subsystem(enumerate, "block");
udev_enumerate_scan_devices(enumerate);
udev_entries = udev_enumerate_get_list_entry(enumerate);
udev_list_entry_foreach(dev_list_entry, udev_entries)
{
    const char* path = udev_list_entry_get_name(dev_list_entry);
    dev = udev_device_new_from_syspath(udev, path);
    const char* bus = udev_device_get_property_value(dev, "ID_BUS");
    const char* type = udev_device_get_property_value(dev, "ID_TYPE");

    if (!bus || !type)
        continue;

    // strncmp return 0 if equal
    if (!(strncmp(bus, "ata", 3) &&
            !strncmp(type, "disk", 4))
        continue;

    // i wanted to get only partitions, so parent is empty
    udev_device *parent = 
        udev_device_get_parent_with_subsystem_devtype(dev, "block", "disk");
    if (!parent)
        continue;

    // get /dev/disk/by-id/...-partX
    struct udev_list_entry* devlinks = udev_device_get_devlinks_list_entry(dev);
    std::string partition(udev_list_entry_get_name(devlinks));
    // now we have /dev/disk/by-id/...-partX in partition and can save it somewhere
}

P.S.: I've used that in special LFS-based distribution, that does have serial numbers in /dev/disk/by-id/ name.

2
sysconfig On

Hm, the id is not something you'd normally use to uniquely identify a partition. IF the UUID is an option, you can do this:

# blkid  /dev/sdf1
/dev/sdf1: UUID="1cdc1aec-5bde-45d4-9202-bc8fdec378f1" TYPE="ext2" 

blkid supports a few command line options to give you different levels of verbosity and formatting.

The reason why you wouldn't normally use the id is that they are not guaranteed to be unique. UUIDs usually are.

If it's got to be the id, iterating through the /dev/disk/by-id directory and finding the one which points to the desired device is probably easiest.

0
vtwaldo21 On

I know its an old question but still the first result when asked on google, yet none of the answers above speak to the OPs question (which they admitted was wrong, but it matches the question I was asking)

Turns out the solution I found was, given a disk "sda", you can find the by-id by running

udevadm info -q symlink --path=/sys/block/sda | awk '{print "/dev/" $1}'