Android Live Lock-Daemon (LKD)

Android 10 enthält den Android Live Lock-Daemon (llkd), die zum Erkennen und Beheben von Kernel-Deadlocks entwickelt wurde. Das llkd Komponente bietet eine eigenständige Standardimplementierung. Sie können jedoch Alternativ können Sie den llkd-Code in einen anderen Dienst integrieren, entweder als Teil eines als Hauptschleife oder als separater Thread.

Erkennungsszenarien

Für llkd gibt es zwei Erkennungsszenarien: den Status „Persistent D“ oder „Z“ und „Persistent“ Stack-Signatur.

Dauerhafter D- oder Z-Zustand

Wenn sich ein Thread im Status D (unterbrechungsfreier Schlaf) oder Z (Zombie) ohne Weiterleitung befindet Fortschritt länger als ro.llk.timeout_ms or ro.llk.[D|Z].timeout_ms, der llkd bricht den Prozess (oder den übergeordneten Prozess) ab. Wenn bei einem nachfolgenden Scan der Prozess weiterhin besteht, bestätigt llkd eine Live-Lock-Bedingung und auf eine Art und Weise, die den detailliertesten Fehlerbericht für den .

Zu llkd gehört auch ein Selbstachter, der warnt, wenn llkd aufsperrt. Watchdog ist Verdoppeln Sie die erwartete Zeit für den Durchlauf der Mainloop und das Sampling erfolgt jeweils ro.llk_sample_ms.

Persistente Stacksignatur

Bei Nutzer-Fehlerbehebungsversionen kann llkd Kernel-Livelocks mithilfe von persistenten Stack-Signaturprüfung. Wenn ein Thread in einem beliebigen Zustand außer Z eine persistente aufgelistetes ro.llk.stack-Kernelsymbol, das länger als ro.llk.timeout_ms oder ro.llk.stack.timeout_ms: llkd beendet den Prozess. (auch wenn es Fortschritte im Zeitplan gibt). Wenn bei einem nachfolgenden Scan der Prozess weiterhin besteht, bestätigt llkd eine Live-Lock-Bedingung und auf eine Art und Weise, die den detailliertesten Fehlerbericht für den .

Die lldk-Prüfung bleibt bestehen, wenn die Bedingung „Live Lock“ vorhanden ist und sucht nach den zusammengesetzten Strings symbol+0x oder symbol.cfi+0x im /proc/pid/stack unter Linux. Die Liste der Symbole befindet sich in ro.llk.stack und ist standardmäßig die kommagetrennte Liste cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable.

Symbole sollten so selten und kurzlebig sein, dass sie in einem typischen System in einer Stichprobe über das Zeitlimit von ro.llk.stack.timeout_ms (Stichproben erscheinen alle ro.llk.check_ms). Aufgrund fehlender ist dies die einzige Möglichkeit, einen Fehlalarm zu verhindern. Das Symbol -Funktion muss unter der Funktion angezeigt werden, die die Sperre aufruft, die konkurrieren kann. Wenn sich das Schloss unterhalb oder in der Symbolfunktion befindet, erscheint das Symbol in allen betroffenen und nicht nur denjenigen, der das Lockup verursacht hat.

Abdeckung

Die Standardimplementierung von llkd überwacht weder init, [kthreadd] noch [kthreadd] ertönt. Für llkd, um [kthreadd]-erzeugte Threads abzudecken:

  • Treiber dürfen nicht in einem dauerhaften D-Zustand bleiben,

ODER

  • Treiber müssen Mechanismen zur Wiederherstellung des Threads haben, falls er gelöscht wird extern zu kommunizieren. Verwenden Sie z. B. wait_event_interruptible() anstelle von wait_event().

Wenn eine der oben genannten Bedingungen erfüllt ist, kann die llkd-Sperrliste angepasst werden: die Kernel-Komponenten behandeln. Die Stack-Symbolprüfung erfordert einen zusätzlichen Prozess Sperrliste, um Richtlinienverstöße bei Diensten zu verhindern, die ptrace blockieren Geschäftsabläufe.

Android-Properties

llkd reagiert auf verschiedene Android-Properties (siehe unten).

  • Attribute mit dem Namen „prop_ms“ werden in Millisekunden angegeben.
  • Bei Eigenschaften, in denen als Trennzeichen ein Komma (,) verwendet wird, wird ein vorangestelltes Trennzeichen verwendet, behalten den Standardeintrag bei und addieren oder subtrahieren dann Einträge mit optionalen Plus- Präfixe (+) bzw. Minuszeichen (-) Für diese Listen ist der String false gleichbedeutend mit einer leeren Liste ist, und leere oder fehlende Einträge führen zur Standardwert festgelegt.

ro.config.low_ram

Das Gerät ist mit begrenztem Arbeitsspeicher konfiguriert.

ro.debuggable

Das Gerät ist für UserDebug oder Engine-Build konfiguriert.

ro.llk.sysrq_t

Wenn das Attribut eng ist, ist der Standardwert weder ro.config.low_ram noch ro.debuggable. Wenn true, löschen Sie alle Threads (sysrq t).

ro.llk.enable

Aktivieren des Live-Sperr-Daemons zulassen. Die Standardeinstellung ist false.

llk.enable

Für Entwickler-Builds bewertet. Die Standardeinstellung ist ro.llk.enable.

ro.khungtask.enable

Aktivieren des [khungtask]-Daemons zulassen. Der Standardwert ist false.

khungtask.enable

