Debian

udev 沒有區域網路訪問權限?

  • February 22, 2022

我正在使用 Raspbian (Bullseye)、Logitech Media Server (LMS) 8.2.0 和 Squeezelite 1.9.9 執行 RPi 4b。為了在連接某個 USB 設備時自動啟動 Squeezelite 程序,我定義了以下udev規則:

SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="154e/300a/3", RUN+="/usr/bin/DAC_start.sh"
SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="154e/300a/3", RUN+="/usr/bin/DAC_stop.sh"

這是我的DAC_start.sh腳本:

#!/bin/sh
######### DAC_start.sh #########
date >> /tmp/udev.log
echo "Starting Squeezelite" >> /tmp/udev.log
sleep 5s
/usr/bin/squeezelite -o hw:CARD=ND8006,DEV=0 -D -n MediaPlayer -d all=debug -f /tmp/sq.log | at now
###############################

這是我的DAC_stop.sh腳本:

#!/bin/sh
######### DAC_stop.sh #########
date >> /tmp/udev.log
echo "Stopping Squeezelite ..." >> /tmp/udev.log
pkill squeezelite
###############################

當我手動執行它們時(作為 pi 和 root),這兩個腳本都可以正常工作:Squeezelite 成功連接到 LMS 和 USB 設備,可以播放音樂。udev當我連接我的 USB DAC(我可以從日誌文件中看到)時,這些規則也會起作用並被觸發。但是,當squeezelite 啟動時udev,squeezelite 似乎無法連接到我在同一區域網路上的LMS 伺服器,實際上是在同一台機器上。這是 Squeezelite 日誌文件(我認為更重要的消息位於最底部,但我複制了所有消息以方便您查看,以防我忽略某些內容):

/usr/bin/squeezelite -o hw:CARD=ND8006,DEV=0 -D -n MediaPlayer -d all=debug -f /tmp/sq.log
[16:22:50.362611] stream_init:454 init stream
[16:22:50.362971] stream_init:455 streambuf size: 2097152
[16:22:50.376806] output_init_alsa:936 init output
[16:22:50.377007] output_init_alsa:976 requested alsa_buffer: 40 alsa_period: 4 format: any mmap: 1
[16:22:50.377081] output_init_common:360 outputbuf size: 3528000
[16:22:50.377333] output_init_common:384 idle timeout: 0
[16:22:50.410804] test_open:301 sample rate 1536000 not supported
[16:22:50.410907] test_open:301 sample rate 1411200 not supported
[16:22:50.411049] test_open:301 sample rate 32000 not supported
[16:22:50.411085] test_open:301 sample rate 24000 not supported
[16:22:50.411118] test_open:301 sample rate 22500 not supported
[16:22:50.411151] test_open:301 sample rate 16000 not supported
[16:22:50.411184] test_open:301 sample rate 12000 not supported
[16:22:50.411216] test_open:301 sample rate 11025 not supported
[16:22:50.411249] test_open:301 sample rate 8000 not supported
[16:22:50.411330] output_init_common:426 supported rates: 768000 705600 384000 352800 192000 176400 96000 88200 48000 44100
[16:22:50.500287] output_init_alsa:1002 memory locked
[16:22:50.500456] output_init_alsa:1008 glibc detected using mallopt
[16:22:50.501072] output_init_alsa:1026 unable to set output sched fifo: Operation not permitted
[16:22:50.501080] output_thread:685 open output device: hw:CARD=ND8006,DEV=0
[16:22:50.501156] decode_init:153 init decode
[16:22:50.502046] alsa_open:354 opening device at: 44100
[16:22:50.502132] register_dsd:908 using dsd to decode dsf,dff
[16:22:50.502166] register_alac:549 using alac to decode alc
[16:22:50.502198] register_faad:663 using faad to decode aac
[16:22:50.502229] register_vorbis:385 using vorbis to decode ogg
[16:22:50.502325] register_opus:328 using opus to decode ops
[16:22:50.502361] register_flac:336 using flac to decode ogf,flc
[16:22:50.502392] register_pcm:483 using pcm to decode aif,pcm
[16:22:50.502433] register_mad:423 using mad to decode mp3
[16:22:50.502463] decode_init:194 include codecs:  exclude codecs:
[16:22:50.503117] alsa_open:425 opened device hw:CARD=ND8006,DEV=0 using format: S32_LE sample rate: 44100 mmap: 1
[16:22:50.503159] discover_server:795 sending discovery
[16:22:50.503272] alsa_open:516 buffer: 40 period: 4 -> buffer size: 1764 period size: 441
[16:22:50.503349] discover_server:799 error sending disovery
[16:22:55.504955] discover_server:795 sending discovery
[16:22:55.505246] discover_server:799 error sending disovery
[16:23:00.510091] discover_server:795 sending discovery
[16:23:00.510360] discover_server:799 error sending disovery
[16:23:05.515053] discover_server:795 sending discovery
[16:23:05.515329] discover_server:799 error sending disovery
[16:23:10.519882] discover_server:795 sending discovery
[16:23:10.520185] discover_server:799 error sending disovery
[16:23:15.528387] discover_server:795 sending discovery
[16:23:15.528659] discover_server:799 error sending disovery
[16:23:20.535819] discover_server:795 sending discovery
[16:23:20.536007] discover_server:799 error sending disovery
[16:23:25.541079] discover_server:795 sending discovery
[16:23:25.541333] discover_server:799 error sending disovery
[16:23:30.549470] discover_server:795 sending discovery
[16:23:30.549640] discover_server:799 error sending disovery
[16:23:35.559568] discover_server:795 sending discovery
[16:23:35.559857] discover_server:799 error sending disovery
[16:23:40.568356] discover_server:795 sending discovery
[16:23:40.568646] discover_server:799 error sending disovery
[16:23:45.576730] discover_server:795 sending discovery
[16:23:45.577009] discover_server:799 error sending disovery
[16:23:50.586202] discover_server:795 sending discovery
[16:23:50.586502] discover_server:799 error sending disovery
[16:23:55.596574] discover_server:795 sending discovery
[16:23:55.596872] discover_server:799 error sending disovery
[16:24:00.604989] discover_server:795 sending discovery
[16:24:00.605269] discover_server:799 error sending disovery
[16:24:05.615978] discover_server:795 sending discovery
[16:24:05.616278] discover_server:799 error sending disovery
[16:24:10.625168] discover_server:795 sending discovery
[16:24:10.625472] discover_server:799 error sending disovery
[16:24:15.633952] discover_server:795 sending discovery
[16:24:15.634246] discover_server:799 error sending disovery
[16:24:20.642357] discover_server:795 sending discovery
[16:24:20.642648] discover_server:799 error sending disovery
[16:24:25.650821] discover_server:795 sending discovery
[16:24:25.651113] discover_server:799 error sending disovery
[16:24:30.662745] discover_server:795 sending discovery
[16:24:30.663055] discover_server:799 error sending disovery
[16:24:35.670289] discover_server:795 sending discovery
[16:24:35.670566] discover_server:799 error sending disovery
[16:24:40.674134] discover_server:795 sending discovery
[16:24:40.674460] discover_server:799 error sending disovery
[16:24:45.679650] discover_server:795 sending discovery
[16:24:45.679984] discover_server:799 error sending disovery
[16:24:50.689070] discover_server:795 sending discovery
[16:24:50.689366] discover_server:799 error sending disovery
[16:24:55.697415] discover_server:795 sending discovery
[16:24:55.697709] discover_server:799 error sending disovery
[16:25:00.705845] discover_server:795 sending discovery
[16:25:00.706128] discover_server:799 error sending disovery
[16:25:05.714279] discover_server:795 sending discovery
[16:25:05.714583] discover_server:799 error sending disovery
[16:25:10.723306] discover_server:795 sending discovery
[16:25:10.723601] discover_server:799 error sending disovery
[16:25:15.728709] discover_server:795 sending discovery
[16:25:15.728977] discover_server:799 error sending disovery

似乎 Squeezelite 在由 啟動時udev無法訪問 LAN?-s 192.168.1.20我還嘗試使用參數(這是我的 LMS 的 IP)啟動 Squeezelite——但沒有成功。它仍然無法連接到 LMS 伺服器。任何想法我做錯了什麼?

我在帶有 piCore OS(這是一個 Tiny Core Linux 發行版)的 RPi 上使用了上面描述的方法,它就像一個魅力……

正如@dirkt 已經建議的那樣,將 Squeezeliteudev作為一個程序啟動並不是一個好主意:LAN 訪問在udev某種程度上受到限制,並且該程序無論如何都會在一段時間後被終止。這是將 Squeezelite 作為服務啟動的首選方式。

為此,udev需要定義如下規則:

# cat /etc/udev/rules.d/50-DAC.rules
SUBSYSTEM=="usb", ACTION=="bind", ENV{PRODUCT}=="154e/300a/3", TAG+="systemd", ENV{SYSTEMD_WANTS}="DAC_sql_start.service"
SUBSYSTEM=="usb", ACTION=="unbind", ENV{PRODUCT}=="154e/300a/3", TAG+="systemd", ENV{SYSTEMD_WANTS}="DAC_sql_stop.service"

請注意,我使用了bind相應的。unbindUSB 設備的操作(在我的情況下)被證明比add相應的更強大。remove. 另外,我不得不把它放在ENV{...}一個SYSTEMD_WANTS我不明白的原因……

對應的服務需要定義如下:

# cat /lib/systemd/system/DAC_sql_start.service
[Unit]
Description=Squeezelite by DAC script (start)

[Service]
ExecStart=/usr/bin/DAC_sql.sh start
# cat /lib/systemd/system/DAC_sql_stop.service
[Unit]
Description=Squeezelite by DAC script (stop)

[Service]
ExecStart=/usr/bin/DAC_sql.sh stop

我修改了shell腳本DAC_sql.sh如下:

# cat /usr/bin/DAC_sql.sh
#!/bin/sh
######### DAC_sql.sh #########
#sleep 5s
case $1 in
   "start")
       #date >> /tmp/DAC.log
       #echo "Starting Squeezelite..." >> /tmp/DAC.log
       /usr/bin/squeezelite -o hw:CARD=ND8006,DEV=0 -s 127.0.0.1 -D -n MediaPlayer #-d all=debug -f /tmp/sq.log;;
       ;;
   "stop")
       #date >> /tmp/DAC.log
       #echo "Stopping Squeezelite..." >> /tmp/DAC.log
       systemctl stop DAC_sql_start
       ;;
esac
##############################

它現在按預期工作:只要打開 USB 設備(綁定到系統),Squeezelite 就會作為服務啟動。當 USB 設備關閉(與系統解除綁定)時,Squeezelite 服務將停止。

來自man udev

執行{類型}

$$ … $$ 在處理特定事件的所有規則後,將程序添加到要執行的程序列表中,具體取決於類型:

這只能用於執行時間很短的前台任務。長時間執行事件程序可能會阻止此設備或從屬設備的所有進一步事件。

udev 不適合啟動守護程序或其他長時間執行的程序;事件處理完成後,分叉的程序,無論是否分離,都將被無條件終止。

因此,即使您可以讓它訪問 LAN(這可能很困難,由 udev 執行的程序處於有限的環境中),它也不是啟動和停止類似 Squeezelite 的正確方法。

嘗試例如this answer中的systemd服務。

引用自:https://unix.stackexchange.com/questions/690474