FHEM blockiert: Accept failed (WEB: Too many open files)

Begonnen von Papaloewe, 14 November 2020, 16:36:28

Vorheriges Thema - Nächstes Thema

duke-f

Ok, ich warte auf den nächste Vorfall - und hoffe, dass ich dann auch wieder gleich rankomme.

Danke Dir
Cubietruck, 3 Raspberry Pis,
CUL868, RFXtrx433, CUL433, SCC868, HM-USB,
IRTrans, EZcontrol XS1, IguanaWorks USB IR Transceiver
ESPEasy, Fritz!Box, Samsung TV+BD, LMS, Squeezelite

Wernieman

Noch ein kleiner Hinweis wegen "Files" und Netzwerk:
Unter Unix als alles ein File. Also kann durchaus wegen Netzwerkverbindungsanzahl es zu solchen Problemen kommen. Aber auch andere Hardware, wie z.B. Serielle Schnittstellen.
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

duke-f

"Endlich" habe ich mal wieder den Zustand. Diesmal leider besonders hartnäckig wiederholt seit über einer Woche. Seltsamerweise genau seit ich das Haus verlassen habe für einen Kurzurlaub und immer dann, wenn die Nachbarin die Anwesenheitskontrolle aktiviert. Damit konnte ich das jetzt sogar eindeutig reproduzieren. Seltsam ist allerdings, dass ich ganz sicher seit längerem diesbezüglich nichts geänedrt habe und auch kein Update durchgeführt hatte. Das hatte ich erst vor wenigen Tagen, als der Fehler wieder auftauchte, gemacht.

Ich füge mal zwei Ausgaben aus lsof bei. Das erste ohne den Fehler, das zweite von gerade jetzt, als ich den Fehler bewusst provoziert habe. Muss aber sagen: Ich sehe zwar den Unterschied in Form der gehäuften TCPs, mir sagt das gar nichts.
Cubietruck, 3 Raspberry Pis,
CUL868, RFXtrx433, CUL433, SCC868, HM-USB,
IRTrans, EZcontrol XS1, IguanaWorks USB IR Transceiver
ESPEasy, Fritz!Box, Samsung TV+BD, LMS, Squeezelite

rudolfkoenig

Von den 1024 Filedeskriptoren sind 170 FileLogs, 8 TCP Serverports, 13 hergestellte Client-Verbindungen, eine ist beim Schliessen, 4 beim vergeblichen Herstellen der Verbindung, und 820 (die mit protocol: TCP) in "gar keinem" Zustand.

Nach laengerem experimentieren: ein "protocol: TCP" Eintrag kann auch auftreten, wenn HttpUtils_NonblockingGet mit keepalive=1 aufgerufen wurde, ohne die Verbindung danach selber zu schliessen. Heisst nicht, dass das auch hier der Fall ist.

duke-f

Danke Dir für die schnelle Antwort. Da habe ich mindestens mal einen neuen Ansatz. Hab' da als erstes die Alexa-Schiene unter Verdacht, auch wenn diese aktuell gar nicht aufgerufen werden sollte. Aber ursprünglich kamen die Probleme erst einige Zeit, nachdem dies eingerichtet wurde.
Cubietruck, 3 Raspberry Pis,
CUL868, RFXtrx433, CUL433, SCC868, HM-USB,
IRTrans, EZcontrol XS1, IguanaWorks USB IR Transceiver
ESPEasy, Fritz!Box, Samsung TV+BD, LMS, Squeezelite

duke-f

Jetzt habe ich AMAD unter Verdacht. Mein Flur-Tablet hatte offensichtlich kurz nach unserem Urlaubsantritt einen Fehler und hat sich aufgehangen. Wenn jetzt die Nachbarin vor der Tür stand, um zu öffenen, sollte am Tablet über AMAD eine Ansage kommen. Die vier vergeblichen TCP-Verbindungsversuche sind auch alle an das Tablet pere AMAD gerichtet. Und als ich jetzt zuhause war und alles wieder vernünftig zum Laufen bringen wollte, giung das erst, als ich AMAD in der Config manuell auskommentiert habe. Dann alles gestartet (FHEM und das Tablet), die Kommentarzeichen wieder entfernt, rereadcfg eingegeben und im Moment läuft es wieder. Ist jetzt keine Dauerlösung, klar. Muss AMAD nochmal im Auge behalten.
Cubietruck, 3 Raspberry Pis,
CUL868, RFXtrx433, CUL433, SCC868, HM-USB,
IRTrans, EZcontrol XS1, IguanaWorks USB IR Transceiver
ESPEasy, Fritz!Box, Samsung TV+BD, LMS, Squeezelite

ronzo

