LINUX.ORG.RU

безопасное извлечение usb

 , ,


0

3

всем привет, задача такая..необходимо просканировать систему на юсб устройства, с целью получения серийного номера, а также безопасного извлечения устройства, если серийный номер не совпадает.

вот тут возникла проблема. опишу конкретней: список usb устройств получаю с помощью libudev, указывая, «subsystem» - «usb» и «DEVTYPE» соответственно «usb_device», серийные номера отлично считываются, но вот с извлечением возникли проблемы..как я разобрался, для извлечения нужен путь к устройству, типа такого «/dev/sdc», с ним все извлекается и все работает, но его нет в дереве «subsystem» - «usb».

вот что там есть:

P: /devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-2 N: bus/usb/001/003 E: BUSNUM=001 E: DEVNAME=/dev/bus/usb/001/003 E: DEVNUM=003 E: DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-2 E: DEVTYPE=usb_device E: DRIVER=usb E: ID_BUS=usb E: ID_MODEL=Backup+_BL E: ID_MODEL_ENC=Backup+\x20BL E: ID_MODEL_FROM_DATABASE=Backup Plus E: ID_MODEL_ID=a003 E: ID_REVISION=0419 E: ID_SERIAL=Seagate_Backup+_BL_NA5BYJ3Y E: ID_SERIAL_SHORT=NA5BYJ3Y E: ID_USB_INTERFACES=:080650: E: ID_VENDOR=Seagate E: ID_VENDOdR_ENC=Seagate\x20 E: ID_VENDOR_FROM_DATABASE=Seagate RSS LLC E: ID_VENDOR_ID=0bc2 E: MAJOR=189 E: MINOR=2 E: PRODUCT=bc2/a003/419 E: SUBSYSTEM=usb E: TYPE=0/0/0 E: USEC_INITIALIZED=2821666176

P: /devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-2/1-2:1.0 E: DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-2/1-2:1.0 E: DEVTYPE=usb_interface E: DRIVER=usb-storage E: ID_MODEL_FROM_DATABASE=Backup Plus E: ID_VENDOR_FROM_DATABASE=Seagate RSS LLC E: INTERFACE=8/6/80 E: MODALIAS=usb:v0BC2pA003d0419dc00dsc00dp00ic08isc06ip50in00 E: PRODUCT=bc2/a003/419 E: SUBSYSTEM=usb E: TYPE=0/0/0 E: USEC_INITIALIZED=2821680372

но он есть в «subsystem» - «block»

