Почему запускаются мои правила 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, у меня, очевидно, есть много PCI-устройств 0x8086:
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
получите правильное количество дат, добавленных к нему.
Почему это не работает во время процесса загрузки?
3 ответа
Как уже упоминалось, процессы, начатые udev
"s RUN=
Директива должна быть кратковременной. Я хотел бы предложить еще один более простой способ отделить длительный процесс от udev
с помощью системного планировщика at
команда:
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x8086", RUN+="/usr/bin/at -M -f /sayhi now"
Просто убедитесь, что ваш /sayhi
сценарий /bin/sh
совместимый - это оболочка, которая at
использует.
У меня действительно есть способ, который будет ждать нужное количество времени, а не произвольные 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 OS, поэтому в 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-события происходят до того, как файловая система перемонтируется как rw
, (Но иногда некоторые из событий PCI наступают после состояния гонки, работающего параллельно)
dmesg | grep -i -e mount -e pci
@Sparhawk sleep
Идея мне кажется хорошей. Я думаю, что это почему-то не работает (Ref: 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"