- tsp
Last update 12 Nov 2024
4 mins
Original language: English
Available languages:
Da ich FreeBSD als mein Hauptbetriebssystem sowohl auf Servern als auch auf
Desktop-Systemen bevorzuge, habe ich es auf vielen verschiedenen Hardware-Konfigurationen
eingesetzt, und in der Regel läuft es sehr stabil und ohne Probleme (insbesondere mit deutlich
weniger Problemen als bei anderen Betriebssystemen). Es ist robust, einfach zu konfigurieren,
konsistent und effizient. Kürzlich gab es jedoch einige neu aufgebaute Systeme aus
kostengünstigen Komponenten, die anfingen, zufällig einzufrieren. Es schien, dass einige
Anwendungen aufhörten zu funktionieren, während man das System noch nutzen konnte, und irgendwann
fror es komplett ein. Auf den ersten Blick schien das Einfrieren mit der Nutzung von Browsern (wie
Firefox oder Chromium) zusammenzuhängen, da es nie passierte, wenn diese nicht liefen, aber
während der Browsernutzung zuverlässig reproduzierbar war, selbst auf Systemen mit viel
Arbeitsspeicher – wobei die Häufigkeit des Einfrierens anscheinend mit dem verfügbaren RAM
korrelierte. Da ich FreeBSD auch bei der Arbeit benutze und das Einfrieren an meinem Arbeitsplatz
etwas zu nervig wurde, beschloss ich, dem weiter nachzugehen. Nach dem Neustart zeigte das Log
jedoch nichts Auffälliges – also beschloss ich, mich von einer anderen Maschine aus in eine
SSH-Sitzung einzuloggen, da die GUI in der Regel völlig einfriert und nur den Inhalt
von /var/log/messages
in Echtzeit anzeigt, indem ich tail -f
benutze:
sudo tail -f /var/log/messages
Das funktioniert auch, wenn Daten nicht auf die Festplatte geschrieben werden, sondern nur im RAM gehalten werden, sodass man Kernel-Meldungen sehen kann, solange der Dateisystemtreiber selbst noch funktioniert. Dies zeigte dann konsequent über alle Einfrierungen hinweg Zeitüberschreitungen auf meinen sehr günstigen SSDs:
kernel: (ada0:ahcich1:0:0:0): FLUSHCACHE48. ACB: ea 00 00 00 00 40 00 00 00 00 00 00
kernel: (ada0:ahcich1:0:0:0): CAM status: ATA Status Error
kernel: (ada0:ahcich1:0:0:0): ATA status: 51 (DRDY SERV ERR), error: 04 (ABRT )
kernel: (ada0:ahcich1:0:0:0): RES: 51 04 00 00 00 40 00 00 00 00 00
kernel: (ada0:ahcich1:0:0:0): Retrying command, 0 more tries remain
kernel: (ada0:ahcich1:0:0:0): FLUSHCACHE48. ACB: ea 00 00 00 00 40 00 00 00 00 00 00
kernel: (ada0:ahcich1:0:0:0): CAM status: ATA Status Error
kernel: (ada0:ahcich1:0:0:0): ATA status: 51 (DRDY SERV ERR), error: 04 (ABRT )
kernel: (ada0:ahcich1:0:0:0): RES: 51 04 00 00 00 40 00 00 00 00 00
kernel: (ada0:ahcich1:0:0:0): Error 5, Retries exhausted
Das schien auf Probleme mit der SSD hinzuweisen, jedoch ergab die Überprüfung der SMART-Parameter keinen weiteren Aufschluss. Auch das Verhalten war auf einer kleinen Anzahl von Maschinen konsistent. Ich versuchte, die Timeout-Einstellung zu erhöhen, falls die SSDs unglaublich langsam waren, wie man es von SMR-Festplatten kennt – die man sowieso nicht für ZFS verwenden sollte. Um dieses Problem zu mildern, erhöhte ich das Standard-Timeout für das Gerät zunächst auf 60 Sekunden und versuchte es schließlich sogar mit 300 Sekunden.
kern.cam.ada.default_timeout=60
Leider löste dies das Problem nicht – es dauerte nur länger, bis das System komplett einfrohr.
Am Ende stellte sich heraus, dass es ein Problem mit dem Leeren der Cache-Puffer in Verbindung mit der Verwendung von Native Command Queuing (NCQ) war. Auf vielen Geräten wie günstigen SSDs und SMR (Shingled Magnetic Recording)-Festplatten kann NCQ (Native Command Queuing) einfach dazu führen, dass mehrere Flush-Befehle in die Warteschlange gestellt werden, die dann den Timeout überschreiten – dies ließe sich lösen, indem man das Timeout einfach weiter erhöht. Leider verursachten meine Geräte weiterhin das gleiche Problem. Dies könnte beispielsweise durch Firmware-Bugs verursacht werden. Dies ließ sich auf meinem speziellen System und meinen speziellen SSDs lösen, indem man NCQ deaktivierte – allerdings mit allen Konsequenzen wie verringerter Durchsatz:
camcontrol negotiate ada0 -T disable
Dies deaktivierte das Tagged Queuing (Native Command Queuing) auf der Festplatte und löste das Einfrier-Problem sofort.
rc.init
-Skript zum Deaktivieren von NCQDa diese Änderung nicht dauerhaft ist, beschloss ich, ein kleines,
modifiziertes rc.init
-Skript in /usr/local/etc/rc.d/disablencq
zu schreiben:
#!/bin/sh
# PROVIDE: disablencq
# REQUIRE: NETWORKING SERVERS
# Deaktiviert Tagged Queuing auf angegebenen Festplatten
#
# disablencq_enable="YES"
# Führt dieses Skript aus
# disablencq_disks="ada0 ada1 ada2"
# Listet die Festplatten auf, auf denen NCQ deaktiviert werden soll
. /etc/rc.subr
name="disablencq"
rcvar=disablencq_enable
desc="Deaktiviert NCQ auf einigen Festplatten"
start_cmd="disablencq_start"
disablencq_start()
{
for dsk in ${disablencq_disks}; do
camcontrol negotiate ${dsk} -T disable
done
}
load_rc_config $name
: ${disablencq_enable:="NO"}
: ${disablencq_disks:="ada0"}
run_rc_command "$1"
Nun konnte ich die problematischen SSDs in /etc/rc.conf
konfigurieren:
disablencq_enable="YES"
disablencq_disks="ada0 ada1"
Das ist natürlich ein Hack – aber er scheint Probleme mit der nativen Firmware einiger SSDs zu umgehen. Üblicherweise ist es eine gute Idee, sich von solchen SSDs fernzuhalten, genauso wie man von SMR-Festplatten Abstand nehmen sollte.
Dipl.-Ing. Thomas Spielauer, Wien (webcomplains389t48957@tspi.at)
This webpage is also available via TOR at http://rh6v563nt2dnxd5h2vhhqkudmyvjaevgiv77c62xflas52d5omtkxuid.onion/