Für Entwickler-Builds bewertet. Die Standardeinstellung ist ro.khungtask.enable.

ro.llk.mlockall

Anruf an mlockall() aktivieren. Der Standardwert ist false.

ro.khungtask.timeout

Maximale Dauer: [khungtask]. Der Standardwert ist 12 Minuten.

ro.llk.timeout_ms

D oder Z. Der Standardwert ist 10 Minuten. Verdoppeln Sie diesen Wert, um Alarm-Watchdog für llkd.

ro.llk.D.timeout_ms

D maximale Zeitbeschränkung. Die Standardeinstellung ist ro.llk.timeout_ms.

ro.llk.Z.timeout_ms

Z. Die Standardeinstellung ist ro.llk.timeout_ms.

ro.llk.stack.timeout_ms

Prüft auf das maximale Zeitlimit für persistente Stack-Symbole. Standardwert ist ro.llk.timeout_ms Nur bei Fehlerbehebungs- oder Entwicklungsteams aktiv.

ro.llk.check_ms

Gewebeproben für D oder Z. Die Standardeinstellung beträgt zwei Minuten.

ro.llk.stack

Prüft auf Kernel-Stack-Symbole, die, wenn sie dauerhaft vorhanden sind, auf einen dass das Subsystem gesperrt ist. Standardwert ist cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable eine durch Kommas getrennte Liste von Kernel-Symbolen. Bei der Prüfung ist keine Vorwärtsterminierung möglich ABA, außer durch Abfragen alle ro.llk_check_ms im Zeitraum ro.llk.stack.timeout_ms, daher sollten Stapelsymbole außergewöhnlich selten sein und flüchtig (es ist sehr unwahrscheinlich, dass ein Symbol überall auf der Welt des Stacks). Sucht nach einer Übereinstimmung mit symbol+0x oder symbol.cfi+0x bei Stack-Erweiterung. Nur bei „UserDebug“ oder „Engineering“ verfügbar Builds Sicherheitsbedenken hinsichtlich Nutzer-Builds zu eingeschränkten Berechtigungen führen, um diese Überprüfung zu verhindern.

ro.llk.blacklist.process

llkd überwacht die angegebenen Prozesse nicht. Der Standardwert ist 0,1,2 (kernel, init und [kthreadd]) plus Prozessnamen init,[kthreadd],[khungtaskd],lmkd,llkd,watchdogd, [watchdogd],[watchdogd/0],...,[watchdogd/get_nprocs-1] Ein Prozess kann eine comm-, cmdline- oder pid-Referenz sein. Automatisierter Standard kann größer sein als die aktuelle maximale Property-Größe von 92.

ro.llk.blacklist.parent

llkd überwacht keine Prozesse, die die angegebenen übergeordneten Elemente haben. Standardeinstellung ist 0,2,adbd&[setsid] (kernel, [kthreadd] und adbd nur für Zombies setsid. Das kaufmännische Und-Zeichen (&) gibt an, dass das übergeordnete Element nur ignoriert wird. in Kombination mit dem Ziel- untergeordneten Prozess zu verwenden. Kaufmännisches Und-Zeichen wurde ausgewählt, ist niemals Teil eines Prozessnamens; Für setprop in der Shell ist jedoch die Et-Zeichen (&) müssen mit Escapezeichen versehen oder in Anführungszeichen gesetzt werden, obwohl die Datei init rc, in der dieses Zeichen normalerweise nicht auftreten. Ein übergeordneter oder Zielprozess kann ein Referenz zu comm, cmdline oder pid.

ro.llk.blacklist.uid

Der llkd überwacht keine Prozesse, die den angegebenen UIDs entsprechen. Durch Kommas getrennte Liste von UIS-Nummern oder -Namen. Der Standardwert ist leer oder false.

ro.llk.blacklist.process.stack

llkd überwacht nicht die angegebene Teilmenge von Prozessen für Live-Sperrstacks Signaturen. Standardeinstellung ist Prozessnamen init,lmkd.llkd,llkd,keystore,ueventd,apexd,logd Verhindert die sepolicy Verstöße in Zusammenhang mit Prozessen, die ptrace blockieren, da diese nicht aktiviert). Nur bei Debugging- und Entwickler-Builds aktiv Weitere Informationen zum Build finden Sie unter Android erstellen.

Architektonische Bedenken

  • Eigenschaften sind auf 92 Zeichen beschränkt. Bei Standardeinstellungen wird dies jedoch ignoriert. in den Quellen in der Datei include/llkd.h definiert.
  • Der integrierte [khungtask]-Daemon ist zu allgemein und verwendet Treibercode, zu oft im D-Zustand umher. Ein Wechsel zu „S“ würde Aufgaben killbar machen. (und bei Bedarf von den Fahrern wiederbeleben zu lassen).

Bibliotheksoberfläche (optional)

Optional können Sie die llkd in einen anderen privilegierten Daemon einbinden. folgende C-Schnittstelle der Komponente libllkd:

#include "llkd.h"
bool llkInit(const char* threadname) /* return true if enabled */
unsigned llkCheckMillseconds(void)   /* ms to sleep for next check */

Wenn ein Threadname angegeben wird, wird automatisch ein Thread erstellt. Andernfalls wird der Aufrufer erstellt. muss llkCheckMilliseconds in seiner Hauptschleife aufrufen. Die Funktion gibt den Fehlerwert Zeitraum bis zum nächsten erwarteten Aufruf an diesen Handler.