1

Добрре всем воемя суток!
Вот начал программировать под Linux, нужна ваша помощь.

Нужно написать программку которая бы смотрела USB и если находило совпадение (по виду пиду) то ОС работала бы дальше, а если не нашло то перегружала систему.
Вот у меня счас есть пару впоросов.
Как используя С++ получить инфу о USB?
Из консоли получить инфу о USB можно различными спосабами, lsusb... можно ли использовать команды консоли в С++ програмке и как?



Большое спасибо!

П.С. если можно то с маленькими примерчиками!

2

Поковыряйте V-USB. Хоть она и предназначена для работы с микроконтроллерами AVR, думаю, это вам поможет.

Истинный hotplug - это обычная электрическая розетка: воткнул - работает, и никаких драйверов.
Arch Linux/Xfce/Xiaomi Mi Notebook Pro 15.6 | Slackware64-current/Xfce/Lenovo G580

3

спасибо, но может я не совсем правильно пояснил суть, попробую пояснить

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

4

ИМХО, тут даже программа - излишек. Есть такая вещь в системе - udev. Пишете правило, из которого запускается reboot. Главное, чтобы вашу флешку можно было однозначно идентифицировать, а с комбинацией VID/PID, насколько я понимаю, можно промахнуться...

Истинный hotplug - это обычная электрическая розетка: воткнул - работает, и никаких драйверов.
Arch Linux/Xfce/Xiaomi Mi Notebook Pro 15.6 | Slackware64-current/Xfce/Lenovo G580

5

спасибо!! счас будем пробовать)

6

Автомонтирование USB-устройств

KERNEL!="sd[a-z][0-9]", GOTO="auto_mount_end"

IMPORT{program}="/sbin/blkid -o udev -p %N"
ENV{ID_FS_LABEL}!="", ENV{dir_name}="%E{ID_FS_LABEL}"
ENV{ID_FS_LABEL}=="", ENV{dir_name}="usbhd-%k"

ACTION=="add", RUN+="/bin/mkdir -p /media/%E{dir_name}", RUN+="/bin/mount -t auto -o rw,relatime,noexec,nodev,utf8 
/dev/%k /media/%E{dir_name}"

ACTION=="remove", ENV{dir_name}!="", RUN+="/bin/umount -l /media/%E{dir_name}", RUN+="/bin/rmdir /media/%E{dir_name}"

LABEL="auto_mount_end"

Вот эта строка - правило для извличения, розмотирования (как я понимаю)

ACTION=="remove", ENV{dir_name}!="", RUN+="/bin/umount -l /media/%E{dir_name}", RUN+="/bin/rmdir /media/%E{dir_name}"

