O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Android Live-LocK Daemon (llkd)

Android 10 inclui o Android Vivo-lock Daemon ( llkd ), que é projetado para captura e mitigar kernel do impasses. O llkd componente fornece uma implementação independente padrão, mas você pode, alternativamente, integrar o llkd código em outro serviço, como parte do circuito principal ou como um segmento separado.

Cenários de detecção

O llkd tem dois cenários de detecção: D persistente ou estado de Z, e de assinatura pilha persistente.

Estado D ou Z persistente

Se um fio é em D (sono ininterrupta) ou estado Z (zombie) com nenhum progresso para a frente por mais de ro.llk.timeout_ms or ro.llk.[D|Z].timeout_ms , o llkd mata o (ou processo pai processo ) Se um subseqüentes shows de digitalização do mesmo processo continua a existir, o llkd confirma uma condição live-bloqueio e pânicos o kernel de uma maneira que fornece o relatório de erro mais detalhada para a condição.

O llkd inclui uma auto watchdog que os alarmes se llkd trava; watchdog é o dobro do tempo esperado para fluir através do mainloop e amostragem é cada ro.llk_sample_ms .

Assinatura de pilha persistente

Para versões userdebug, o llkd pode detectar núcleo vivo de portas usando persistente verificação de assinatura pilha. Se um fio em qualquer estado, exceto Z tem um listados persistente ro.llk.stack símbolo do kernel que é relatado por mais de ro.llk.timeout_ms ou ro.llk.stack.timeout_ms , o llkd mata o processo (mesmo se houver a frente progresso de programação). Se um subseqüentes shows de digitalização do mesmo processo continua a existir, o llkd confirma uma condição live-bloqueio e pânicos o kernel de uma maneira que fornece o relatório de erro mais detalhada para a condição.

Os lldk persiste verificar continuamente quando a condição de bloqueio ao vivo existe e olha para as cordas compostas " symbol+0x" ou " symbol.cfi+0x" no /proc/pid/stack de arquivos no Linux. A lista de símbolos é em ro.llk.stack e padrões para a lista separados por vírgulas de " cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable ".

Os símbolos devem ser raros e de curta duração suficiente para que em um sistema típico a função é visto apenas uma vez em uma amostra durante o período de tempo limite de ro.llk.stack.timeout_ms (amostras ocorrem a cada ro.llk.check_ms ). Devido à falta de proteção ABA, esta é a única maneira de prevenir um falso gatilho. A função do símbolo deve aparecer abaixo da função que chama o bloqueio que pode contender. Se o bloqueio estiver abaixo ou na função do símbolo, o símbolo aparecerá em todos os processos afetados, não apenas no que causou o bloqueio.

Cobertura

A implementação padrão de llkd não monitora init , [kthreadd] , ou [kthreadd] desova. Para o llkd a tampa [kthreadd] tópicos -spawned:

  • Os motoristas não devem permanecer em um estado D persistente,

OU

  • Os drivers devem ter mecanismos para recuperar o encadeamento caso ele seja eliminado externamente. Por exemplo, o uso wait_event_interruptible() em vez de wait_event() .

Se uma das condições acima for atendida, o llkd lista negra pode ser ajustado para componentes de kernel tampa. Pilha símbolo verificação envolve uma lista negra processo adicional para evitar violações sepolicy sobre serviços que bloqueiam ptrace operações.

Propriedades Android

Os llkd responde a várias propriedades Android (listados abaixo).

  • Propriedades nomeadas prop_ms estão em milissegundos.
  • As propriedades que usam o separador de vírgula (,) para listas usam um separador à esquerda para preservar a entrada padrão e, em seguida, adiciona ou subtrai as entradas com prefixos opcionais de mais (+) e menos (-), respectivamente. Para essas listas, a string "false" é sinônimo de uma lista vazia e as entradas em branco ou ausentes recorrem ao valor padrão especificado.

ro.config.low_ram

O dispositivo está configurado com memória limitada.

ro.debuggable

O dispositivo está configurado para userdebug ou eng build.

ro.llk.sysrq_t

Se a propriedade é "eng", o padrão não é ro.config.low_ram ou ro.debuggable . Se for verdade, despejar os tópicos ( sysrq t ).

ro.llk.enable

Permitir que o daemon live-lock seja habilitado. O padrão é falso.

llk.enable

Avaliado para builds de eng. O padrão é ro.llk.enable .

ro.khungtask.enable

