Visão geral do A/B virtual

O A/B virtual é o principal mecanismo de atualização do Android. Os builds A/B virtuais se baseiam nas atualizações A/B legadas (consulte Atualizações do sistema A/B) e não A/B, que foram descontinuados na versão 15 para reduzir a sobrecarga de espaço das atualizações.

O A/B virtual não tem um slot extra para partições dinâmicas. Consulte partições dinâmicas. Em vez disso, o delta é gravado em um snapshot e, em seguida, mesclado na partição de base após a confirmação de uma inicialização bem-sucedida. O A/B virtual usa um formato de snapshot específico do Android. Consulte Formato COW para snapshots compactados, que permite compactar os snapshots e minimiza o uso do espaço em disco. Em uma OTA completa, o tamanho do snapshot é reduzido em cerca de 45% com a compactação, e o tamanho do snapshot incremental da OTA é reduzido em cerca de 55%.

O Android 12 oferece a opção de compactação A/B virtual para compactar partições com snapshots. O A/B virtual oferece o seguinte:

  • As atualizações A/B virtuais são integradas (a atualização ocorre inteiramente em segundo plano enquanto o dispositivo está operacional), como atualizações A/B. As atualizações A/B virtuais minimizam o tempo em que um dispositivo fica off-line e inutilizável.
  • As atualizações A/B virtuais podem ser revertidas. Se houver falha na inicialização do novo SO, os dispositivos serão revertidos automaticamente para a versão anterior.
  • As atualizações A/B virtuais usam um espaço mínimo extra duplicando apenas as partições usadas pelo carregador de inicialização. Outras partições atualizáveis têm snapshots.

Contexto e terminologia

Esta seção define a terminologia e descreve a tecnologia que oferece suporte ao A/B virtual. Durante a instalação do OTA, novos dados do sistema operacional são gravados no novo slot para partições físicas ou em um dispositivo COW específico do Android. Após a reinicialização do dispositivo, os dados da partição dinâmica são mesclados novamente no dispositivo base por meio do uso do dm-user e dos daemons Snapuserd. Esse processo ocorre inteiramente no espaço do usuário.

Device-mapper

O Device-mapper é uma camada de bloco virtual do Linux usada com frequência no Android. Com partições dinâmicas, partições como /system são uma pilha de dispositivos em camadas:

  • Na parte de baixo da pilha, há a partição super física (por exemplo, /dev/block/by-name/super).
  • No meio, há um dispositivo dm-linear, que especifica quais blocos na superpartilha formam a partição dinâmica especificada. Ele aparece como /dev/block/mapper/system_[a|b] em um dispositivo A/B ou /dev/block/mapper/system em um dispositivo não A/B.
  • Na parte de cima, está um dispositivo dm-verity, criado para partições verificadas. Esse dispositivo verifica se os blocos no dispositivo dm-linear estão assinados corretamente. Ele aparece como /dev/block/mapper/system-verity e é a origem do ponto de montagem /system.

A Figura 1 mostra a aparência da pilha abaixo do ponto de montagem /system.

Partição empilhada abaixo do
sistema

Figura 1. Empilhamento no ponto de montagem /system

Snapshots compactados

No Android 12 e versões mais recentes, como os requisitos de espaço na partição /data podem ser altos, é possível ativar snapshots compactados no build para atender aos requisitos de espaço mais altos da partição /data.

Os snapshots compactados A/B virtuais são criados com base nos seguintes componentes disponíveis no Android 12 e versões mais recentes:

  • dm-user, um módulo do kernel semelhante ao FUSE que permite que o espaço do usuário implemente dispositivos de bloco.
  • snapuserd, um daemon de espaço do usuário para implementar um novo formato de snapshot.

Esses componentes ativam a compactação. As outras mudanças necessárias feitas para implementar os recursos de snapshots compactados são fornecidas nas próximas seções: Formato COW para snapshots compactados, dm-user e snapuserd.

Formato COW para snapshots compactados

No Android 12 e versões mais recentes, os snapshots compactados usam um formato COW específico do Android. O formato COW contém metadados sobre a OTA e tem buffers distintos contendo operações COW e novos dados do sistema operacional. Em comparação com o formato de snapshot do kernel, que permitia apenas operações de substituição, substitua o bloco X na imagem base pelo conteúdo do bloco Y no snapshot. O formato COW de snapshots compactados do Android é mais expressivo e oferece suporte às seguintes operações:

  • Cópia: o bloco X no dispositivo de base precisa ser substituído pelo bloco Y no dispositivo base.
  • Substituir: o bloco X no dispositivo base precisa ser substituído pelo conteúdo do bloco Y no snapshot. Cada um desses blocos é comprimido em gz.
  • Zero: o bloco X no dispositivo base precisa ser substituído por todos os zeros.
  • XOR: o dispositivo COW armazena bytes compactados XOR entre o bloco X e o bloco Y. Disponível no Android 13 e em versões mais recentes.

As atualizações OTA completas consistem apenas em operações de substituir e zero. As atualizações OTA incrementais também podem ter operações de cópia.

O layout de snapshot completo no disco tem esta aparência:

formato vaca

Figura 2. Formato de COW do Android no disco

dm-user

O módulo do kernel dm-user permite que userspace implemente dispositivos de bloco device-mapper. Uma entrada de tabela dm-user cria um dispositivo diverso em /dev/dm-user/<control-name>. Um processo userspace pode pesquisar o dispositivo para receber solicitações de leitura e gravação do kernel. Cada solicitação tem um buffer associado para que o espaço do usuário seja preenchido (para uma leitura) ou propagado (para uma gravação).

O módulo do kernel dm-user oferece uma nova interface visível para o usuário que não faz parte da base de código upstream kernel.org. Até que seja, o Google se reserva o direito de modificar a interface dm-user no Android.