в моем случае в  RUN+="" добавить путь к файлу в котором команда перезагрузки? подскажите...
не работал с udev((

7

Fogord пишет:

Как используя С++ получить инфу о USB?

смотрите в сторону libusb. как пример можно использовать тот же lsusb.
и в линуксе основной язык - Си.

Fogord пишет:

Из консоли получить инфу о USB можно различными спосабами, lsusb... можно ли использовать команды консоли в С++ програмке и как?

man 3 exec; иногда man 3 system.
Но ИМХО это не правильный путь. проще самому покопаться в исходниках и вытянуть нужные части, чем парсить вывод. и париться с обёртками процесса.
ЗЫ: с udev ИМХО верное решение.

Fogord пишет:

в моем случае в  RUN+="" добавить путь к файлу в котором команда перезагрузки?

в общем да. ещё надо убрать ENV{dir_name}!="" - защита, позволяющая отмонтировать так только диски, которые udev и смонтировала.
только нужно ещё будет придумать какую-то проверку, что это именно та флешка.

ЗЫ: пользуйтесь тегом code

95% процентов проблем находятся между клавиатурой и стулом.

8

создал файл /etc/udev/rules.d/10-udev-my.rules в котором написал

BUS=="usb", SUBSYSTEM=="block", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="14ad", KERNEL=="sd*", ACTION=="remove", RUN+="/etc/udev/scripts/udev-myflash-mount remove %k"


/etc/udev/scripts/udev-myflash-mount создал скрипт

#!/bin/bash

LOG="/var/log/udev"
 
sleep 3
if [ "$1" = "remove" ]; then
  if [ "$DEV" != "" ]; then
    echo "--- `date` ---" >> $LOG
    echo "Unmounting /dev/$DEV" >> $LOG
    umount /dev/$DEV >> $LOG 2>&1
    rm -rf /mnt/$DEV >> $LOG 2>&1
    echo b > /proc/sysrq-trigger 
  fi
fi

что то мне кажется что я не так это все делаю(

9

Fogord, сдаётся мне, что не хватает DEV=$2.

Fogord пишет:

    echo b > /proc/sysrq-trigger

ИМХО лучше перезагружать цивилизованно, через reboot.

ЗЫ: покажите руководство, которым пользуетесь
ЗЗЫ: собственно отмонтирование выполнять необязательно.
ЗЗЗЫ: скрипт лучше переименовать во что-то соответствующее его действиям.

95% процентов проблем находятся между клавиатурой и стулом.

10 (10.04.2012 16:49:19 отредактировано Fogord)

пользуюсь эти руководством

http://ru.gentoo-wiki.com/wiki/HOWTO_Ud … 0%B5%D0%B9

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

названия подправлю...

без размонтирования:

#!/bin/bash

LOG="/var/log/udev"

sleep 3

DEV=`echo $2 | sed -n '/^sd[a-z][1-9]\?/p'`

if [ "$1" == "remove" ]; then
     echo b > /proc/sysrq-trigger 
fi
DEV=`echo $2 | sed -n '/^sd[a-z][1-9]\?/p'`

- зачем эта строчка не могу понять, но скорей всего ее и не хватает

11

Fogord пишет:

DEV=`echo $2 | sed -n '/^sd[a-z][1-9]\?/p'`

ана пропускает только строки, содержащие соответствующий регэксп, иначе строка опустошается.
для начала достаточно просто DEV=$2.

ЗЫ: если не работает, то добавьте отладочную печать...

95% процентов проблем находятся между клавиатурой и стулом.

12

поробывал вывести отладочную информацию... не выводит
код сейчас такой:
правило с именем 00remove.rules

BUS=="usb", KERNEL=="sd", SUBSYSTEM=="block", ATTRS{idVendor}=="8644", ATTRS{idProduct}=="800b", ACTION=="remove", RUN+="etc/udev/scripts/udev-myflash-mount remove %k"

idV, idP взял с помошью "lsusb"

скрипт быт сделан исполняемым

chmod u+x /etc/udev/scripts/udev-myflash-mount remove

сам скрипт вот

#!/bin/bash
LOG="/var/log/udev/log.log"
echo $1 >> $LOG
sleep 3
DEV=$2
if [ "$1" == "remove" ]; then
     echo b > /proc/sysrq-trigger 
fi

/var/log/udev/log.log - пусто

гляньте своим опытным глазом)))

13 (11.04.2012 07:42:59 отредактировано bormant)

... RUN+="etc/ ...
пропущен /:
... RUN+="/etc/ ...

В вашем варианте скрипт мог быть вызван, только если текущим каталогом процесса udev (или кто там отрабатывает скрипты) являлся корень "/" (и только при условии, если относительные пути не запрещены в коде в целях безопасности).

14

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

15 (11.04.2012 11:07:38 отредактировано bormant)

# udevadm monitor
показывает само наличие события с желанными параметрами?
Что не получается?
Скрипт вызывается?

16 (11.04.2012 11:26:30 отредактировано bormant)

Fogord пишет:

программку которая бы смотрела USB и если находило совпадение (по виду пиду) то ОС работала бы дальше, а если не нашло то перегружала систему

#!/bin/bash
VID=8644
PID=800b
while ((1)); do
    if ! /usr/bin/lsusb | /usr/bin/grep "ID $VID:$PID" &> /dev/null
    then /sbin/reboot
    fi
    sleep 30s
done

;-D

17

вот что мониторится

monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent

KERNEL[1334099582.859273] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0/host6/target6:0:0/6:0:0:0/bsg/6:0:0:0 (bsg)
KERNEL[1334099582.859329] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0/host6/target6:0:0/6:0:0:0/scsi_device/6:0:0:0 (scsi_device)
KERNEL[1334099582.859341] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0/host6/target6:0:0/6:0:0:0/scsi_disk/6:0:0:0 (scsi_disk)
KERNEL[1334099582.859350] remove   /devices/virtual/bdi/8:16 (bdi)
KERNEL[1334099582.859362] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0/host6/target6:0:0/6:0:0:0/block/sdb (block)
KERNEL[1334099582.859373] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0/host6/target6:0:0/6:0:0:0 (scsi)
KERNEL[1334099582.859382] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0/host6/target6:0:0 (scsi)
KERNEL[1334099582.859391] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0/host6/scsi_host/host6 (scsi_host)
KERNEL[1334099582.859399] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0/host6 (scsi)
KERNEL[1334099582.860604] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0 (usb)
KERNEL[1334099582.860619] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/usb_device/usbdev1.7 (usb_device)
KERNEL[1334099582.860638] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2 (usb)
UDEV  [1334099582.863685] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0/host6/target6:0:0/6:0:0:0/scsi_device/6:0:0:0 (scsi_device)
UDEV  [1334099582.866179] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0/host6/target6:0:0/6:0:0:0/bsg/6:0:0:0 (bsg)
UDEV  [1334099582.868427] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/usb_device/usbdev1.7 (usb_device)
UDEV  [1334099582.870144] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0/host6/scsi_host/host6 (scsi_host)
UDEV  [1334099582.870660] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0/host6/target6:0:0/6:0:0:0/block/sdb (block)
UDEV  [1334099582.871176] remove   /devices/virtual/bdi/8:16 (bdi)
UDEV  [1334099582.871686] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0/host6/target6:0:0/6:0:0:0/scsi_disk/6:0:0:0 (scsi_disk)
UDEV  [1334099582.873250] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0/host6/target6:0:0/6:0:0:0 (scsi)
UDEV  [1334099582.874872] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0/host6/target6:0:0 (scsi)
UDEV  [1334099582.876394] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0/host6 (scsi)
UDEV  [1334099582.879153] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0 (usb)
UDEV  [1334099582.882123] remove   /devices/pci0000:00/0000:00:06.0/usb1/1-2 (usb)

счас ваш скрипт попробую )

18

Fogord пишет:

счас ваш скрипт попробую

А ваше устройство в выводе lsusb присутствует в виде

# lsusb
... ID 8644:800b ...

?

19 (11.04.2012 17:27:42 отредактировано Fogord)

на работе с другой флешкой работаю...

... ID 1307:0165 ...

что то совсем без реакции, проблема может быть в том что я через виртуалку работаю? (мало возможно)

есть еще у кого идеи?

20

возможно я не там пишу правило или скрипт?
или как можно узнать какое правило обрабатывается перед моим?

что то меня все идеи покинули ((

21

Fogord пишет:

или как можно узнать какое правило обрабатывается перед моим?

В выводе команды

udevadm test $(udevadm info -q path -n /dev/sdc)

где /dev/sdc ваше устройство, можно найти вызов соответствующих правил.

Был, был и весь вышел...

22

попробовал команду, были ошибки связные с BUS и NAME поправил...теперь пишет

parse_file: reading '/etc/udev/rules.d/00-1remove.rules' as rules file

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

23

А скрипт сам по себе отрабатывает, как нужно?

Был, был и весь вышел...

24

#!/bin/bash

LOG=$"/var/log/udev/log.log"
echo "--- `date` ---" >> $LOG
sleep 3
  
DEV=`echo $2 | sed -n '/^sd[a-z][1-9]\?/p'`
if [ "$1" = "add" ]; then
  if [ "$DEV" != "" ]; then
    echo "--- `date` ---" >> $LOG
    echo "Mounting /dev/$DEV" >> $LOG
    mkdir /mnt/$DEV >> $LOG 2>&1
    chmod a+rwx /mnt/$DEV >> $LOG 2>&1
    mount /dev/$DEV /mnt/$DEV -o sync,umask=0000,iocharset=cp1251 >> $LOG 2>&1
  fi
elif [ "$1" = "remove" ]; then
  if [ "$DEV" != "" ]; then
    echo "--- `date` ---" >> $LOG
    echo "Unmounting /dev/$DEV" >> $LOG
    umount /dev/$DEV >> $LOG 2>&1
    rm -rf /mnt/$DEV >> $LOG 2>&1
  fi
fi

выодит дату только

echo "--- `date` ---" >> $LOG

это мне говорит хотя бы о том что при отбавлении устройства правило работает и переходит в скрипт

25

Fogord пишет:

LOG=$"/var/log/udev/log.log"

$ — лишнее.
В предыдущем сообщении просто тестовый скрипт или рабочий аналог?
Покажите полностью правило udev, с помощью которого должен запускаться скрипт.

Был, был и весь вышел...

26 (11.04.2012 20:09:35 отредактировано Fogord)

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

сейчас все поркажу

27 (11.04.2012 20:13:33 отредактировано bormant)

Что касается поллинга (постоянного дёрганья lsusb), не совсем желательный вариант, но:
1) в скрипте поменять VID и PID на свои, которые видны в виртуалке или где там тестируете.
2) возможно великоват интервал в 30 сек.