Permitir [khungtask] daemon a ser habilitado. O padrão é falso.

khungtask.enable

Avaliado para builds de eng. O padrão é ro.khungtask.enable .

ro.llk.mlockall

Ativar chamada para mlockall() . O padrão é falso.

ro.khungtask.timeout

[khungtask] máximo limite de tempo. O padrão é 12 minutos.

ro.llk.timeout_ms

Limite de tempo máximo D ou Z. O padrão é 10 minutos. Dobrar este valor para definir o cão de guarda de alarme para llkd .

ro.llk.D.timeout_ms

D limite de tempo máximo. O padrão é ro.llk.timeout_ms .

ro.llk.Z.timeout_ms

Limite máximo de tempo Z. O padrão é ro.llk.timeout_ms .

ro.llk.stack.timeout_ms

Verifica o limite de tempo máximo dos símbolos da pilha persistente. O padrão é ro.llk.timeout_ms . Ativo somente em userdebug ou eng constrói.

ro.llk.check_ms

Amostras de threads para D ou Z. O padrão é dois minutos.

ro.llk.stack

Verifica os símbolos da pilha do kernel que, se persistentemente presentes, podem indicar que um subsistema está bloqueado. O padrão é cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable lista separada por vírgulas de símbolos do kernel. A verificação não faz ABA agendamento para a frente, exceto por polling a cada ro.llk_check_ms durante o período ro.llk.stack.timeout_ms , então símbolos pilha deve ser excepcionalmente raro e fugaz (é altamente improvável para um símbolo para mostrar-se persistentemente em todos amostras da pilha). Verifica se há uma correspondência para " symbol+0x" ou " symbol.cfi+0x" na expansão da pilha. Disponível apenas em userdebug ou eng constrói; preocupações de segurança em compilações de usuário resultam em privilégios limitados que evitam essa verificação.

ro.llk.blacklist.process

O llkd não assistir os processos especificados. O padrão é 0,1,2 ( kernel , init , e [kthreadd] ), mais nomes de processo init,[kthreadd],[khungtaskd],lmkd,llkd,watchdogd, [watchdogd],[watchdogd/0],...,[watchdogd/get_nprocs-1] . Um processo pode ser um comm , cmdline , ou pid referência. Um padrão automatizado pode ser maior do que o tamanho máximo de propriedade atual de 92.

ro.llk.blacklist.parent

O llkd não assiste processos que têm o pai especificado (s). O padrão é 0,2,adbd&[setsid] ( kernel , [kthreadd] , e adbd apenas para zombie setsid ). Um separador e comercial (&) especifica que o pai é ignorado apenas em combinação com o processo filho de destino. O e comercial foi selecionado porque nunca faz parte do nome de um processo; no entanto, um setprop no shell requer o comercial ser escapado ou cotados, embora o init rc arquivo onde esta é normalmente especificada não tem esse problema. Um processo pai ou alvo pode ser um comm , cmdline , ou pid referência.

ro.llk.blacklist.uid

O llkd não assiste processos que correspondem aos especificados uid (s). Lista separada por vírgulas de números ou nomes de uid. O padrão é vazio ou falso.

ro.llk.blacklist.process.stack

O llkd não monitora o subconjunto específico de processos para assinaturas pilha de bloqueio ao vivo. O padrão é nomes de processo init,lmkd.llkd,llkd,keystore,ueventd,apexd,logd . Impede que a violação sepolicy associada a processos que bloqueiam ptrace (uma vez que estes não podem ser verificadas). Ativo somente em userdebug e eng constrói. Para mais detalhes sobre tipos de compilação, consulte Construção Android .

Preocupações arquitetônicas

  • Propriedades estão limitados a 92 caracteres (no entanto, isso é ignorado para padrões definidos no include/llkd.h arquivo nas fontes).
  • A built-in [khungtask] daemon é muito genérico e viagens no código do driver que fica em torno de estado D demais. Mudar para S tornaria as tarefas elimináveis ​​(e ressuscitáveis ​​pelos motoristas, se necessário).

Interface da biblioteca (opcional)

Opcionalmente, é possível incorporar o llkd em outro daemon privilegiado, usando a seguinte interface C do libllkd componente:

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

Se um threadname é fornecido, um fio automaticamente desova, caso contrário, o chamador deve chamar llkCheckMilliseconds em seu loop principal. A função retorna o período de tempo antes da próxima chamada esperada para este manipulador.