PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Systemd Socket übergabe an Bash Script in Systemd Service klappt nur einmalig



bachmarc
28.04.15, 17:28
Hallo,
ich habe da eine Frage zu Systemd auf debian Jessie...
Ich möchte einen TCP Socket auf Port 777 öffnen, diesen dann zB simple über Telnet von einem Windoof Rechner ansteuern und Systemd soll dann passend zur eingehenden Verbindung auf dem Socket einen Service starten.

Das funktioniert auch ganz gut, zumindest beim ersten Aufruf:(

Ich habe eine

my_service.socket:



[Unit]
Description=Mein Socket zum Service

[Socket]
ListenStream=777
Accept=no
TimeoutSec=0


Diese lässt sich über systemctl start my_service.socket starten, ein netstat |grep 777 zeigt auch brav LISTENING


Der gleichnamige Service:

my_service.service:


[Unit]
Description=Mein Service

[Service]
Type=oneshot
ExecStart=-/bin/sh -c "/home/main/test.sh"
StandardInput=socket

wird auch ausgeführt! Telnet flackert kurz, das test.sh erzeugt eine "Beweisdatei" im Filesystem und dann ist Schluss.
Hinter test.sh steckt derzeit nichts Tolles, es schreibt nur das Datum in ein Textfile, damit ich weiss es hat kurz gelebt.

Der Service lässt sich alleine fehlerfrei ausführen über systemctl start my_service.service.
Nutze ich aber das Socket als Trigger schmiert das Ganze unmittelbar nach dem ersten Start ab.

Systemd meldet mir, dass der Socket permanenten Fehler habe und der Service sagt er sei zu oft gestartet worden und ei erst mal gesperrt für x Sekunden.



my_service.socket - Mein Socket zum Service
Loaded: loaded (/etc/systemd/system/my_service.socket; static)
Active: failed (Result: service-failed-permanent) since Mo 2015-04-27 23:56:28 CEST; 8s ago
Listen: [::]:777 (Stream)

Apr 27 23:56:28 europa systemd[1]: Unit my_service.socket entered failed state.




my_service.service - Mein service
Loaded: loaded (/etc/systemd/system/my_service.service; static)
Active: failed (Result: start-limit) since Mo 2015-04-27 23:56:28 CEST; 1min 50s ago
Process: 27064 ExecStart=/bin/sh -c /home/main/test.sh (code=exited, status=0/SUCCESS)
Main PID: 27064 (code=exited, status=0/SUCCESS)

Apr 27 23:56:28 europa systemd[1]: my_service.service start request repeated too quickly, refusing to start.
Apr 27 23:56:28 europa systemd[1]: Failed to start Mein Service service.
Apr 27 23:56:28 europa systemd[1]: Unit my_service.service entered failed state.


Der Socket mag es nicht, wenn sich der oneshot Service klanglos verabschiedet nach der sh Ausführung, er versucht wohl auch noch mehrfach den Service neu zu triggern.
Ich kann diesen Absturz verhindern, indem ich den Service auch nach dem script ende als aktiv flagge im Systemd, das hat aber den Preis, dass das Socket den noch als aktive geflaggten Service nicht erneut starten will.

Mir war es auch nicht möglich über STIN oder STOUT mit dem script über telnet zu reden... Ich dachte bisher das Socket würde den Service rufen und alles was ich über Telnet ins Kabel drücke kommt im STIN beim Script an. Ich dachte auch ich könne ein einfaches "Action performed" html per echo zurück in STOUT schreiben...


Das Fernziel ist, dass der Raspi auf die IP meines NAS lauschen soll und dieses dann aus dem Suspend weckt, wenn ein request reinkommt. Klar könnt ichs jetzt in Ruby machen oder Java aber zumindest nen Port überwachen und ein script triggern muss ich doch auch so hinbekommen...

Wo liegt mein Fehler?

Marc

fork
30.04.15, 23:54
Ehrlich gesagt keine Ahnung: Ich würde vermuten bei dem Script, dass den Dienst stellt. Poste dochmal das Script. schreibe STDERR in ein logfile und schau Dir an was da so kommt.

bachmarc
06.05.15, 13:10
Ich habe es mal mit einem von einem init.d howtohttp://www.troubleshooters.com/codecorn/sockets/ geklauten script probiert:


#!/bin/bash

logfile="/tmp/log.log"
firstname="initialization"
lastname="initialization"
/bin/echo "LOG: $(/bin/date)" > $logfile
/bin/echo >> $logfile
while test 1; do ###Forever, see the break in the case statement
/bin/echo >> $logfile
/bin/echo "Begin Cycle: $(/bin/date) **********" >> $logfile
/bin/echo
/bin/echo "Please type Linux celebs name below:" | /usr/bin/tee -a $logfile
read firstname

##### NEXT STATEMENT REMOVES EXTRA CTRL+M PUT IN BY TELNET #####
##### PROGRAMMER: MAKE SURE THE CHAR IS CTRL+M, NOT A CARAT AND AN M! #####
firstname=$(/bin/echo ${firstname}|/bin/sed -e 's/^M$//')

/bin/echo ":$firstname, " | /usr/bin/tee -a $logfile
case "$firstname" in
(richard) lastname="stallman";;
(linus) lastname="torvalds";;
(maddog) lastname="hall";;
(q*) lastname="quit"; break;;
(*) lastname="Unknown celeb";;
esac
/bin/echo "$lastname" | /usr/bin/tee -a $logfile
done

/bin/echo | /usr/bin/tee -a $logfile
/bin/echo "Finished" | /usr/bin/tee -a $logfile


das führt bei aufruf durch systemd generiertes socket nicht dazu, dass ich per telnet stdin und out bekomme... die verbindung wird geöffnet, aber ich kann weder was tippen noch kommt was sinnvolles durch netz... im log steht auch nur 4 mal ":, Unknown celeb" mit gleichem zeitstempel... was drauf hindeutet, dass es nicht wirklich klappt und systemd mehrfach versucht etwas zu starten.


Ohne systemd bekäme ichs ja hin ;o)

Marc

fork
06.05.15, 22:36
Ja, habe das mal ausprobiert. Scheint so zu sein als ob die Daten nicht korrekt ankommen(Zeilenendezeichen, ..., ?).

Habe dazu netcat verwendet. Da sieht man mehr.

Für den Server:


netcat -p7777 -l 127.0.0.1 7777 | ./shellscript.sh

Für den Request:


echo -n linus | netcat localhost 7777