P: /devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-2/1-2:1.0/host34/target34:0:0/34:0:0:0/block/sdc N: sdc S: disk/by-id/ata-ST1000LM024_HN-M101MBB_S2ZPJ9AD110729 S: disk/by-id/wwn-0x50004cf2095c8d88 S: disk/by-path/pci-0000:02:03.0-usb-0:2:1.0-scsi-0:0:0:0 E: DEVLINKS=/dev/disk/by-id/ata-ST1000LM024_HN-M101MBB_S2ZPJ9AD110729 /dev/disk/by-id/wwn-0x50004cf2095c8d88 /dev/disk/by-path/pci-0000:02:03.0-usb-0:2:1.0-scsi-0:0:0:0 E: DEVNAME=/dev/sdc E: DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-2/1-2:1.0/host34/target34:0:0/34:0:0:0/block/sdc E: DEVTYPE=disk E: ID_ATA=1 E: ID_ATA_DOWNLOAD_MICROCODE=1 E: ID_ATA_FEATURE_SET_AAM=1 E: ID_ATA_FEATURE_SET_AAM_CURRENT_VALUE=0 E: ID_ATA_FEATURE_SET_AAM_ENABLED=0 E: ID_ATA_FEATURE_SET_AAM_VENDOR_RECOMMENDED_VALUE=254 E: ID_ATA_FEATURE_SET_APM=1 E: ID_ATA_FEATURE_SET_APM_ENABLED=0 E: ID_ATA_FEATURE_SET_HPA=1 E: ID_ATA_FEATURE_SET_HPA_ENABLED=1 E: ID_ATA_FEATURE_SET_PM=1 E: ID_ATA_FEATURE_SET_PM_ENABLED=1 E: ID_ATA_FEATURE_SET_PUIS=1 E: ID_ATA_FEATURE_SET_PUIS_ENABLED=0 E: ID_ATA_FEATURE_SET_SECURITY=1 E: ID_ATA_FEATURE_SET_SECURITY_ENABLED=0 E: ID_ATA_FEATURE_SET_SECURITY_ENHANCED_ERASE_UNIT_MIN=208 E: ID_ATA_FEATURE_SET_SECURITY_ERASE_UNIT_MIN=208 E: ID_ATA_FEATURE_SET_SMART=1 E: ID_ATA_FEATURE_SET_SMART_ENABLED=1 E: ID_ATA_ROTATION_RATE_RPM=5400 E: ID_ATA_SATA=1 E: ID_ATA_SATA_SIGNAL_RATE_GEN1=1 E: ID_ATA_SATA_SIGNAL_RATE_GEN2=1 E: ID_ATA_WRITE_CACHE=1 E: ID_ATA_WRITE_CACHE_ENABLED=1 E: ID_BUS=ata E: ID_MODEL=ST1000LM024_HN-M101MBB E: ID_MODEL_ENC=ST1000LM024\x20HN-M101MBB\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20 E: ID_PART_TABLE_TYPE=dos E: ID_PART_TABLE_UUID=13b7b43e E: ID_PATH=pci-0000:02:03.0-usb-0:2:1.0-scsi-0:0:0:0 E: ID_PATH_TAG=pci-0000_02_03_0-usb-0_2_1_0-scsi-0_0_0_0 E: ID_REVISION=2AR20002 E: ID_SERIAL=ST1000LM024_HN-M101MBB_S2ZPJ9AD110729 E: ID_SERIAL_SHORT=S2ZPJ9AD110729 E: ID_TYPE=disk E: ID_WWN=0x50004cf2095c8d88 E: ID_WWN_WITH_EXTENSION=0x50004cf2095c8d88 E: MAJOR=8 E: MINOR=32 E: SUBSYSTEM=block E: TAGS=:systemd: E: USEC_INITIALIZED=2823299830

т.е можно конечно дергать оттуда, но как быть с устройствами типа телефона, которых нет в «block», для них создается запись только в «usb».

короче вопрос такой, как из «subsystem usb» выдрать путь к устройству, чтоб потом можно было его размониторовать/извлечь

возможно глупый вопрос, готовый код не надо, просто поможет любой совет, в какую сторону копать

спасибо.

п.с вроде спрятал все под спойлер, согласно разметке, и вставлял с переносом строк, но все равно все в куче

«безопасное извлечение» это для юсб-накопителей, а серийный номер может быть и у другого юсб-устройства.

будь человеком – исправь разметку!

anonymous ()
Ответ на: комментарий от anonymous

хм.. об этом я не подумал вы предлагаете использовать subsystem «block» и анализ «partition» или «disk»? дело в том, что это работает для моих внешних hdd и флешек, все хорошо, но когда я подключаю телефон в качестве флешки, его не видно, но видно, когда использую «usb» и «usb_device», не знаю, только ли с моим телефоном так будет происходить.

и при команде fdisk -l

телефон тоже не показывается.

follownow ()

и еще такой вопрос: я размонтирую флешку вызовом umount в коде, она размонтируется, но остается в системе, если на нее щелкнуть она опять же монтируется, но udev monitor это не отлавливает, он отлавливает только после этих команд:

udisksctl unmount --block-device /dev/sdb1
и потом:
udisksctl power-off --block-device /dev/sdb

реализации udisks api для c++ я чет не нашел, выходит на c++ это делается только с помощью консоли?

follownow ()
Ответ на: комментарий от follownow
Ответ на: комментарий от XMs

Если это не какой-то форензик-дистрибутив, то при подключении ФС автоматически монтируется, и ядро уже что-нибудь запишет. Может, ещё какие-то процессы в системе реагируют на монтирование ФС.

А ещё для жёстких дисков очень важная составляющая «безопасного» извлечения - это power-off. Иначе бывает слышен не очень приятный звук и +1 в «Power-Off_Retract_Count». Казалось бы, жёстким дискам уже очень давно как не нужна команда парковки перед выключением: они не дают головкам приземлиться посередине диска при выключении. Тем не менее отличия парковки при пропадании питания слышны даже невооружённым ухом.

gag ★★★★★ ()
Ответ на: комментарий от gag

А разве при размонтировании посылается команда на парковку головок? Ведь даже если все разделы отмонтированы, с диска всё ещё можно читать данные, да и писать тоже

