2010-08-16 2 views
4

Если я подключаю USB-накопитель, я вижу новую папку в/sys/bus/usb/devices ... таким образом, новое USB-устройство.Linux: Как сопоставить блок-устройство с USB-устройством?

Также я вижу новую папку в/sys/block ... таким образом, новое блочное устройство.

Мой вопрос: Как я могу получить водонепроницаемое сопоставление между этими двумя устройствами? Значения: Если я получу новое устройство в/sys/bus/usb/devices, как я могу программно (fi путем проверки/sys/...) узнать, какое блок-устройство сопоставлено/связано с этим USB-устройством и типом -versa ?!

ответ

5

Информация в /sys организована несколькими способами (с помощью драйвера, на автобусе и т. Д.), И есть много символических ссылок для перехода от одной иерархии к другой.

Дело в точке (пример показан на ядре 2.6.26): начиная с блочного устройства в /sys/block/sdc, символическая ссылка /sys/block/sdc/device точек внутри иерархии типа устройства. Вы можете видеть, что это устройство USB, так как цель ссылки нечто вроде

../../devices/pci0000:00/0000:00:1d.7/usb8/8-2/8-2:1.0/host9/target9:0:0/9:0:0:0 

С другой стороны, USB устройства перечислены в /sys/bus/usb/devices, и мы можем видеть, что 8-2:1.0 является дискообразной устройство, потому что /sys/bus/usb/devices/8-2:1.0/driver ссылки на usb-storage , Чтобы узнать, что такое связанное блочное устройство, нам кажется, что нам нужно спуститься в каталог /sys/bus/usb/devices/8-2:1.0/host9/target9:0:0/9:0:0:0, который содержит символическую ссылку block:sdc, целью которой является /sys/block/sdc.

ADDED Предупреждение: точная структура /sys изменяется с версии ядра на версию ядра. Например, с ядром 2.6.32, /sys/block/sdc/device указывает прямо на /dev/bus/scsi, не пропуская USB-хоп.


Другой подход заключается в вызове команды udevadm info. udevadm info -p /sys/block/sdc --query=… содержит информацию об устройстве на основании его записи /sys, а udevadm info -n sdc --query=… содержит информацию об устройстве /dev/sdc.

информация включает в себя информацию шины, например udevadm info -p /sys/block/sdc --query=env показывает

ID_BUS=usb 
ID_PATH=pci-0000:00:1d.7-usb-0:2:1.0-scsi-0:0:0:0 

в документации по Udev может иметь больше информации, представляющей интерес для Вас.


Заключительное слово предостережения: есть всевозможные сложные случаи, которые могут сделать все, что вы не так водонепроницаемы. Как ваша программа будет работать с одним USB-устройством, которое представляет собой массив дисков, которым назначено несколько блочных устройств? И наоборот, как ваша программа будет работать с массивом RAID, собранным с нескольких устройств (возможно, некоторые из них USB и некоторые из них не являются)? Вас интересуют другие типы съемных носителей, такие как Firewire и e-SATA? и т. д. Вы не сможете предсказать все угловые случаи, поэтому убедитесь, что они изящно потерпели неудачу.

+0

Спасибо за объяснение. Я могу следовать за вашим образцом на машине debian. Но на Ubuntu f.i./sys/block/sdb содержит ссылку «устройство» на «../../../7:0:0:0» ». Если я следую за остальным вами образцом, символьная ссылка «block: sdb» отсутствует. На всех путях устройств, начинающихся с/sys/block, не появляется никаких намеков на то, что это USB-устройство :-( Итак, для debian это может сработать, но Ubuntu, похоже, как-то отличается. Команда «udevinfo» не является доступный с Ubuntu, но есть «udevadm», который кажется похожим. Но анализ вывода командной строки, может быть, не самый лучший? – Alex

+0

относительно водонепроницаемой проблемы: Мои варианты использования не заботятся о рейдах различных типов устройств. Это всего лишь диск с флэш-памятью USB. Все, что мне нужно - это идентификатор продавца + идентификатор продукта + номер_соединения + отношение к точке монтирования. Вот и все. – Alex

+0

@ Alex: Хорошо, я посмотрел, и кажется, что больше последние версии ядра имеют различную структуру символических ссылок в '/ sys'. Насколько я могу судить,' udevinfo' (где он существует) является точно эквивалент 'udevadm info'. Похоже, что «udevadm info» - это путь (он дает вам информацию о продавце и серийном номере). – Gilles

0

Насколько я понял, можно получить доступ к информации udev через библиотеку «libudev». В сети также имеется хороший образец: http://www.signal11.us/oss/udev/

Я смог изменить его, чтобы прочитать все устройства «/ dev/sd *», и получить их идентификатор поставщика, идентификатор продукта, а также серийный номер. Я думаю, что это решение - дистрибутив kernel/linux. Но я все еще должен это проверить.

Смежные вопросы