[gelöst] SVDRP vdr1 < 127.0.0.1:40510 lost connection to client

  • Hallo,


    Welche Ursachen kann

    Code
    1. SVDRP vdr1 < 127.0.0.1:40510 lost connection to client

    haben?


    Im Syslog:

    Auf der Commandline:

    Code
    1. $ /usr/bin/svdrpsend PLUG softhddevice DETA
    2. 220 vdr1 SVDRP VideoDiskRecorder 2.4.5; Mon Dec 28 21:10:02 2020; UTF-8
    3. $ /usr/bin/svdrpsend PLUG softhddevice DETA
    4. 220 vdr1 SVDRP VideoDiskRecorder 2.4.5; Mon Dec 28 21:10:15 2020; UTF-8
    5. 900 SoftHdDevice is detached
    6. 221 vdr1 closing connection


    Oder, anders gefragt: warum muss ich das svdrp Kommando 2 mal eingeben, damit es funktioniert?

    Also, das ist jetzt nicht immer reproduzierbar, manchmal klappt es auch beim 1. mal.


    ~ Markus

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.4x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

  • So ganz kann ich deinem Patch nicht zustimmen.

    Was mir aber auffällt ist, dass es an dieser Stelle (und auch an einer Zweiten) heißt

    Code
    1. if (r > 0) {
    2. ...
    3. }
    4. else if (r <= 0) {
    5. ...
    6. }

    Die Abfrage auf r <= 0 ist überflüssig, da wenn nicht r > 0 ist, r automatisch <= 0 ist.


    Aber safe_read() kann offensichtlich 0 zurückgeben, ohne dass dies einen Fehler darstellt.

    Daher würde ich es mal mit der Abfrage im beiliegenden Patch versuchen.

  • Hallo Klaus,


    Ich sehe durchaus, dass mein Patch verbessert werden sollte.

    Ich habe einfach nur verhindert, dass "Close" aufgerufen wird, obwohl kein Verbindungsfehler vorliegt.

    Bleibt die Frage: wie kann ich zuverlässig prüfen, ob ein Fehler vorliegt?

    Ich habe mal auf https://linux.die.net/man/3/read geschaut:

    Quote

    Upon successful completion, read() and pread() shall return a non-negative integer indicating the number of bytes actually read. Otherwise,
    the functions shall return -1 and set errno to indicate the error.


    Das würde für Deinen Patch sprechen. Aber darunter steht:


    Quote

    Errors

    The read() and pread() functions shall fail if:

    EAGAIN
    The O_NONBLOCK flag is set for the file descriptor and the process would be delayed.

    ...


    Die Frage ist, wie kann ich zuverlässig prüfen, ob die Verbindung wirklich nicht mehr da ist? Weil nur in diesem Fall "Close" aufgerufen werden sollte.


    ~ Markus

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.4x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

  • Und noch eine Frage: in Zeile 469 steht:

    Code
    1. esyslog("SVDRP %s < %s timeout while waiting for response from '%s'", Setup.SVDRPHostName, serverIpAddress.Connection(), *serverName);
    2. return false;


    Warum wird hier kein "Close()" aufgerufen?

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.4x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

  • Warum wird hier kein "Close()" aufgerufen?

    Da ist nur der Timeout für ein Kommando abgelaufen. Deswegen muss nicht unbedingt die Verbindung unterbrochen sein.


    Zu deinem verbesserten Patch: wäre es nicht konsequenter, anstatt drei andere Werte abzufragen, einfach den Wert abzufragen, um den es bei O_NONBLOCK geht:


    else if (r < 0 && errno != EAGAIN) {

  • Hallo Klaus,


    Code
    1. else if (r < 0 && errno != EAGAIN) {


    funktioniert auch.

    Ich kann jetzt nicht sagen, was besser ist. In der Praxis ist es vermutlich egal.


    ~Markus

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.4x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

  • Hi,


    > The O_NONBLOCK flag is set for the file descriptor and the process would be delayed.

    Ist das sinnvoll? Wäre es nicht besser, O_NONBLOCK nicht zu setzten?


    ~ Markus

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.4x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

  • O_NONBLOCK ist notwendig, weil ansonsten eine blockierende Verbindung alle anderen Verbindungen lahmlegen könnte.


    Ich habe jetzt mal eine Zeit lang mit 'else if (r < 0 && errno != EAGAIN) {' getestet, aber damit bekommt z.B. der Client nicht mehr sofort mit, wenn der Server die Verbindung schließt. Es kommt dann laufend zu r==0 und errno==EAGAIN.


    Aus momentaner Sicht würde ich dich daher bitten erstmal das Szenario genauer zu untersuchen um herauszufinden, was da wirklich ganz genau schiefgeht.

  • Und meinem Patch fehlt außerdem der Timeout.

    Ich werde noch eine Runde testen und dann einen neuen Patch posten.

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.4x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

  • Hi,


    Anbei ein neuer Patch.

    r = 0 bedeutet laut manpage "If no process has the pipe open for writing, read() shall return 0 to indicate end-of-file." . Dies entspricht auch der Beobachtung von Klaus. Also wird bei r = 0 direkt "Close();" aufgerufen, wie ohne den Patch.

    Bei r < 0 wird ein Eintrag ins syslog geschrieben, und nach einem Timeout abgebrochen.

    Funktioniert hier super. Im Syslog steht dann gelegentlich:


    errno = 9 bedeutet EBADF, also "The fildes argument is not a valid file descriptor open for reading." .

    Bleibt die Frage: Warum ist der file descriptor 1202 mal ungültig, und danach auf einmal gültig? Und außerdem: 2 Zeilen vor dem read wird ja mit "file.Ready(false)" überprüft, ob der file descriptor OK ist.


    ~ Markus

    Files

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.4x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

  • Hi,


    mal wieder getestet, und heute:


    11 ist EAGAIN, das leuchtet mir noch ein. Also, dieser Fehler passiert gelegentlich, sehr oft geht die Verbindung auch mit

    Quote

    Feb 13 22:02:23 vdr1 vdr: [149130] SVDRP vdr1 < 127.0.0.1:44500 client connection accepted

    Feb 13 22:02:23 vdr1 vdr: [149130] SVDRP vdr1 > 127.0.0.1:44500 server created

    Feb 13 22:02:23 vdr1 vdr: [149130] SVDRP vdr1 < 127.0.0.1:44500 connection closed

    Feb 13 22:02:23 vdr1 vdr: [149130] SVDRP vdr1 < 127.0.0.1:44500 server destroyed

    durch.


    ~ Markus

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.4x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

  • Kann es sein, dass dieses Problem nur unmittelbar nach dem öffnen der Datei und vor dem Lesen des ersten Zeichens passiert?

    Vielleicht ist ja die Verbindung zwischen Client und Server noch nicht ganz aufgebaut, obwohl Ready() true zurückgibt. Eventuell liegt der eigentliche Fehler ja in cFile::AnyFileReady(). Vielleicht sollte hier statt file.Ready(false) besser cFile::FileReady(file, 0) aufgerufen werden.

    Kannst du bitte mal (bei ansonsten originalem svdrp.c) testen, ob das Problem mit beiliegender Änderung auch auftritt?


    Das cFile scheint ein Relikt aus vergangenen Tagen zu sein, das nur noch in svdrp.c verwendet wird. Und es ist offensichtlich auch nicht thread-safe, was vielleicht ein Problem ist, seit SVDRP in einem separaten Thread läuft.

  • Hallo Klaus,


    Ich habe mal alle Patches entfernt, und nur diesen Patch angewandt

    Außerdem alle Plugins weggelassen, außer softhddevice (von INJ).

    Mit VDR version 2.4.6:


    /usr/bin/svdrpsend PLUG softhddevice DETA

    liefert dann im syslog:

    Code
    1. May 22 07:23:47 vdr1 vdr: [80101] [softhddev]OpenGl Thread not started successfully, using Dummy OSD
    2. May 22 07:23:47 vdr1 vdr: [80113] device 1 TS buffer thread started (pid=80101, tid=80113, prio=high)
    3. May 22 07:23:47 vdr1 vdr: [80102] video directory scanner thread ended (pid=80101, tid=80102)
    4. May 22 07:27:05 vdr1 vdr: [80110] SVDRP vdr1 < 127.0.0.1:51044 client connection accepted
    5. May 22 07:27:05 vdr1 vdr: [80110] SVDRP vdr1 > 127.0.0.1:51044 server created
    6. May 22 07:27:05 vdr1 vdr: [80110] SVDRP vdr1 < 127.0.0.1:51044 connection closed
    7. May 22 07:27:05 vdr1 vdr[80101]: *** buffer overflow detected ***: terminated

    VDR stoppt und startet neu. Das ist reproduzierbar.


    ~ Markus

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.4x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x