Ich habe diese Sache nun auch in einem Container erlebt, der unter K3s läuft. Ziemlich viele "Too many open files"-Meldungen:

2023.05.16 16:34:46 1: Accept failed (telnetPort: Too many open files)
2023.05.16 16:34:46 1: Accept failed (telnetPort: Too many open files)
2023.05.16 16:34:46 1: Accept failed (telnetPort: Too many open files)
2023.05.16 16:34:46 1: Accept failed (telnetPort: Too many open files)
2023.05.16 16:34:46 1: Accept failed (telnetPort: Too many open files)
Unrecognised protocol udp at /usr/share/perl5/Net/DNS/Resolver/Base.pm line 908.
/entry.sh: line 621: kill: (3487212) - No such process


Leider habe ich das K3s-Deployment aus Panik etwas nicht mehr steuern zu können einfach nochmal neu deployed. Derzeit sieht es so aus:

root@fhem-deployment-57c5864689-tlxbg:/opt/fhem# ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.3  0.0  14676  4552 ?        Ss   17:38   0:06 /bin/bash /entry.sh start
fhem       12099  1.4  2.3 241204 190116 ?       S    17:47   0:17 /usr/bin/perl fhem.pl fhem.cfg
fhem       12100  0.0  0.9 107128 80288 ?        S    17:47   0:00 /usr/bin/perl fhem.pl fhem.cfg
root       16634  0.0  0.0  14160  4092 pts/0    Ss   17:53   0:00 /bin/bash
root       29047  0.0  0.0  12364   580 ?        S    18:08   0:00 sleep 0.5
root       29048  0.0  0.0  16760  3588 pts/0    R+   18:08   0:00 ps aux
root@fhem-deployment-57c5864689-tlxbg:/opt/fhem# ls /proc/*/fd
/proc/12099/fd:
0    102  107  111  116  120  125  13 134  139  143  148  152  157  161  19  23  28  32  37  41  46  50  55  6   64  69  73  78  82  87  91  96
1    103  108  112  117  121  126  130 135  14   144  149  153  158  162  2   24  29  33  38  42  47  51  56  60  65  7   74  79  83  88  92  97
10   104  109  113  118  122  127  131 136  140  145  15   154  159  163  20  25  3   34  39  43  48  52  57  61  66  70  75  8   84  89  93  98
100  105  11   114  119  123  128  132 137  141  146  150  155  16   17   21  26  30  35  4   44  49  53  58  62  67  71  76  80  85  9   94  99
101  106  110  115  12 124  129  133 138  142  147  151  156  160  18   22  27  31  36  40  45  5   54  59  63  68  72  77  81  86  90  95

/proc/12100/fd:
0  1  2  3  4  5  6  7

/proc/16634/fd:
0  1  2  255

/proc/1/fd:
0  1  2  255

/proc/29072/fd:
0  1  2

/proc/self/fd:
0  1  2  3

/proc/thread-self/fd:
0  1  2  3

Sobald die Situation erneut auftritt, schau ich nochmal genauer...


gregor

Ich stand auch soeben vor dieser Fehlermeldung. Auch bei mir läuft FHEM in einem Container. Und obwohl angeblich alle "files" belegt waren, wurden seit Monaten die Daten weiter in jeweils neu angelegten Logfiles aufgezeichnet.

Ich hatte UNGLAUBLICH viele auto-gefundene Geräte (so 12.000). Ich wohne in einem Dorf mit 70 Einwohnern,der Empfänger im Keller. Da wird offensichtlich "rosa Rauschen" auf Geräte zugeordnet...

ich habe in der fhem.cfg auto-create auskommentiert, die hinzugekommenen Geräte entfernt und aus /opt/fhem/log/ zuerst alle Dateien der Größe "0" gelöscht und anschließend manuell alles was ich nicht kannte.

Wer ein bisschen skripten kann, kann versuchen meine Grundlage für sich anzupassen.

Die Änderungen hatte ich ausgeführt, während fhem gestoppt war. Nach dem Start war alles wieder erreichbar.

{
IFS=$'\n'
i=0
for LINE in $(ls -lSr)
do
  size=""
  name=""
  LINE=$(echo $LINE|sed -e "s/\s\s*/ /g")
  size=$(echo $LINE|awk '{print $5}')
  name=$(echo $LINE|awk '{print $9}')
 
  #echo "$var1 $var2 $var3 $var4 $var5 $var6 $var7 $var8 $var9"
 # echo "$LINE    size= $var5      name = $var9"
 
  if [ $size -eq 0 ] ; then
    echo "del $name weil $size"
    # rm $name
  else
    echo "    $name  =   $size"
  fi

  i=$(( $i + 1 ))
  if [ $size -gt 0 ]; then
    break
  fi
done
echo "es wurden $i dateien gelöscht."
}


