Ponto de verificação de dados do usuário (UDC)

O Android 10 apresenta o User Data Checkpoint (UDC), que permite que o Android volte ao estado anterior quando uma atualização do Android over-the-air (OTA) falha. Com o UDC, se uma atualização do Android OTA falhar, o dispositivo poderá voltar ao estado anterior com segurança. Embora as atualizações A/B resolvam esse problema para inicialização antecipada, a reversão não é suportada quando a partição de dados do usuário (montada em /data ) é modificada.

O UDC permite que o dispositivo reverta a partição de dados do usuário mesmo após ser modificado. O recurso UDC faz isso com recursos de ponto de verificação para o sistema de arquivos, uma implementação alternativa quando o sistema de arquivos não oferece suporte a pontos de verificação, integração com o mecanismo A/B do carregador de inicialização ao mesmo tempo em que oferece suporte a atualizações não A/B e suporte para vinculação de versão de chave e prevenção de reversão de chave.

Impacto do usuário

O recurso UDC melhora a experiência de atualização OTA para os usuários, pois menos usuários perdem seus dados quando uma atualização OTA falha. Isso pode reduzir o número de chamadas de suporte de usuários que enfrentam problemas durante o processo de atualização. No entanto, quando uma atualização OTA falha, os usuários podem notar que o dispositivo é reinicializado várias vezes.

Como funciona

Funcionalidade de ponto de verificação em diferentes sistemas de arquivos

Para o sistema de arquivos F2FS, o UDC adiciona a funcionalidade de ponto de verificação ao kernel Linux 4.20 upstream e o retroporta para todos os kernels comuns suportados por dispositivos que executam o Android 10.

Para outros sistemas de arquivos, o UDC usa um dispositivo virtual mapeador de dispositivo chamado dm_bow para funcionalidade de ponto de verificação. dm_bow fica entre o dispositivo e o sistema de arquivos. Quando uma partição é montada, um trim é emitido, fazendo com que o sistema de arquivos emita comandos de trim em todos os blocos livres. dm_bow intercepta esses trims e os usa para configurar uma lista de bloqueio livre. As leituras e gravações são enviadas para o dispositivo sem modificações, mas antes que uma gravação seja permitida, os dados necessários para uma restauração são copiados para um bloco livre.

Processo de verificação

Quando uma partição com o sinalizador checkpoint=fs/block é montada, o Android chama restoreCheckpoint na unidade para permitir que o dispositivo restaure qualquer checkpoint atual. O init então chama a função needsCheckpoint para determinar se o dispositivo está em um estado A/B do carregador de inicialização ou definiu a contagem de novas tentativas de atualização. Se um deles for verdadeiro, o Android chama createCheckpoint para adicionar sinalizadores de montagem ou construir um dispositivo dm_bow .

Depois que a partição é montada, o código do ponto de verificação é chamado para emitir trims. O processo de inicialização continua normalmente. Em LOCKED_BOOT_COMPLETE , o Android chama commitCheckpoint para confirmar o checkpoint atual e a atualização continua normalmente.

Gerenciando chaves mestras

As chaves Keymaster são usadas para criptografia de dispositivos ou outros propósitos. Para gerenciar essas chaves, o Android atrasa as chamadas de exclusão de chave até que o ponto de verificação seja confirmado.

Monitorando a integridade

Um daemon de integridade verifica se há espaço em disco suficiente para criar um ponto de verificação. O daemon de integridade está localizado em cp_healthDaemon em Checkpoint.cpp .

O daemon de integridade tem os seguintes comportamentos que podem ser configurados:

  • ro.sys.cp_msleeptime : Controla a frequência com que o dispositivo verifica o uso do disco.
  • ro.sys.cp_min_free_bytes : Controla o valor mínimo que o daemon de integridade procura.
  • ro.sys.cp_commit_on_full : Controla se o daemon de integridade reinicializa o dispositivo ou confirma o ponto de verificação e continua quando o disco está cheio.

APIs de ponto de verificação

As APIs de ponto de verificação são usadas pelo recurso UDC. Para outras APIs usadas pelo UDC, consulte IVoid.aidl .

void startCheckpoint(int retry)

Cria um ponto de verificação.

A estrutura chama esse método quando está pronta para iniciar uma atualização. O ponto de verificação é criado antes que os sistemas de arquivos com ponto de verificação, como userdata, sejam montados em R/W após a reinicialização. Se a contagem de novas tentativas for positiva, a API lidará com novas tentativas de rastreamento e o atualizador chamará needsRollback para verificar se uma reversão da atualização é necessária. Se a contagem de novas tentativas for -1 , a API adiará o julgamento do carregador de inicialização A/B.

Este método não é chamado ao fazer uma atualização A/B normal.

void commitAlterações()

Confirma as alterações.

A estrutura chama esse método após a reinicialização quando as alterações estão prontas para serem confirmadas. Isso é chamado antes que os dados (como fotos, vídeo, SMS, recibo de recebimento do servidor) sejam gravados em userdata e antes BootComplete .

Se não existir nenhuma atualização de ponto de verificação ativa, esse método não terá efeito.

abortChanges()

Força a reinicialização e reverte para o ponto de verificação. Abandona todas as modificações de dados do usuário desde a primeira reinicialização.

A estrutura chama esse método após a reinicialização, mas antes commitChanges . retry_counter é reduzido quando esse método é chamado. As entradas de log são geradas.

bool precisaRollback()

Determina se uma reversão é necessária.

Em dispositivos sem ponto de verificação, retorna false . Em dispositivos de ponto de verificação, retorna true durante uma inicialização sem ponto de verificação.

Implementando UDC

Implementação de referência

Para obter um exemplo de como o UDC pode ser implementado, consulte dm-bow.c . Para documentação adicional sobre o recurso, consulte dm-bow.txt .

Configuração

Em on fs em seu arquivo init.hardware.rc , certifique-se de ter:

mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --early

Em on late-fs em seu arquivo init.hardware.rc , certifique-se de ter:

mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --late

Em seu arquivo fstab.hardware , certifique-se de que /data esteja marcado como latemount .

/dev/block/bootdevice/by-name/userdata              /data              f2fs
noatime,nosuid,nodev,discard,reserve_root=32768,resgid=1065,fsync_mode=nobarrier
latemount,wait,check,fileencryption=ice,keydirectory=/metadata/vold/metadata_encryption,quota,formattable,sysfs_path=/sys/devices/platform/soc/1d84000.ufshc,reservedsize=128M,checkpoint=fs

Adicionando partição de metadados

O UDC requer uma partição de metadados para armazenar as chaves e a contagem de novas tentativas do não carregador de inicialização. Configure uma partição de metadados e monte-a antecipadamente em /metadata .

Em seu arquivo fstab.hardware , certifique-se de que /metadata esteja marcado como earlymount ou first_stage_mount .

/dev/block/by-name/metadata           /metadata           ext4
noatime,nosuid,nodev,discard,sync
wait,formattable,first_stage_mount

Inicialize a partição com todos os zeros.

Adicione as seguintes linhas ao BoardConfig.mk :

BOARD_USES_METADATA_PARTITION := true
BOARD_ROOT_EXTRA_FOLDERS := existing_folders metadata

Atualizando sistemas

Sistemas F2FS

Para sistemas que usam F2FS para formatar dados, verifique se sua versão do F2FS oferece suporte a pontos de verificação. Para obter mais informações, consulte Funcionalidade de ponto de verificação em diferentes sistemas de arquivos .

Adicione o sinalizador checkpoint=fs à seção <fs_mgr_flags> do fstab para o dispositivo montado em /data .

Sistemas não F2FS

Para sistemas não F2FS, dm-bow deve estar habilitado na configuração do kernel.

Adicione o sinalizador checkpoint=block à seção <fs_mgr_flags> do fstab para o dispositivo montado em /data .

Verificando registros

As entradas de log são geradas quando as APIs do Checkpoint são chamadas.

Validação

Para testar sua implementação de UDC, execute o conjunto de testes VTS VtsKernelCheckpointTest .