snapuserd

O componente de espaço do usuário snapuserd para dm-user implementa a compactação A/B virtual. O Snapuserd é um daemon do espaço do usuário responsável por gravar e ler os dispositivos COW do Android. Toda a E/S do snapshot precisa passar por esse serviço. Durante a instalação do OTA, novos dados do sistema operacional são gravados no snapshot por Snapuserd (com compactação). A análise dos metadados e a descompactação de novos dados do bloco também são tratadas aqui.

Compactação XOR

Para dispositivos lançados com o Android 13 e versões mais recentes, o recurso de compactação XOR, que é ativado por padrão, permite que os snapshots do espaço do usuário armazenem bytes compactados XOR entre blocos antigos e novos. Quando apenas alguns bytes em um bloco são alterados em uma atualização A/B virtual, o esquema de armazenamento de compactação XOR usa menos espaço do que o esquema de armazenamento padrão, porque snapshots não armazenam 4.000 bytes completos. Essa redução no tamanho do snapshot é possível porque os dados XOR contêm muitos zeros e são mais fáceis de compactar do que dados de bloco brutos. Em dispositivos Pixel, a compactação XOR reduz o tamanho do snapshot em 25% a 40%.

Para dispositivos que estão fazendo upgrade para o Android 13 e versões mais recentes, a compactação XOR precisa estar ativada. Para mais detalhes, consulte Compactação XOR.

Mesclar snapshots

Em dispositivos lançados com o Android 13 e versões mais recentes, os processos de mesclagem e de snapshot na compactação A/B virtual são realizados pelo componente de espaço do usuário snapuserd. Para dispositivos que fizerem upgrade para o Android 13 e versões mais recentes, esse recurso precisa estar ativado. Para mais detalhes, consulte Mesclar o espaço do usuário.

Confira a seguir a descrição do processo de compactação A/B virtual:

  1. O framework monta a partição /system fora de um dispositivo dm-verity, que é empilhado sobre um dispositivo dm-user. Isso significa que todas as E/S do sistema de arquivos raiz são roteadas para dm-user.
  2. dm-user encaminha a E/S para o daemon snapuserd do espaço do usuário, que processa a solicitação de E/S.
  3. Quando a operação de mesclagem é concluída, o framework reduz dm-verity em cima de dm-linear (system_base) e remove dm-user.

Processo de compactação
A/B virtual

Figura 3. Processo de compactação do A/B virtual

O processo de mesclagem de snapshots pode ser interrompido. Se o dispositivo for reinicializado durante o processo de mesclagem, esse processo será retomado após a reinicialização.

Transições de inicialização

Ao inicializar com snapshots compactados, a inicialização da primeira fase precisa iniciar snapuserd para montar partições. Isso gera um problema: quando o sepolicy é carregado e aplicado, o snapuserd é colocado no contexto errado, e as solicitações de leitura falham, com negações do SELinux.

Para resolver isso, o snapuserd faz transições em conjunto com o init, da seguinte maneira:

  1. O init de primeiro estágio inicia o snapuserd no ramdisk e salva um descritor de arquivo aberto para ele em uma variável de ambiente.
  2. A init do primeiro estágio alterna o sistema de arquivos raiz para a partição do sistema e, em seguida, executa a cópia do sistema de init.
  3. A cópia do sistema de init lê a sepolicy combinada em uma string.
  4. Init invoca mlock() em todas as páginas com suporte para ext4. Em seguida, ele desativa todas as tabelas de mapeamento de dispositivo para dispositivos de snapshot e interrompe o snapuserd. Depois disso, fica proibido ler das partições, porque isso causa um deadlock.
  5. Usando o descritor aberto para a cópia do ramdisk de snapuserd, init reinicia o daemon com o contexto correto do selinux. As tabelas de mapeador de dispositivo para dispositivos de snapshot são reativadas.
  6. O init invoca munlockall(). É seguro realizar a E/S novamente.

Uso do espaço

A tabela a seguir mostra uma comparação do uso de espaço para diferentes mecanismos de OTA usando o SO e os tamanhos OTA do Pixel.

Impacto do tamanho não A/B A/B A/B virtual A/B virtual (compactado)
Imagem original da fábrica Super de 4,5 GB (imagem de 3,8 GB + 700 MB reservados)1 9 GB super (3,8 GB + 700 MB reservados, para dois slots) 4,5 GB super (3,8 GB de imagem + 700 MB reservados) 4,5 GB super (3,8 GB de imagem + 700 MB reservados)
Outras partições estáticas /cache Nenhum Nenhum Nenhum
Armazenamento adicional durante a OTA (espaço retornado após a aplicação do OTA) 1,4 GB em /data 0 3,8 GB2 em /data 2,1 GB2 em /data
Armazenamento total necessário para aplicar a OTA 5,9 GB3 (superior e dados) 9GB (super) 8,3 GB3 (super e dados) 6,6 GB3 (super e dados)

1 Indica o layout presumido com base no mapeamento de pixels.

2Assume que a nova imagem do sistema tem o mesmo tamanho que a original.

3 O requisito de espaço é temporário até a reinicialização.

A/B virtual do Android 11

O Android 11 do Virtual A/B gravou na partição dinâmica usando o formato COW do kernel. Isso foi descontinuado porque o formato COW do kernel não oferece suporte à compressão.

A/B virtual do Android 12

No Android 12, há suporte à compactação na forma de um formato COW específico do Android. Essa versão do A/B virtual exigia uma tradução do COW específico do Android para o formato COW do kernel. Eventualmente, isso foi substituído no Android 13, que removeu a dependência do formato COW do kernel e também do dm-snapshot.

Para implementar o A/B virtual ou usar recursos de snapshot compactado, consulte Como implementar o A/B virtual.