Почему мои правила udev работают, если я использую триггер udevadm, но НЕ во время начальной загрузки?

Я испытываю затруднения из-за правил udev, не работающих. Вот пример:

У меня есть правило /etc/udev/rules.d/99-test.rules который содержит:

ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x8086", RUN+="/sayhi"

И sayhi просто имеет:

#!/bin/bash
date +"%Y-%m-%d %H:%M:%S,%3N" >> /saidhi

Так как этот машина Intel, у меня, очевидно, есть много устройств 0x8086 PCI поставщика:

root@imtrobot:~# lspci -n |grep 8086
00:00.0 0600: 8086:2770 (rev 02)
00:02.0 0300: 8086:2772 (rev 02)
00:1d.0 0c03: 8086:27c8 (rev 01)
[ etc. 12 lines total ]

И все же, когда я загружаюсь, /saidhi не будет или создан вообще или будет иметь 1 или 2 линии перемены даты в нем.

Если после начальной загрузки я работаю udevadm trigger --action=add --subsystem-match=pci затем /saidhi получит точно правильное количество дат, добавленных к нему.

Почему это не работает во время процесса начальной загрузки?

7
задан 11 April 2014 в 16:47

3 ответа

У меня на самом деле есть путь, который будет ожидать просто правильное количество времени, не произвольные 30 секунд. Я сделал это на Raspberry Pi для автоматического монтирования всех связанных дисков USB после соединения, но также и на времени начальной загрузки.

правило подобно Вашему:

$ sudo cat /etc/udev/rules.d/10-usb_automount.rules 
KERNEL=="sd*", RUN+="/home/pi/bin/usb-automount"

Теперь сценарий является на самом деле рекурсивным вызовом (и я знаю, что это является злым):

$ cat /home/pi/bin/usb-automount
#!/bin/sh

ROOT_RW=`mount | grep 'dev/root' | grep -E '\(.*rw.*\)'`

if [ -z "$ROOT_RW" ]; then
 sleep 3 
 /home/pi/bin/usb-automount & disown
else
 /home/pi/bin/usb-automount.sh
fi

Примечание, которое "grep 'dev/root'" характерно для Raspbian ОС, таким образом, на Ubuntu необходимо будет разработать собственный grep для обнаружения rootfs (или еще лучший дизайн некоторый универсальный grep). Заметьте, что сценарий назовет себя в фоновом режиме и выйдет и только если rootfs является "rw", назовет правильный сценарий монтирования. Сценарий "/home/pi/bin/usb-automount.sh" делает фактическое монтирование или в Вашем случае вход.

Примечание этот сценарий все еще занимает 3 секунды для выполнения, таким образом, можно далее оптимизировать путем изменения на:

if [ -z "$ROOT_RW" ]; then
 ( sleep 3; /home/pi/bin/usb-automount ) & disown
else
 /home/pi/bin/usb-automount.sh
fi

Однако я никогда не проверял, что и не знают, будет ли это работать как ожидалось (я не гуру сценариев).

1
ответ дан 17 November 2019 в 04:06

Я преподавал той же причины, как @dmd, PCI uevents прибывает перед файловой системой повторно монтируются как rw. (Но иногда, часть PCI uevents прибывает после, состояние состязания, работая параллельно)

dmesg | grep -i -e mount -e pci

, идея @Sparhawk sleep кажется хорошей мне. Я думаю это, почему это не работает (Касательно: man udev):

Это может только использоваться для очень коротко рабочих приоритетных задач. Выполнение обработки события в течение длительного периода времени может заблокировать все дальнейшие события для этого или зависимого устройства.

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

Так, я создал новый сценарий, которые запускают & disown сценарий, который имеет sleep команда. На самом деле Это действительно РАБОТАЕТ!

$ ls -l /sa*
-rw-r--r-- 1 root root 1104 Oct 24 12:37 /saidhi
-rwxr-xr-x 1 root root   29 Oct 24 12:31 /sayhi
-rwxr-xr-x 1 root root   62 Oct 24 12:28 /sayhi2

$ cat /sayhi
#!/bin/bash
/sayhi2 & disown

$ cat /sayhi2 
#!/bin/bash
sleep 30
date +"%Y-%m-%d %H:%M:%S,%3N" >> /saidhi

$ cat /etc/udev/rules.d/99-test.rules 
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x8086", RUN+="/sayhi"
0
ответ дан 17 November 2019 в 04:06

Как упомянуто другими, процессы, запущенные udev RUN= директива должна быть коротким выполнением. Я хотел бы предложить другой более простой способ отделить продолжительный процесс от udev при помощи системного планировщика at команда:

ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x8086", RUN+="/usr/bin/at -M -f /sayhi now"

Просто удостоверьтесь что Ваш /sayhi сценарий /bin/sh совместимый - это - оболочка это at использование.

1
ответ дан 23 November 2019 в 06:54

Другие вопросы по тегам:

Похожие вопросы: