Файлы System/bin Android 12. Справочник.


  Все     Команда     Скрипт     Служба     Приложение  

llkd
Служба обнаружения взаимоблокировок ядра и их устранения

Тип файла: служба
  Eng  

Android Live-LocK Daemon

   

Комментарии
https://android.googlesource.com/platform/system/core/+/android-o-mr1-iot-release-1.0.3/llkd/README.md

Демон Android Live-LocK

ВВЕДЕНИЕ

Android Live-LocK Daemon (llkd) используется для обнаружения взаимоблокировок ядра и их устранения.

Код структурирован так, чтобы обеспечить интеграцию в другой сервис либо как часть основного цикла, либо как отдельный поток, если это необходимо. Автономная реализация по умолчанию предоставляется компонентом llkd.

Интерфейс «C» компонента libllkd выглядит следующим образом:

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

Если указано имя потока, поток будет создан автоматически, в противном случае вызывающая сторона должна вызвать llkCheckMilliсекунды в своем основном цикле.
Функция вернет период времени до следующего ожидаемого вызова этого обработчика.

ОПЕРАЦИИ

Если поток находится в состоянии D или Z и не продвигается вперед дольше, чем ro.llk.timeout_ms или ro.llk.[D|Z].timeout_ms, уничтожьте процесс или родительский процесс соответственно.
Если другое сканирование показывает, что тот же процесс продолжает существовать, значит, у вас подтвержденное состояние активной блокировки и вам нужно паниковать.
Паникуйте ядро таким образом, чтобы предоставить максимально подробную информацию об ошибке относительно состояния.
Добавьте сигнализацию самоконтроля на случай, если она когда-нибудь заблокируется, что в два раза превышает ожидаемое время прохождения через основной цикл. Выборка производится каждый ro.llk_sample_ms.

По умолчанию не будет отслеживаться инициализация или [kthreadd] и все, что порождает [kthreadd].
Это снижает эффективность llkd за счет ограничения его охвата.
Если есть смысл закрыть потоки, порожденные [kthreadd], требование будет состоять в том, чтобы драйверы не оставались в постоянном состоянии «D» или чтобы у них были механизмы для восстановления потока в случае его закрытия извне (это хорошая гигиена кодирования драйверов), распространенный запрос на добавление таких драйверов в общедоступные драйверы, поддерживаемые kernel.org).
Например, используйте wait_event_interruptible() вместо wait_event().
Черные списки могут быть скорректированы соответствующим образом, если эти условия выполняются для охвата компонентов ядра.

Был добавлен сопутствующий набор gTest, который настроит постоянный процесс D или Z с продвижением вперед или без него, но не в состоянии активной блокировки, поскольку для стимулирования потребуется ядро с ошибками или модификация модуля или ядра.
Тест проверит, что llkd сначала устранит проблему, убив соответствующий процесс.
Состояние D устанавливается с помощью vfork(), ожидающего exec() в дочернем процессе.
Состояние Z устанавливается с помощью fork() и неожиданного дочернего процесса.
Следует отметить, что оба этих условия никогда не должны возникать в Android намеренно, и llkd эффективно устраняет процессы, которые создают эти условия.
Если тест сможет это сделать, он перенастроит llkd, чтобы ускорить продолжительность теста, изменив свойства ro.llk.* Android.
Тесты запускают состояние D с некоторым прогрессом планирования, чтобы гарантировать, что проверка ABA предотвращает ложные срабатывания.
Если на платформе 100% надежный ABA, то для ro.llk.killtest можно установить значение false;
однако это приведет к тому, что некоторые модульные тесты вызовут панику ядра вместо более изящной операции уничтожения.

СВОЙСТВА ANDROID

Android Properties llkd отвечает на (параметры _ms указаны в миллисекундах):

ro.config.low_ram - по умолчанию false, если true, не выполнять sysrq t (дамп всех потоков)

ro.llk.enable - по умолчанию false, разрешить включение демона live-lock

llk.enable - по умолчанию ro.llk.enable и оценен на англ

ro.khungtask.enable - по умолчанию false, разрешить включение демона [khungtask]

khungtask.enable - по умолчанию ro.khungtask.enable и оценен на англ

ro.llk.mlockall - по умолчанию false, включить вызов mlockall()

ro.khungtask.timeout - значение по умолчанию 12 минут, максимальный срок [khungtask]

ro.llk.timeout_ms - по умолчанию 10 минут, максимальный срок D или Z, удвойте это значение, и будет установлен сторожевой таймер для llkd

ro.llk.D.timeout_ms - по умолчанию ro.llk.timeout_ms, максимальный срок D

ro.llk.Z.timeout_ms - по умолчанию ro.llk.timeout_ms, максимальный срок Z

ro.llk.check_ms - по умолчанию 2-минутные образцы резьб для D или Z

ro.llk.blacklist.process - по умолчанию 0,1,2 (ядро, init и [kthreadd]) плюс имена процессов init,[kthreadd],[khungtaskd],lmkd,lmkd.llkd,llkd,watchdogd, [watchdogd],[watchdogd/0],.. .,[watchdogd/<get_nprocs-1>]

ro.llk.blacklist.parent - по умолчанию 0,2 (ядро и [kthreadd])

ro.llk.blacklist.uid - default , список номеров или имен uid, разделенных запятыми

АРХИТЕКТУРНЫЕ ПРОБЛЕМЫ

Создайте модуль ядра и связанный с ним gTest, чтобы проверить панику.
Создайте gTest для проверки черного списка (ro.llk.blacklist. обычно не является входными данными).
Может потребоваться больше интерфейсов только для тестирования для libllkd.
Ускорьте gTest, используя что-то другое, кроме ro.llk., которое не должно быть входными данными.



https://source.android.com/docs/core/architecture/kernel/llkd

Демон Android Live-LocK (llkd)

В состав Android 10 входит демон Android Live-LocK ( llkd), который предназначен для обнаружения и устранения взаимоблокировок ядра. Компонент llkd предоставляет автономную реализацию по умолчанию, но вы также можете интегрировать llkdкод в другую службу либо как часть основного цикла, либо как отдельный поток.

СЦЕНАРИИ ОБНАРУЖЕНИЯ

Существует два сценария обнаружения llkd: постоянное состояние D или Z и постоянная подпись стека.

Постоянное состояние D или Z

Если поток находится в состоянии D (непрерывный сон) или Z (зомби) и не продвигается вперед дольше ro.llk.timeout_ms or ro.llk.[D|Z].timeout_ms, llkdпроцесс (или родительский процесс) завершается.

Если последующее сканирование показывает, что тот же процесс продолжает существовать, это llkdподтверждает состояние активной блокировки и вызывает панику ядра таким образом, чтобы предоставить наиболее подробный отчет об ошибке для этого состояния.

В llkd комплект входит функция самоконтроля, которая подает сигнал тревоги в случае llkdблокировки; сторожевой таймер в два раза превышает ожидаемое время прохождения через основной цикл, а выборка выполняется каждые ro.llk_sample_ms.

Постоянная подпись стека

Для выпусков пользовательской отладки они llkdмогут обнаруживать живые блокировки ядра с помощью постоянной проверки подписи стека.
Если поток в любом состоянии, кроме Z, имеет постоянный указанный ro.llk.stackсимвол ядра, о котором сообщается дольше ro.llk.timeout_msили ro.llk.stack.timeout_ms, llkdпроцесс завершается (даже если выполняется прямое планирование).
Если последующее сканирование показывает, что тот же процесс продолжает существовать, это llkdподтверждает состояние активной блокировки и вызывает панику ядра таким образом, чтобы предоставить наиболее подробный отчет об ошибке для этого состояния.

Примечание.
Поскольку прогресс планирования вперед разрешен, обнаружение ABAllkd не выполняется.

Проверка llkd продолжается постоянно, пока существует условие оперативной блокировки, и ищет составные строки " symbol+0x"или " symbol.cfi+0x"файл /proc/pid/stackв Linux.

Список символов по ro.llk.stackумолчанию представляет собой список символов " cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable", разделенных запятыми.

Символы должны быть редкими и достаточно недолговечными, чтобы в типичной системе функция отображалась только один раз в выборке в течение периода ожидания ro.llk.stack.timeout_ms(выборки происходят каждые ro.llk.check_ms). Из-за отсутствия защиты ABA это единственный способ предотвратить ложный срабатывание. Функция символа должна располагаться ниже функции, вызывающей блокировку, которая может конкурировать. Если блокировка находится ниже или в функции символа, символ появляется во всех затронутых процессах, а не только в том, который вызвал блокировку.

ПОКРЫТИЕ

Реализация по умолчанию llkd не отслеживает init, [kthreadd] или [kthreadd] не порождает.
Чтобы llkd скрыть [kthreadd] порожденные темы:

Драйверы не должны оставаться в постоянном состоянии D

ИЛИ

Драйверы должны иметь механизмы восстановления потока в случае его внешнего завершения.
Например, используйте wait_event_interruptible()вместо wait_event().

Если одно из вышеперечисленных условий соблюдено, llkd черный список можно настроить так, чтобы он охватывал компоненты ядра.
Проверка символов стека включает дополнительный черный список процессов для предотвращения нарушений политики конфиденциальности в службах, которые блокируют ptrace операции.

СВОЙСТВА ANDROID

Отвечает llkd на несколько свойств Android (перечисленных ниже).

Названия свойств prop_ms указаны в миллисекундах.

Свойства, в которых для списков используется разделитель-запятая (,), используют ведущий разделитель, чтобы сохранить запись по умолчанию, а затем добавляют или вычитают записи с необязательными префиксами плюс (+) и минус (-) соответственно.

Для этих списков строка «false» является синонимом пустого списка, а пустые или отсутствующие записи используют указанное значение по умолчанию.

ro.config.low_ram - Устройство настроено с ограниченным объемом памяти