Что касается перезагрузки правил udev-а:
# udevadm control --reload-rules

По моим наблюдениям (udev-165) при ACTION=="remove" проверки ATTR{}== и ATTRS{}== не срабатывают, такое ощущение, что к этому моменту атрибутов уже нет.
У кого другие наблюдения, делитесь, не забыв сообщить версию udev и правило.
Возможно, есть обходной манёвр с сохранением на ACTION=="add", ATTR{serial}=="серийник" какого-то уникального параметра, ещё доступного при ACTION=="remove", а при удалении проверять это сохранённое значение. Надо этот вопрос поисследовать.

28 (11.04.2012 23:21:42 отредактировано Fogord)

правило

#First rule
SUBSYSTEMS=="usb", SUBSYSTEM=="block", KERNEL=="sd*", ACTION=="add", ATTRS{idVendor}=="1307", ATTRS{idProduct}=="0165", RUN+="/etc/udev/scripts/udev-myflash-mount add %k"
#Second rule
SUBSYSTEMS=="usb", SUBSYSTEM=="block", KERNEL=="sd*", ACTION=="remove", ATTRS{idVendor}=="1307", ATTRS{idProduct}=="0165", RUN+="/etc/udev/scripts/udev-myflash-mount remove %k"

скрипт

#!/bin/bash


LOG="/var/log/udev/log.log"
echo "---+---" >> $LOG


DEV=$2

if [ "$1" == "add" ]; then
    if ["$DEV" != ""]; then
     echo "--- `date` ---" >> $LOG
     echo "Mounting " >> $LOG
     echo "Mounting /dev/$DEV" >> $LOG
     mkdir /mnt/$DEV >> $LOG 2>&1
     chmod a+rwx /mnt/$DEV >> $LOG 2>&1
     mount /dev/$DEV mnt/$DEV -o sync,umask=0000,iocharset=cp1251 >> $LOG 2>&1
    fi
elif [ "$1" == "remove" ]; then
    if ["$DEV" != ""]; then
     echo "--- `date` ---" >> $LOG
     echo "Remov ">> $LOG
     echo "Remov /dev/$DEV" >> $LOG
     echo b > /proc/sysrq-trigger 
    fi
fi

по мои наблюдением при ACTION=="remove" проверки ATTR{}== и ATTRS{}== не срабатывают тоже(

з.ы.сейчас домой доберусь буду побывать дальше

29

правило работает на "add"

скрипт написал так

!/bin/bash
LOG="/var/log/udev/log.log"
echo "$1" >> $LOG
sleep 2
DEV=$2

if [ "$1" == "add" ]; then
   echo "Mounting " >> $LOG
    if ["$DEV" != ""]; then
     echo "--- `date` ---" >> $LOG
     echo "Mounting /dev/$DEV" >> $LOG
     mkdir /mnt/$DEV >> $LOG 2>&1
     chmod a+rwx /mnt/$DEV >> $LOG 2>&1
     mount /dev/$DEV mnt/$DEV -o sync,umask=0000,iocharset=cp1251 >> $LOG 2>&1
    fi
elif [ "$1" == "remove" ]; then
    echo "Remov ">> $LOG
    if ["$DEV" != ""]; then
     echo "--- `date` ---" >> $LOG
     echo "Remov /dev/$DEV" >> $LOG
     echo b > /proc/sysrq-trigger 
    fi
fi

что дает мне возможность видеть до куда доходит скрипт, но дальше чем первое условие он не уходит

в log.log

add
Mounting 

"Remov" совсем не выполняеться, "$1" не передаеться, потому как работает другое правило, но какое еще не нашел
в rules.d куча правил, счас попробую оставить только свое

30

написал такой скрипт

#!/bin/bash
LOG="/var/log/udev/log.log"
echo "$1" >> $LOG
VID=1307
PID=0165
sleep 3
DEV=$2
if [ "$1" == "add" ]; then
   echo "Mounting" >> $LOG
fi
   while ((1));
        do
                if
                        /user/bin/grep "$VID:$PID" /user/bin/lsusb
                then
                        echo "Find USB" >> $LOG
                else
                        /sbin/reboot
                fi
        done

теперь PC перегружаеться когда флешку вставляю