การเมานต์จะไม่ถูกเรียกใช้งานเมื่อถูกเรียกโดย udev


17

ฉันพยายามสร้างกฎ udev เพื่อเมานต์และยกเลิกการต่อเชื่อมแฟลชไดรฟ์ USB ของฉัน กฎสำหรับช่วงเวลานั้นง่ายมาก:

ACTION=="add",KERNEL=="sd[b-z]",RUN+="/root/scripts/plug_flash_drive.sh %k"
ACTION=="remove",KERNEL=="sd[b-z]",RUN+="/root/scripts/unplug_flash_drive.sh %k"

plug_flash_drive.sh นั้นง่ายมาก:

device_name=$1
mount_options="umask=000,utf8"
if [ ! -e "/media/$device_name" ]; then
    mkdir "/media/$device_name"
fi
sleep 1
/usr/bin/mount "/dev/$device_name" "/media/$device_name" -o "$mount_options"

unplug_flash_drive.sh:

device_name=$1

umount "/dev/$device_name"
rmdir "/media/$device_name"

ฉันได้ทำการทดสอบบางอย่างเพื่อให้แน่ใจได้ว่า:

  • เมื่อเสียบปลั๊กแฟลชไดรฟ์ของฉันจะตรวจจับ ไฟล์ถูกสร้างขึ้นใน / dev
  • plug_flash_drive.sh ถูกเรียกโดย udev
  • ส่วน mkdir ของสคริปต์ทำงาน
  • อย่างไรก็ตามดูเหมือนว่าส่วน "เมานท์" ของสคริปต์จะไม่ถูกเรียกใช้งานดังนั้นไดรฟ์ของฉันจึงไม่ถูกเมานต์
  • เมื่อฉันเรียกสคริปต์ของฉันบนบรรทัดคำสั่งพวกเขาทำงานได้อย่างสมบูรณ์

ไม่มีใครรู้ว่าทำไมการติดตั้งไม่ได้ถูกเรียกใช้เมื่อเรียกโดย udev

แก้ไข 28/08/14: ฉันเพิ่ม "grep -q / proc / mounts && echo success || echo failure" ที่ท้ายสคริปต์ของฉันเพื่อตรวจสอบในบันทึกการแก้ไขข้อบกพร่องของฉันหากอุปกรณ์ถูกติดตั้งจริงก่อนที่สคริปต์จะจบลง ปรากฏว่ามีการติดตั้งอุปกรณ์ณ จุดนั้นแม้ว่าจะมีการเรียกใช้สคริปต์โดย udev ดังนั้นปัญหาที่แท้จริงคือตอนนี้ "อุปกรณ์บล็อกของฉันดูเหมือนจะไม่ได้ต่อเชื่อมหลังจากสคริปต์ mount สิ้นสุดเมื่อเรียกผ่าน udev": s


นี้อาจจะเป็นข้างจุด แต่ทำไมคุณทำmkdir "$mount_dir"แต่rmdir "/media/$device_name"? $mount_dirตั้งอยู่ที่ไหน
G-Man กล่าวว่า 'Reinstate Monica'

ขอโทษนี่เป็นตัวพิมพ์ดีดฉันใช้ตัวแปรนามแฝงที่ไร้ประโยชน์บางอย่างในรหัสต้นฉบับและฉันลบพวกเขาที่นี่เพื่อประโยชน์ของความชัดเจน
magva

คุณได้ลองการดีบักแบบเก่าแล้วหรือยัง เช่นโดยการวางset -xvและexec >> "$HOME"/mount.log 2>&1เข้าไปใน.shไฟล์?
G-Man กล่าวว่า 'Reinstate Monica'

1
ฉันทำอย่างนั้น แต่ตามบันทึกที่ฉันได้รับเมาต์จะถูกเรียกใช้งานเมื่อสคริปต์ถูกเรียกโดย udev ไม่มีความแตกต่างในบันทึกระหว่างการโทรจาก udev และจาก command line ... ที่จริงแล้วค่อนข้างยุ่งเหยิง
magva

1
ในกรณีนั้นสคริปต์จะล้มเหลวเมื่อเรียกใช้จากบรรทัดคำสั่ง
magva

คำตอบ:


22

systemd-udevd รันในเนมสเปซระบบไฟล์ของตัวเองและโดยค่าเริ่มต้นการเมาต์ที่ทำภายใน udev .rules จะไม่แพร่กระจายไปยังโฮสต์ ในการทำให้สคริปต์เก่าของคุณใช้งานได้คุณสามารถตั้งค่าMountFlags=sharedใน/usr/lib/systemd/system/systemd-udevd.serviceหรือ (ดีกว่า) สร้างและแก้ไขสำเนาได้ที่/etc/systemd/system/

ดูman 5 systemd.execข้อมูลเพิ่มเติมMountFlagsตัวเลือก


คุณหมายถึงอะไรโดย "ไม่เผยแพร่ไปยังโฮสต์"?
sebelk

2
@sebelk ฉันเชื่อว่า user83388 หมายความว่าพวกเขาไม่เผยแพร่ไปยัง namespace "root"
Mark

2

ขณะที่เขียนนี้คำตอบอื่น ๆ ไม่ถูกต้อง (หรือล้าสมัย)

คุณไม่ควรเรียกใช้mountจากบริการ Systemd แม้หลังจากแสดงความคิดเห็นMountFlagsและPrivateMountsบรรทัดในsystemd-udevd.serviceกฎของคุณจะไม่ทำงานสำหรับระบบไฟล์ FUSE เช่น NTFS หรือ exFAT เพราะกระบวนการ FUSE จะได้รับความช่วยเหลือจาก Systemd

ดูหน้า ArchWiki นี้ซึ่งมีตัวเลือกที่ดีกว่าหลายรายการ การตั้งค่าของฉันเป็นโครงการเล็ก ๆ บน GitHub เรียกว่าudev-media-automountซึ่งเพียงแค่เริ่มบริการ Systemd จากกฎ Udev นี่เป็นวิธีที่สะดวกในการหลีกเลี่ยงข้อ จำกัด ที่ยุ่งยากต่างๆของ Udev เกี่ยวกับ namespaces และกระบวนการลูก

ดูเพิ่มเติมanwser นี้ซึ่งแสดงวิธีการใช้SYSTEMD_WANTSตัวแปร Udev เพื่อเริ่มหน่วย Systemd


-1

คุณสามารถลองใช้:=แทน+=การกำหนดกฎ RUN

:=ประกอบการตั้งค่ารายการและไม่อนุญาตให้เปลี่ยนแปลงเพิ่มเติม


ขอบคุณ แต่ภูเขายังคงใช้งานไม่ได้ :(
magva

1
อาจไม่ใช่กรณีของคุณ แต่ในเมานต์ระบบของฉันตั้งอยู่ที่ / bin / mount ลอง "command -v mount"
xae

1
ในระบบของฉันเส้นทางที่ส่งคืนโดย "command -v mount" คือ / usr / bin / mount ฉันสังเกตเห็นว่าฉันยังมี / bin / mount ที่สามารถเรียกใช้งานได้ แต่มันไม่ทำงานเมื่อถูกเรียกโดย udev
magva
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.