O Android 10 apresenta o User Data Checkpoint (UDC), que permite que o Android volte ao seu 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 pode reverter com segurança para seu estado anterior. 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 depois de modificado. O recurso UDC realiza 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 ligação de versão 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 a reinicialização do dispositivo 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 upstream 4.20 e faz o backport 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 dispositivos 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. Leituras e gravações são entã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 ponto 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 ponto de verificação atual. 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 for verdadeiro, o Android chama createCheckpoint
para adicionar sinalizadores de montagem ou criar um dispositivo dm_bow
.
Depois que a partição é montada, o código do ponto de verificação é chamado para emitir cortes. O processo de inicialização continua normalmente. Em LOCKED_BOOT_COMPLETE
, o Android chama commitCheckpoint
para confirmar o ponto de verificação atual e a atualização continua normalmente.
Gerencie chaves mestras
As chaves principais são usadas para criptografia do dispositivo ou outros fins. Para gerenciar essas chaves, o Android atrasa as chamadas de exclusão de chave até que o ponto de verificação seja confirmado.
Monitore a saúde
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 saúde tem os seguintes comportamentos que podem ser configurados:
-
ro.sys.cp_msleeptime
: controla com que frequência 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 IVold.aidl
.
void startCheckpoint(int retry)
Cria um ponto de verificação.
A estrutura chama esse método quando está pronto para iniciar uma atualização. O ponto de verificação é criado antes que os sistemas de arquivos com ponto de verificação, como dados do usuário, sejam montados R/W após a reinicialização. Se a contagem de novas tentativas for positiva, a API tratará de 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 commitChanges()
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 imagens, vídeo, SMS, recibo de recebimento do servidor) sejam gravados em userdata e antes de BootComplete
.
Se não existir nenhuma atualização ativa com ponto de verificação, 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 de commitChanges
. retry_counter
é diminuído quando esse método é chamado. As entradas de registro 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.
Implementar 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 .
Configurar
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 /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
Adicionar partição de metadados
O UDC requer uma partição de metadados para armazenar a contagem e as chaves de novas tentativas do nonbootloader. 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 para todos os zeros.
Adicione as seguintes linhas ao BoardConfig.mk
:
BOARD_USES_METADATA_PARTITION := true BOARD_ROOT_EXTRA_FOLDERS := existing_folders metadata
sistemas de atualização
Sistemas F2FS
Para sistemas que usam F2FS para formatar dados, certifique-se de que sua versão do F2FS oferece suporte a pontos de verificação. Para obter mais informações, consulte Funcionalidade do ponto de verificação em diferentes sistemas de arquivos .
Adicione o sinalizador checkpoint=fs
à seção <fs_mgr_flags>
de fstab para o dispositivo montado em /data
.
Sistemas não-F2FS
Para sistemas não-F2FS, dm-bow
deve ser ativado na configuração do kernel.
Adicione o sinalizador checkpoint=block
à seção <fs_mgr_flags>
do fstab para o dispositivo montado em /data
.
Verificar 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
.