0

Is there a safe way to map a filesystem path to a /sys/block/ node.

For instance on my system (Ubuntu) my / path is mounted from /dev/disk/by-uuid/7f6a93a7-1e63-48a3-a7e3-b336a2f9dbf7 which is a symlink to /dev/sda1 which is a partition of /dev/sda which maps to /sys/block/sda

How do I get from:

/ -> /sys/block/sda

in a safe way that I can rely on to work across all distributions?

2 Answers2

0

fstat() on the file returns a struct stat which contains a field of type dev_t. There are macros which will extract the major and minor device numbers. Those uniquely identify a drive and partition on a system.

caskey
  • 271
  • 1
  • 5
0

Thanks to caskey for pointing me in the right direction. In case someone else needs the same functionality, here is the function that converts a path to a device:

#include <libudev.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string>

std::string getPhysicalDiskSerialNumber(const char *path) {
    struct stat s;
    char syspath[256];
    syspath[0] = '\0';
    stat(path,&s);
    sprintf(syspath,"/sys/dev/block/%d:%d",major(s.st_dev),minor(s.st_dev));

    struct udev *context = udev_new();
    struct udev_device *device = udev_device_new_from_syspath(context, syspath);
    const char *id = udev_device_get_property_value(device, "ID_SERIAL");
    std::string serial = id;

    // Cleanup
    udev_device_unref(device);
    udev_unref(context);
    return serial;
}