ro.debuggable - Устройство настроено для пользовательской отладки или сборки на английском языке

ro.llk.sysrq_t - Если свойство имеет значение «eng», значение по умолчанию — нет ro.config.low_ramили ro.debuggable. Если это правда, выгрузить все потоки ( sysrq t).

ro.llk.enable - Разрешить включение демона live-lock. По умолчанию — ложь

llk.enable - Оценивается для англоязычных сборок. По умолчанию ro.llk.enable

ro.khungtask.enable - Разрешить [khungtask]включение демона. По умолчанию — ложь

khungtask.enable - Оценивается для англоязычных сборок. По умолчанию ro.khungtask.enable

ro.llk.mlockall - Включить вызов на mlockall(). По умолчанию — ложь

ro.khungtask.timeout - [khungtask] максимальный срок. По умолчанию — 12 минут

ro.llk.timeout_ms - Максимальный срок D или Z. По умолчанию — 10 минут
Удвойте это значение, чтобы установить сторожевой таймер для llkd

ro.llk.D.timeout_ms - D максимальный срок. По умолчанию ro.llk.timeout_ms

ro.llk.Z.timeout_ms - Z максимальный срок. По умолчанию ro.llk.timeout_ms

ro.llk.stack.timeout_ms - Проверяет максимальный срок хранения символов постоянного стека.
По умолчанию ro.llk.timeout_ms. Активно только в сборках userdebug или eng .

ro.llk.check_ms - Примеры тем для D или Z. По умолчанию — две минуты

ro.llk.stack - Проверяет символы стека ядра, которые, если они постоянно присутствуют, могут указывать на то, что подсистема заблокирована. По умолчанию — cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable список символов ядра, разделенный запятыми.

Проверка не выполняет ABA прямого планирования, за исключением опроса каждого ro.llk_check_msза период ro.llk.stack.timeout_ms, поэтому символы стека должны быть исключительно редкими и мимолетными (очень маловероятно, чтобы символ постоянно появлялся во всех образцах стека).

Проверяет совпадение " symbol+0x"или " symbol.cfi+0x"расширение стека. Доступно только в сборках userdebug или eng ; проблемы безопасности в пользовательских сборках приводят к ограничению привилегий, которые препятствуют этой проверке.

ro.llk.blacklist.process - Не следит llkdза указанными процессами. По умолчанию это 0,1,2( kernel, initи [kthreadd]) плюс имена процессов init,[kthreadd],[khungtaskd],lmkd,llkd,watchdogd, [watchdogd],[watchdogd/0],...,[watchdogd/get_nprocs-1].

Процесс может быть comm, cmdline или pid ссылкой.
Автоматическое значение по умолчанию может превышать текущий максимальный размер свойства, равный 92

Примечание.
Занесение в черный список крайне маловероятно false

ro.llk.blacklist.parent - Не отслеживает процессы, имеющие указанных родительских элементов. По умолчанию 0,2,adbd&[setsid] ( kernel, [kthreadd] и adbd только для зомби setsid).

Разделитель амперсанд (&) указывает, что родительский процесс игнорируется только в сочетании с целевым дочерним процессом. Был выбран амперсанд, поскольку он никогда не является частью имени процесса; однако a setprop в оболочке требует, чтобы амперсанд был экранирован или заключен в кавычки, хотя в init rc файле, где это обычно указывается, такой проблемы нет. Родительский или целевой процесс может быть comm, cmdline или pid ссылкой.

ro.llk.blacklist.uid - Не отслеживает процессы, соответствующие указанным uid(ам).
Список номеров или имен uid, разделенных запятыми. По умолчанию пусто или ложно.

ro.llk.blacklist.process.stack - Не llkdотслеживает указанное подмножество процессов на наличие сигнатур стека действующих блокировок. По умолчанию — имена процессов init,lmkd.llkd,llkd,keystore,ueventd,apexd,logd. Предотвращает нарушение политики конфиденциальности, связанное с блокирующими процессами ptrace(поскольку их невозможно проверить). Активен только в сборках userdebug и eng. Подробную информацию о типах сборки см. в разделе Сборка Android .

АРХИТЕКТУРНЫЕ ПРОБЛЕМЫ

Свойства ограничены 92 символами (однако это игнорируется для значений по умолчанию,
определенных в include/llkd.h файле в источниках).

Встроенный [khungtask] демон слишком общий и срабатывает на коде драйвера, который слишком долго находится в состоянии D. Переключение на S сделает задачу(и) удаляемыми (и при необходимости восстанавливаемыми драйверами).


ИНТЕРФЕЙС БИБЛИОТЕКИ (опционально)

При желании вы можете включить llkd в другой привилегированный демон, используя следующий интерфейс C из libllkdкомпонента:

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

Если указано имя потока, поток создается автоматически, в противном случае вызывающая сторона должна вызвать llkCheckMilliseconds свой основной цикл.
Функция возвращает период времени до следующего ожидаемого вызова этого обработчика.