Reinícios em segundo plano (<= AOSP 14)

O Android 11 oferece suporte a reinicializações em segundo plano, que são reinicializações de tempo de execução de processos no espaço do usuário usados para aplicar atualizações que exigem uma reinicialização, por exemplo, atualizações para pacotes APEX. No momento, a reinicialização suave é limitada a processos iniciados depois que userdata foi montado.

Um reinício em segundo plano é solicitado das seguintes maneiras:

  • De PowerManager, ligando para PowerManager.reboot(PowerManager.REBOOT_USERSPACE)

  • No shell, usando adb shell svc power reboot userspace ou adb reboot userspace

Após uma reinicialização parcial, o armazenamento criptografado por credenciais permanece desbloqueado.

Se um dispositivo for compatível com reinicializações leves, o método da API PowerManager.isRebootingUserspace() vai retornar true, e o valor da propriedade do sistema init.userspace_reboot.is_supported será igual a 1.

Se o dispositivo não for compatível com reinicializações leves, as chamadas para PowerManager.reboot(PowerManager.REBOOT_USERSPACE), adb reboot userspace e adb shell svc power reboot userspace vão falhar.

Execução de reinício em segundo plano

Depois que um reinício em segundo plano é solicitado (por PowerManager ou por um shell), init executa as seguintes etapas:

  1. Recebe sys.powerctl=reboot,userspace.

  2. Cria um processo UserspaceRebootWatchdogThread() separado para monitorar o reinício em segundo plano.

  3. Aciona uma ação userspace-reboot-requested, que redefine todas as propriedades do sistema que podem afetar o reinício em segundo plano. Propriedades afetadas:

    • sys.usb.config
    • sys.usb.state
    • sys.boot_completed
    • dev.bootcomplete
    • sys.init.updatable_crashing
    • sys.init.updatable_crashing_process_name
    • apexd.status
    • sys.user.0.ce_available
    • sys.shutdown.requested
    • service.bootanim.exit

    As propriedades acima precisam ser definidas novamente durante a sequência de inicialização. Se necessário, você pode redefinir outras propriedades. Para exemplos, consulte a ação on userspace-reboot-requested em rootdir/init.rc.

  4. Executa a função DoUserspaceReboot, que realiza as seguintes ações:

    1. Envia SIGTERM para processos iniciados depois que userdata foi montado e aguarda a interrupção deles.
    2. Depois que o tempo limite é atingido, envia SIGKILL para encerrar todos os processos em execução.
    3. Chama /system/bin/vdc volume reset.
    4. Desconecta o dispositivo de apoio do zRAM.
    5. Desmonta pacotes APEX ativos.
    6. Volta para o namespace de montagem de bootstrap.
    7. Aciona a ação userspace-reboot-resume.

Se o checkpoint do sistema de arquivos foi solicitado antes do reinício em segundo plano, o userdata será remontado no modo de checkpoint durante a ação userspace-reboot-fs-remount. Consulte a seção a seguir para mais detalhes. Um reinício em segundo plano é considerado depois que o sys.boot_completed property é definido como 1. No final da reinicialização suave, a tela permanece desligada e é necessária uma interação explícita do usuário para ativá-la.

Criação de checkpoints do sistema de arquivos

Se um ponto de controle do sistema de arquivos foi solicitado antes do reinício em segundo plano, o userdata será remontado no modo de ponto de controle durante o reinício em segundo plano. A lógica de remontagem é implementada na função fs_mgr_remount_userdata_into_checkpointing e varia entre os métodos de checkpoint. Especificamente, quando o userdata é compatível com:

  • Criação de checkpoints no nível do sistema de arquivos (por exemplo, f2fs), userdata é remontado com a opção checkpoint=disable.

  • Criação de pontos de verificação no nível do bloco (por exemplo, ext4). Em seguida, /data é desmontado e todos os dispositivos de mapeamento de dispositivo pai em que ele foi montado são destruídos. Em seguida, userdata é montado usando o mesmo caminho de código usado na inicialização normal de checkpointing.

