Как программно удалить флешку по имени узла устройства?

У меня есть система Linux с несколькими подключенными USB-накопителями, такими как /dev/sda1, /dev/sdb1 и т. д. Мне нужно извлечь один из них из моей программы — что-то вроде EjectDrive("/dev/sdb1"); Затем мне может понадобиться программно переустановить вставьте диск.

Я знаю, что могу сделать это из командной строки, если знаю шину USB, порт и номер устройства. например echo '2-1.3' > /sys/bus/usb/drivers/usb/unbind, а затем echo '2-1.3' > /sys/bus/usb/drivers/usb/bind

Я не уверен, как это сделать с C++, и быть на 100% уверенным, что я использую правильную шину, порт и устройство для указанного диска.

Это встроенная платформа с BusyBox v1.22.1, поэтому udev мне недоступен, а lsusb возвращает минимум информации.


person IndefatibableGoodForm    schedule 20.06.2017    source источник
comment
Всегда есть программа eject..   -  person Jesper Juhl    schedule 20.06.2017
comment
Так что есть. Но мне также (может быть) нужно программно повторно вставить его, так что это решает только половину моей проблемы. Я отредактирую вопрос, чтобы прояснить это. Спасибо.   -  person IndefatibableGoodForm    schedule 20.06.2017
comment
Вы изучили справочные страницы? Какова команда для вывода списка USB-накопителей в системе, если они есть? (используйте google) Итак, как узнать шину, порт, устройство? Как вы узнаете, когда вы не знаете? (подсказка - погуглите, как составить список всех usb-устройств?) Возможно, вы могли бы провести больше исследований... для этих вопросов есть другие ресурсы, но ни один из них не C++   -  person 2785528    schedule 21.06.2017


Ответы (1)


Да, это можно сделать с помощью libusb (перейдите по этой ссылке для использования libusb с C++). Теперь несколько вещей, которые нужно иметь в виду -

1 - Что такое адрес устройства? (Вы можете получить это с помощью libusb API)

libusb_get_device_list (libusb_context *ctx, libusb_device ***list)
libusb_get_device_address (libusb_device *dev)
libusb_get_port_number (libusb_device *dev)

2 - Устройство подключено к порту корневого концентратора или к порту концентратора? (Это можно сделать, прочитав родительское устройство /dev/sdb1 или sda1)

libusb_get_parent (libusb_device *dev)

3 - Если он подключен к концентратору, выполните передачу управления, чтобы «очистить» функцию PORT_POWER этого порта. Это отключит порт, и устройство будет отключено. Вы можете «настроить» функцию PORT_POWER, чтобы включить порт, и устройство снова будет подключено. Помните, что вы не получите никакого события отключения, которое соответствует спецификации. (EHCI или XHCI)

int libusb_control_transfer (   libusb_device_handle *  dev_handle,
uint8_t     bmRequestType,
uint8_t     bRequest,
uint16_t    wValue,
uint16_t    wIndex,
unsigned char *     data,
uint16_t    wLength,
unsigned int    timeout 
)   

4 - Если устройство подключено к порту корневого концентратора напрямую, проверьте, поддерживает ли libusb сброс питания порта корневого концентратора. Я не уверен в этом. Это также зависит от стека драйверов хост-контроллера.

Пожалуйста, перейдите по ссылке, которую я упомянул вверху, например, для использования этих API.

person Shaibal    schedule 22.06.2017
comment
Это могло бы быть отличным ответом, если бы в нем упоминались фактические libusb API, которые можно было бы использовать. В этом ответе отсутствует минимальный фрагмент кода (даже если он был проверен только для конкретной настройки аппаратного / программного обеспечения), который демонстрирует идентификацию USB-устройства по его имени узла устройства и его извлечение. - person TheCodeArtist; 24.06.2017
comment
@TheCodeArtist Спасибо за предложение. Добавлены API. - person Shaibal; 24.06.2017