Я испытываю затруднения из-за правил 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
получит точно правильное количество дат, добавленных к нему.
Почему это не работает во время процесса начальной загрузки?
У меня на самом деле есть путь, который будет ожидать просто правильное количество времени, не произвольные 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
Однако я никогда не проверял, что и не знают, будет ли это работать как ожидалось (я не гуру сценариев).
Я преподавал той же причины, как @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"
Как упомянуто другими, процессы, запущенные udev
RUN=
директива должна быть коротким выполнением. Я хотел бы предложить другой более простой способ отделить продолжительный процесс от udev
при помощи системного планировщика at
команда:
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x8086", RUN+="/usr/bin/at -M -f /sayhi now"
Просто удостоверьтесь что Ваш /sayhi
сценарий /bin/sh
совместимый - это - оболочка это at
использование.