Se um keyring no nível do sistema de arquivos for usado para gerenciar chaves criptografadas com credenciais (CE) e criptografadas com dispositivo (DE), as chaves serão perdidas depois que userdata for desmontado. Para permitir a restauração de chaves, ao instalar uma chave em um keyring do sistema de arquivos, o vold também instala a mesma chave do tipo fscrypt-provisioning no keyring no nível da sessão. Quando init_user0 é chamado, vold reinstala as chaves no keyring do sistema de arquivos.

Substituição por reinicialização forçada

Para garantir que um reinício em segundo plano não deixe um dispositivo em um estado inutilizável, o Android 11 inclui um substituto para reinicialização forçada que é acionado quando uma das seguintes condições é atendida:

  • Um dispositivo não inicia o reinício em segundo plano (ou seja, sys.init.userspace_reboot.in_progress=1) dentro de um determinado tempo limite.
  • Um processo não é interrompido dentro de um tempo limite especificado.
  • A operação /system/bin/vdc volume reset falha.
  • A desmontagem do dispositivo zRAM falha.
  • Um pacote APEX ativo é desmontado incorretamente.
  • Uma tentativa de remontar userdata no modo de checkpointing falha.
  • Um dispositivo não consegue inicializar (ou seja, sys.boot_completed=1) dentro de um tempo limite especificado.

Configuração por dispositivo

Alguns aspectos do reinício em segundo plano podem ser ajustados mudando os valores das seguintes propriedades:

  • init.userspace_reboot.is_supported controla quando um dispositivo pode fazer um reinício em segundo plano. Se o valor dessa propriedade for false, 0 ou não for especificado, as tentativas de reinicialização serão rejeitadas.
  • init.userspace_reboot.sigkill.timeoutmillis controla o tempo limite em milissegundos para processos que receberam um sinal SIGKILL para parar. Se um dos processos não for interrompido no tempo limite especificado, um fallback para reinicialização forçada será acionado.
  • init.userspace_reboot.sigterm.timeoutmillis controla o tempo limite em milissegundos para processos que receberam um sinal SIGTERM para serem encerrados. Todos os processos que não foram encerrados no tempo limite especificado recebem um sinal SIGKILL.
  • init.userspace_reboot.started.timeoutmillis controla o tempo limite em milissegundos para o início do reinício em segundo plano (ou seja, sys.init.userspace_reboot.in_progress=1). Se um dispositivo não iniciar o reinício em segundo plano dentro do tempo limite especificado, uma substituição por reinicialização forçada será acionada.
  • init.userspace_reboot.userdata_remount.timeoutmillis controla o tempo limite em milissegundos para desmontar userdata. Se um dispositivo não conseguir desmontar userdata dentro do tempo limite especificado, uma reinicialização forçada será acionada.
  • init.userspace_reboot.watchdog.timeoutmillis controla o tempo limite para que um dispositivo seja inicializado com sucesso (ou seja, sys.boot_completed=1). Se um dispositivo não for inicializado dentro do tempo limite especificado, um fallback para reinicialização forçada será acionado.

Personalizar a animação durante o reinício em segundo plano

A implementação de referência de um reinício em segundo plano inclui a capacidade de personalizar a animação mostrada durante o reinício em segundo plano.

Ao final da ação userspace-reboot-fs-remount, o init inicia o serviço bootanim. Esse serviço procura a existência dos seguintes arquivos de animação, na ordem listada, e reproduz o primeiro que encontrar:

  • /product/media/userspace-reboot.zip
  • /oem/media/userspace-reboot.zip
  • /system/media/userspace-reboot.zip
a seguir.

Se nenhum arquivo de animação específico de reinício em segundo plano for especificado, bootanim vai mostrar uma animação android padrão.

Teste

O Android 11 inclui uma implementação de referência de um reinício em segundo plano. Além disso, é possível verificar um reinício em segundo plano usando testes do CTS em UserspaceRebootHostTest.