mount wird nicht ausgeführt, wenn es von udev aufgerufen wird


15

Ich habe versucht, einige udev-Regeln zu erstellen, um meine USB-Flash-Laufwerke zu aktivieren und zu deaktivieren. Die Regeln für den Moment sind sehr einfach:

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 ist auch sehr einfach:

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"

Ich habe einige Tests durchgeführt, damit ich feststellen kann, dass:

  • Beim Anschließen wird mein Flash-Laufwerk erkannt. Eine Datei wird in / dev erstellt
  • plug_flash_drive.sh wird von udev aufgerufen
  • Der mkdir-Teil des Skripts funktioniert
  • Es scheint jedoch, dass der "Mount" -Teil des Skripts nicht ausgeführt wird, sodass mein Laufwerk nicht gemountet ist
  • Wenn ich meine Skripte auf der Kommandozeile aufrufe, funktionieren sie perfekt

Weiß jemand, warum mount nicht ausgeführt wird, wenn es von udev aufgerufen wird?

EDIT 28/08/14: Ich habe am Ende meines Skripts "grep -q / proc / mounts && echo success || echo failure" hinzugefügt, um in meinem Debug-Protokoll zu überprüfen, ob das Gerät tatsächlich eingehängt ist, bevor das Skript endet. Es scheint, dass das Gerät an diesem Punkt eingehängt ist , auch wenn das Skript von udev aufgerufen wird. Das eigentliche Problem ist nun "Mein Block-Gerät scheint nach dem Ende des Mount-Skripts, wenn es über udev aufgerufen wird, nicht gemountet zu sein": s


Das mag nebensächlich sein, aber warum machst du das mkdir "$mount_dir"aber rmdir "/media/$device_name"? Wo wird $mount_dirgesetzt?
G-Man sagt, dass Monica

Entschuldigung, dies ist ein Tippfehler, ich habe einige ziemlich nutzlose Variablen verwendet, die in den ursprünglichen Codes als Alias ​​verwendet wurden, und ich habe sie hier aus Gründen der Klarheit entfernt
magva

Haben Sie versucht, Old-School-Debugging; zB indem man set -xvund exec >> "$HOME"/mount.log 2>&1in die .shAkten legt ?
G-Man sagt, dass Monica

1
Ich habe das getan, aber gemäß dem Protokoll, das ich erhalte, wird mount ausgeführt, wenn das Skript von udev aufgerufen wird. Es gibt keinen Unterschied im Protokoll zwischen einem Aufruf von udev und von der Kommandozeile ... das ist eigentlich ziemlich verwirrend
Magva

1
in diesem Fall würde das Skript auch fehlschlagen , wenn von der Kommandozeile ausgeführt
magva

Antworten:


22

systemd-udevd wird in einem eigenen Dateisystem-Namespace ausgeführt. Standardmäßig werden Bereitstellungen, die in udev-Regeln ausgeführt werden, nicht auf den Host übertragen. Um Ihre alte Schriften arbeiten können Sie einstellen , MountFlags=sharedin /usr/lib/systemd/system/systemd-udevd.serviceoder (besser) die Erstellung und Bearbeitung seine Kopie an/etc/systemd/system/

Siehe man 5 systemd.execweitere Informationen MountFlagsOption.


Was meinst du mit "nicht auf den Host verbreiten"?
Sonntag,

2
@sebelk Ich glaube user83388 Mittel , die sie an die „root“ nicht Namespace propagieren
Mark

2

Zum jetzigen Zeitpunkt sind die anderen Antworten falsch (oder veraltet).

Sie sollten nicht mountvon einem Systemd-Dienst ausgeführt werden. Auch nach dem Kommentieren der Zeilen MountFlagsund PrivateMountsin systemd-udevd.servicefunktioniert Ihre Regel nicht für FUSE-Dateisysteme wie NTFS oder exFAT, da der FUSE-Prozess von Systemd hilfreich beendet wird.

Siehe diese ArchWiki-Seite, die mehrere bessere Optionen auflistet. Ich bevorzuge ein kleines Projekt auf GitHub namens udev-media-automount , das einfach einen Systemd-Dienst von der Udev-Regel aus neu startet. Dies ist eine bequeme Möglichkeit, um die verschiedenen umständlichen Einschränkungen von Udev für Namespaces und untergeordnete Prozesse zu umgehen.

Siehe auch diese Antwort , die zeigt, wie die SYSTEMD_WANTSUdev-Variable zum Starten einer Systemd-Unit verwendet wird.


-1

Sie könnten versuchen , zu verwenden , :=anstatt +=in den Regeln Zuweisungen RUN.

Der :=Bediener legt den Listenwert fest und lässt weitere Änderungen nicht zu.


danke, aber mount funktioniert immer noch nicht :(
magva

1
Vielleicht nicht Ihr Fall, aber in meinem System befindet sich mount unter / bin / mount. Versuchen Sie "Befehl -v mount".
Xae

1
In meinem System lautet der von "command -v mount" zurückgegebene Pfad / usr / bin / mount. Ich bemerkte, dass ich auch eine / bin / mount ausführbare Datei hatte, aber sie funktioniert auch nicht, wenn sie von udev
magva
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.