I am doing a project with mass storage devices in linux. I am trying to write an application which will list all the connected usb mass storage devices and will give notification when a new mass storage device is plugged in. I am using libudev for this purpose. I have used the code found in "http://www.signal11.us/oss/udev/" . I have done the modification here
/* Create a list of the devices in the 'block' subsystem. */
enumerate = udev_enumerate_new(udev);
udev_enumerate_add_match_subsystem(enumerate, "block");
udev_enumerate_scan_devices(enumerate);
devices = udev_enumerate_get_list_entry(enumerate);
The problem now is that it list all the block devices. I want only the usb mass storage devices. How to get this list. One more problem is that how to get the label of usb storage devices using libudev.
One solution is to match devices with the following criteria:
Here is example program (also available on github):
#include <libudev.h>
#include <stdio.h>
static struct udev_device*
get_child(
struct udev* udev, struct udev_device* parent, const char* subsystem)
{
struct udev_device* child = NULL;
struct udev_enumerate *enumerate = udev_enumerate_new(udev);
udev_enumerate_add_match_parent(enumerate, parent);
udev_enumerate_add_match_subsystem(enumerate, subsystem);
udev_enumerate_scan_devices(enumerate);
struct udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate);
struct udev_list_entry *entry;
udev_list_entry_foreach(entry, devices) {
const char *path = udev_list_entry_get_name(entry);
child = udev_device_new_from_syspath(udev, path);
break;
}
udev_enumerate_unref(enumerate);
return child;
}
static void enumerate_usb_mass_storage(struct udev* udev)
{
struct udev_enumerate* enumerate = udev_enumerate_new(udev);
udev_enumerate_add_match_subsystem(enumerate, "scsi");
udev_enumerate_add_match_property(enumerate, "DEVTYPE", "scsi_device");
udev_enumerate_scan_devices(enumerate);
struct udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate);
struct udev_list_entry *entry;
udev_list_entry_foreach(entry, devices) {
const char* path = udev_list_entry_get_name(entry);
struct udev_device* scsi = udev_device_new_from_syspath(udev, path);
struct udev_device* block = get_child(udev, scsi, "block");
struct udev_device* scsi_disk = get_child(udev, scsi, "scsi_disk");
struct udev_device* usb
= udev_device_get_parent_with_subsystem_devtype(
scsi, "usb", "usb_device");
if (block && scsi_disk && usb) {
printf("block = %s, usb = %s:%s, scsi = %s\n",
udev_device_get_devnode(block),
udev_device_get_sysattr_value(usb, "idVendor"),
udev_device_get_sysattr_value(usb, "idProduct"),
udev_device_get_sysattr_value(scsi, "vendor"));
}
if (block)
udev_device_unref(block);
if (scsi_disk)
udev_device_unref(scsi_disk);
udev_device_unref(scsi);
}
udev_enumerate_unref(enumerate);
}
int main()
{
struct udev* udev = udev_new();
enumerate_usb_mass_storage(udev);
udev_unref(udev);
return 0;
}
And it's output for my external disk:
block = /dev/sdb, usb = 0bc2:ab20, scsi = Seagate
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With