Viele Grüße, Gregor

rudolfkoenig

ZitatIch hatte UNGLAUBLICH viele auto-gefundene Geräte (so 12.000).
Von welchem Typ?
Kandidaten fuer Falschmeldungen sind S300 und HOERMANN, da hier die Checksums nicht richtig geprueft werden, mangels Verstaendnis des Protokolls.
Auch andere Protokolle verwenden schwache Checksums, bei schlechten Empfang kann das zu solchen Unfaellen fuehren.

Zitatich habe in der fhem.cfg auto-create auskommentiert,
Einfacher ist es mit dem disable Attribut zu deaktivieren, oder noch besser, mit dem ignoreTypes Attribut die Verursacher rauszufiltern.
Ohne autocreate ist das Einpflegen von neuen ZWave oder MQTT2_DEVICE Instanzen deutlich komplizierter.

Beta-User

...oder man unterbindet das automatische Anlegen der filelog Devices....
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

gregor

Zitat von: rudolfkoenig am 24 Juni 2023, 11:11:37Von welchem Typ?
HOERMANN, FS20, FHT und ein paar Revolt. (Die mit 0 byte hab ich mir aber gar nicht angesehen.) Wenn es wichtig zur Fehlerbehung sein könnte, guck ich gerne in einen Backup nach!

Einige der Logfiles waren bis auf über 30GiB/Tag gewachsen. Ich habe mit Chat-GPT ein Skript basteln lassen, das die Zeilen mit gefundenem Suchbegriff entfernt. Dateizeitstempel bleibt gleich. So geht es von 34GiB auf 3,5MiB runter. Das läuft natürlich ne Weile. Je nachdem wie fix die Platten die Daten liefern...

#!/bin/python3

import os
import shutil
import concurrent.futures
import multiprocessing

# Verzeichnis, in dem die Dateien gesucht werden sollen
input_directory = '/volume1/docker/container-data/fhem/opt_fhem/log'

# Verzeichnis, in dem die bearbeiteten Dateien gespeichert werden sollen
output_directory = '/volume1/docker/container-data/fhem/opt_fhem/log2'

# String, der in den Dateien gefunden werden soll
string = 'Accept failed (telnetPort: Too many open files)'


def process_file(filepath, string, output_directory, chunk_size=16777216):
#    print(f"es soll verarbeitet werden: {filepath}")
    filename = os.path.basename(filepath)
    if os.path.isfile(filepath) and os.path.splitext(filename)[1] == '.log':
#        print(f"es wird verarbeitet: {filepath}")
        # Erfasse den ursprünglichen Zeitstempel und die Größe der Datei
        original_timestamp = os.stat(filepath).st_mtime
        original_size = os.path.getsize(filepath)
       
        with open(filepath, 'rb') as file:
#            print(f"oeffne {filepath}")
            with open(os.path.join(output_directory, filename), 'wb') as temp_file:
#                print(f"schreibe nach {os.path.join(output_directory, filename)}")
                while True:
                    chunk = file.read(chunk_size)
                    if not chunk:
                        break
                    lines = chunk.splitlines()
                    for i, line in enumerate(lines):
                        if string.encode() not in line.rstrip():
                            if i < len(lines) - 1:
                                temp_file.write(line + os.linesep.encode())
                            else:
                                temp_file.write(line)
       
        # Wiederherstellen des ursprünglichen Zeitstempels der Datei
        os.utime(os.path.join(output_directory, filename), (original_timestamp, original_timestamp))
       
        # Ausgabe des Dateinamens und der Größe des bearbeiteten Files
        output_file_path = os.path.join(output_directory, filename)
        output_file_size = os.path.getsize(output_file_path)
        print(f"Datei fertig: {output_file_path}, Größe: {output_file_size/1024} kiB")

def remove_line_with_string(directory, string, output_directory):
    if not os.path.exists(output_directory):
        os.makedirs(output_directory)
   
    # Liste der Dateien im Eingabe-Verzeichnis, sortiert von groß nach klein
    files = sorted(os.listdir(directory), key=lambda x: os.path.getsize(os.path.join(directory, x)), reverse=True)
   
    num_cpus = multiprocessing.cpu_count()
   
    with concurrent.futures.ProcessPoolExecutor(max_workers=num_cpus) as executor:
        # Dateien parallel verarbeiten
        futures = []
        for filepath in files:
#            print(f"schicke File {filepath} in die Queue.")
            futures.append(executor.submit(process_file, filepath, string, output_directory))
       
        # Auf Beendigung aller Prozesse warten
        concurrent.futures.wait(futures)


# Aufruf der Funktion
remove_line_with_string(input_directory, string, output_directory)