XMs ★★★★★ ()
Ответ на: комментарий от XMs

Нет, поэтому с udisks2 после unmount нужно ещё дёрнуть power-off. А с gio mount (ранее gvfs-mount) можно отлючить диск вообще одним махом: gio mount -e file:///media/some-of-several-disk-partitions.

А вообще-то есть eject. Просто, лаконично и логично. Но в настройках Debian по-умолчанию он у меня давно перестал работать для внешних жёстких дисков (если не путаю, то прав не было, то он отключал диск, но тот тут же раскручивался снова), и я перестал проверять его работоспособность.

gag ★★★★★ ()
Ответ на: комментарий от follownow

обычно при подключении телефона/смартфона/планшета необходимо выбрать режим подключения. и насколько я помню, каждый производитель реализует этот сценарий как ему угодно. обычно самых популярных вариантов 2-3, но всегда можно нарваться на какую-либо «экзотику».

я ничего не предлагал, только обратил твоё внимание на некоторые малозаметные детали. скорее всего проверка в твоём коде будет не такой простой, как ты представлял.

у тебя телефон с андроидом подключается в режиме MTP (здесь могу ошибаться в деталях) – при этом он не является «классическим» дисковым накопителем/флешкой. моё пояснение слишком «научно-популярно». но ты можешь сам разобраться в этом вопросе.

anonymous ()

с безопасным извлечением вроде разобрался. в итоге сканирую «subsystem» «block» и «partition», все флешки и внешние hdd определяются отлично, но проблема с телефоном осталась. Udev на телефон реагирует только «subsystem» «usb» и «usb_device». получается такое:

P: /devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-2
N: bus/usb/001/005
E: BUSNUM=001
E: DEVNAME=/dev/bus/usb/001/005
E: DEVNUM=005
E: DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-2
E: DEVTYPE=usb_device
E: DRIVER=usb
E: ID_BUS=usb
E: ID_MODEL=H9436
E: ID_MODEL_ENC=H9436
E: ID_MODEL_ID=01ff
E: ID_REVISION=0409
E: ID_SERIAL=Sony_H9436_BH9709SQDR
E: ID_SERIAL_SHORT=BH9709SQDR
E: ID_USB_INTERFACES=:ffff00:
E: ID_VENDOR=Sony
E: ID_VENDOR_ENC=Sony
E: ID_VENDOR_FROM_DATABASE=Sony Ericsson Mobile Communications AB
E: ID_VENDOR_ID=0fce
E: MAJOR=189
E: MINOR=4
E: PRODUCT=fce/1ff/409
E: SUBSYSTEM=usb
E: TYPE=0/0/0
E: USEC_INITIALIZED=15608705240

P: /devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-2/1-2:1.0
E: DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-2/1-2:1.0
E: DEVTYPE=usb_interface
E: DRIVER=usbfs
E: ID_VENDOR_FROM_DATABASE=Sony Ericsson Mobile Communications AB
E: INTERFACE=255/255/0
E: MODALIAS=usb:v0FCEp01FFd0409dc00dsc00dp00icFFiscFFip00in00
E: PRODUCT=fce/1ff/409
E: SUBSYSTEM=usb
E: TYPE=0/0/0
E: USEC_INITIALIZED=15608713688

в дисковых устройствах телефон нигде не светится, подключается, как отдельный том, если его открыть в терминале, пишет такой путь:

/run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C005%5D$

такой вопрос, зная, что телефон висит на определенной шине, можно ли просто отключить ему питание, или это тупая идея?

еще размышления..все внешние hdd и флешки, при подключении в разделе usb показывают

ID_USB_INTERFACES=:080650:
у телефона же:
ID_USB_INTERFACES=:ffff00:
соответственно можно решить, что у всех телефонов так..или тоже херня(к сожалению под рукой больше нет телефона, чтоб проверить)?

follownow ()
Ответ на: комментарий от follownow

подключается, как отдельный том

Нет, никакого тома не создается. MTP – это просто протокол доступа к файлам, все операции atomic, т.к. доступ к файлам разделяется с хостом (т.е. с Androidом). Прямого доступа к ФС на телефоне MTP не предоставляет. Поэтому размонтировать тут просто нечего, кэшей нет.

От внезапного отключения usb кабеля ничего страшного не произойдет.

i586 ()