Wie kann ich einen systemd-Dienst starten, wenn ein bestimmtes USB-Gerät (Ethernet-Dongle) angeschlossen ist?

790
SoniEx2

Ich habe einen USB - Ethernet - Dongle ich für Ethernet - Zugang verwenden, aber ich mag automatisch starten, netctl-ifplugd@...wenn Sie ihn aufstecken (nicht mit dem Einstecken des verwechselt werden. Ethernet - Kabel - das ist von behandelt netctl-ifplugd.) Wie kann ich dies geschieht?

Ich habe gesehen, wie man einen systemd-Dienst schreibt, der von einem vorhandenen Gerät abhängt. Aber es scheint nicht so zu sein, dass es eingesteckt wird, nur dass es präsent ist.

0

2 Antworten auf die Frage

1
blihp

udev ist das, was Sie sich anschauen wollen. So können Sie beispielsweise Befehle ausführen, wenn Hardware angeschlossen ist, entfernt wird, Statusänderungen vorgenommen werden usw. Sie können auch eine Vielzahl von Kriterien zur Steuerung der Triggerung festlegen (z. B. wenn ein Speichergerät angeschlossen ist oder nur ein bestimmtes Modell von) ein bestimmter Hersteller usw.) Sie sollten in /etc/udev/rules.d/ auf Ihrem System vorhandene Regeln sehen.

1
grawity

Ich habe gesehen "Wie schreibt man einen systemd-Dienst, der von einem vorhandenen Gerät abhängt?" Aber es scheint nicht so zu sein, dass es eingesteckt wird, nur dass es präsent ist.

Es ist sehr ähnlich, nur Sie benötigen die entgegengesetzte Abhängigkeit: Anstelle (oder möglicherweise zusätzlich zu) Ihrem Dienst, abhängig vom Gerät, möchten Sie, dass die virtuelle Geräteeinheit von Ihrem Dienst abhängt.

Obwohl der Titel der verknüpften Frage scheinbar das Gegenteil fordert, dokumentiert die akzeptierte Antwort im Thread bereits eine der genauen Methoden, die das Gerät dazu veranlassen würden, einen Dienst zu starten (die Methode udev-rule).

Wenn Sie jedoch einen genauen Namen für die .device-Einheit haben, ist es einfacher, systemd-Abhängigkeiten direkt zu verwenden:

Wenn der genaue sysfs-Pfad bekannt ist:

Sie haben beispielsweise festgestellt, dass das Gerät sys-subsystem-net-devices-usb0.device ist . Sie können verschiedene Erweiterungsmöglichkeiten (obwohl es sich um eine virtuelle Einheit handelt) verwenden, z. B. foo.device.d/*.confDrop-Ins oder foo.device.wants/Symlinks (die auf dieselbe Weise funktionieren wie z. B. " multi-user.target.wants /" ).

  • Sie können eine [Install]Konfiguration zu Ihrem Dienst hinzufügen und dann systemctl aktivieren :

    [Install] WantedBy=sys-subsystem-net-devices-%i.device 
  • Oder Sie erhalten das gleiche Ergebnis direkt mit systemctl add-wants:

    # systemctl add-wants sys-subsystem-net-devices-usb0.device netctl-ifplugd@usb0.service 
  • Beide Methoden führen lediglich zu einem symbolischen Link, der per Hand hergestellt werden kann ln -s.

Dies funktioniert im Allgemeinen für Benutzereinheiten gleich.

Wenn nur ein Teilname (oder eine Kombination anderer Eigenschaften) bekannt ist:

Schreiben Sie eine udev-Regel, die Ihrem Gerät entspricht (die exakte udev-Regelsyntax ist hier außerhalb des Gültigkeitsbereichs), und legen Sie die SYSTEMD_WANTSudev-Eigenschaft (auch als "Geräteumgebungsvariable" bezeichnet) fest, die Ihre Einheit angibt:

ACTION=="add", SUBSYSTEM=="net", KERNEL=="usb*", ENV+="netctl-ifplugd@%k.service" 

Da alle *.rulesDateien in alphabetischer Reihenfolge verarbeitet werden, stellen Sie sicher, dass Ihre Regel später als die eigenen "persistenten Netzwerkschnittstellen" von systemd platziert wird.

Dies funktioniert bei Benutzereinheiten, wenn Sie verwenden ENV.


Sie könnten versucht sein, RUN+="/bin/systemctl start foo"über udev zu verwenden. Tu das nicht Wenn dies jedoch der systemctl --no-blockFall ist, verwenden Sie zumindest die Option, damit Sie keinen möglichen Deadlock zwischen den beiden Komponenten erstellen.