Descripción general de A/B virtual

El A/B virtual es el mecanismo de actualización principal de Android. A/B virtual se basa en actualizaciones de A/B heredadas (consulta Actualizaciones del sistema A/B) y no A/B, que dejarán de estar disponibles en 15 para reducir la sobrecarga de espacio de las actualizaciones.

En realidad, la A/B virtual no tiene un espacio adicional para particiones dinámicas. Consulta particiones dinámicas. En su lugar, la delta se escribe en una instantánea y, luego, se combina en la partición base después de confirmar que el inicio se realizó correctamente. A/B virtual usa un formato de instantáneas específico de Android. Consulta el formato COW para las instantáneas comprimidas, que permite comprimir las instantáneas y minimizar el uso del espacio en el disco. En una actualización OTA completa, el tamaño de la instantánea se reduce en alrededor de un 45% con la compresión, y el tamaño de la instantánea OTA incremental se reduce en alrededor de un 55%.

Android 12 ofrece la opción de compresión de A/B virtual para comprimir las particiones con instantáneas. A/B virtual ofrece lo siguiente:

  • Las actualizaciones de A/B virtuales son sin interrupciones (la actualización se realiza por completo en segundo plano mientras el dispositivo está en funcionamiento), al igual que las actualizaciones de A/B. Las actualizaciones de A/B virtual minimizan el tiempo que un dispositivo está desconectado y no se puede usar.
  • Las actualizaciones de A/B virtuales se pueden revertir. Si el SO nuevo no se inicia, los dispositivos vuelven automáticamente a la versión anterior.
  • Las actualizaciones A/B virtuales usan un espacio adicional mínimo, ya que duplican solo las particiones que usa el bootloader. Se crean instantáneas de otras particiones actualizables.

Información general y terminología

En esta sección, se define la terminología y se describe la tecnología que admite pruebas A/B virtuales. Durante la instalación OTA, los datos del sistema operativo nuevo se escriben en su nuevo espacio para particiones físicas o en un dispositivo COW específico de Android. Una vez que se reinicia el dispositivo, los datos de la partición dinámica se vuelven a combinar con el dispositivo base mediante el uso de dm-user y daemon Snapuserd. Este proceso ocurre completamente en el espacio del usuario.

Device-mapper

Device-mapper es una capa de bloques virtual de Linux que se usa con frecuencia en Android. Con las particiones dinámicas, las particiones como /system son una pila de dispositivos en capas:

  • En la parte inferior de la pila, se encuentra la partición física super (por ejemplo, /dev/block/by-name/super).
  • En el medio, hay un dispositivo dm-linear que especifica qué bloques de la superpartición forman la partición dinámica determinada. Aparece como /dev/block/mapper/system_[a|b] en un dispositivo A/B o como /dev/block/mapper/system en un dispositivo que no es A/B.
  • En la parte superior, se encuentra un dispositivo dm-verity creado para particiones verificadas. Este dispositivo verifica que los bloqueos en el dispositivo dm-linear estén firmados de forma correcta. Se muestra como /dev/block/mapper/system-verity y es la fuente del punto de activación /system.

En la Figura 1, se muestra cómo se ve la pila debajo del punto de activación /system.

El apilamiento de particiones debajo del sistema

Figura 1: Se apila debajo del punto de activación /system.

Instantáneas comprimidas

En Android 12 y versiones posteriores, como los requisitos de espacio en la partición /data pueden ser altos, puedes habilitar instantáneas comprimidas en tu compilación para abordar los requisitos de espacio más altos de la partición /data.

Las instantáneas comprimidas de A/B virtual se compilan sobre los siguientes componentes disponibles en Android 12 y versiones posteriores:

  • dm-user, un módulo de kernel similar a FUSE que permite que el espacio del usuario implemente dispositivos de almacenamiento en bloque
  • snapuserd, un daemon de espacio de usuario para implementar un nuevo formato de instantánea.

Estos componentes habilitan la compresión. Los otros cambios necesarios que se realizan con el fin de implementar las capacidades de las instantáneas comprimidas se proporcionan en las siguientes secciones: Formato COW para instantáneas comprimidas, dm-user y Snapuserd.

Formato COW para instantáneas comprimidas

En Android 12 y versiones posteriores, las instantáneas comprimidas usan un formato de COW específico de Android. El formato COW contiene metadatos sobre la OTA y tiene búferes distintos que contienen operaciones de COW y datos nuevos del sistema operativo. En comparación con el formato de instantánea del kernel que solo se permitía para las operaciones replace (Reemplazar bloque X en la imagen base con el contenido del bloque Y en la instantánea), el formato COW de instantáneas comprimidas de Android es más expresivo y admite las siguientes operaciones:

  • Copiar: El bloque X en el dispositivo base debe reemplazarse por el bloque Y en el dispositivo base.
  • Reemplazo: El bloque X en el dispositivo base debe reemplazarse por el contenido del bloque Y en la instantánea. Cada uno de estos bloques está comprimido en gz.
  • Cero: El bloque X del dispositivo base debe reemplazarse por ceros.
  • XOR: El dispositivo COW almacena bytes comprimidos XOR entre el bloque X y el bloque Y. (Disponible en Android 13 y versiones posteriores).

Las actualizaciones OTA completas consisten solo en operaciones de reemplazo y cero. Además, las actualizaciones OTA incrementales pueden tener operaciones de copia.

El diseño completo de la instantánea en el disco se ve de la siguiente manera:

formato de vaca

Figura 2: Formato COW de Android en el disco

dm-user

El módulo del kernel dm-user permite que userspace implemente dispositivos de bloqueo de mapeo de dispositivos. Una entrada de la tabla dm-user crea un dispositivo misceláneo en /dev/dm-user/<control-name>. Un proceso userspace puede sondear el dispositivo para recibir solicitudes de lectura y escritura del kernel. Cada solicitud tiene un búfer asociado para que el espacio de usuario lo propague (para una operación de escritura) o lo propague (para una operación de lectura).

El módulo de kernel dm-user proporciona una nueva interfaz visible para el usuario al kernel que no forma parte de la base de código ascendente de kernel.org. Hasta que lo haga, Google se reserva el derecho de modificar la interfaz dm-user en Android.

Snapuserd

El componente de espacio de usuario snapuserd para dm-user implementa la compresión A/B virtual. Snapuserd es un daemon de espacio de usuario a cargo de escribir y leer los dispositivos COW de Android. Toda la E/S de la instantánea debe pasar por este servicio. Durante la instalación inalámbrica, Snapuserd (con compresión) escribe los datos nuevos del sistema operativo en la instantánea. Aquí también se controla el análisis de los metadatos y el desempaquetado de datos de bloques nuevos.

Compresión XOR

En el caso de los dispositivos que se lanzan con Android 13 y versiones posteriores, la función de compresión XOR, que está habilitada de forma predeterminada, permite que las instantáneas del espacio del usuario almacenen bytes comprimidos XOR entre bloques antiguos y nuevos. Cuando solo se cambian algunos bytes en un bloque en una actualización A/B virtual, el esquema de almacenamiento de compresión XOR usa menos espacio que el esquema de almacenamiento predeterminado, ya que las instantáneas no almacenan 4K de bytes completos. Esta reducción en el tamaño de la instantánea es posible porque los datos XOR contienen muchos ceros y son más fáciles de comprimir que los datos de bloque sin procesar. En los dispositivos Pixel, la compresión XOR reduce el tamaño de los resúmenes entre un 25% y un 40%.

En el caso de los dispositivos que se actualizan a Android 13 y versiones posteriores, se debe habilitar la compresión XOR. Para obtener más información, consulta Compresión XOR.

Combinación de instantáneas

En el caso de los dispositivos que se lanzan con Android 13 y versiones posteriores, el componente de espacio de usuario snapuserd realiza los procesos de combinación de instantáneas en la compresión A/B virtual. En el caso de los dispositivos que se actualizan a Android 13 y versiones posteriores, esta función debe estar habilitada. Para obtener más información, consulta Combinación de espacio de usuario.

A continuación, se describe el proceso de compresión A/B virtual:

  1. El framework activa la partición /system de un dispositivo dm-verity, que se apila sobre un dispositivo dm-user. Esto significa que cada E/S del sistema de archivos raíz se enruta a dm-user.
  2. dm-user enruta la E/S al daemon snapuserd del espacio de usuario, que controla la solicitud de E/S.
  3. Cuando se completa la operación de combinación, el framework contrae dm-verity sobre dm-linear (system_base) y quita dm-user.

El proceso de compresión A/B virtual

Figura 3: Proceso de compresión de A/B virtual

El proceso de combinación de instantáneas se puede interrumpir. Si el dispositivo se reinicia durante el proceso de combinación, este se reanuda después del reinicio.

Transiciones de init

Cuando se inicia con instantáneas comprimidas, el init de primera etapa debe iniciar snapuserd para activar las particiones. Esto plantea un problema: cuando se carga y aplica sepolicy, snapuserd se coloca en el contexto incorrecto y sus solicitudes de lectura fallan, con rechazos de SELinux.

Para solucionar este problema, snapuserd realiza transiciones en sincronía con init, de la siguiente manera:

  1. El init de primera etapa inicia snapuserd desde el ramdisk y le guarda un descriptor de archivo abierto en una variable de entorno.
  2. La primera etapa, init, cambia el sistema de archivos raíz a la partición del sistema y, luego, ejecuta la copia del sistema de init.
  3. La copia del sistema de init lee la sepolicy combinada en una cadena.
  4. Init invoca a mlock() en todas las páginas con copia de seguridad de ext4. Luego, desactiva todas las tablas de Device Mapper para los dispositivos de instantáneas y detiene snapuserd. Después de esto, no se permitirá la lectura de particiones, ya que esto provoca un interbloqueo.
  5. Con el descriptor abierto para la copia de ramdisk de snapuserd, init reinicia el daemon con el contexto de selinux correcto. Se vuelven a activar las tablas de Device-mapper para los dispositivos de instantáneas.
  6. Init invoca a munlockall(); es seguro volver a realizar operaciones de E/S.

Uso del espacio

En la siguiente tabla, se proporciona una comparación del uso de espacio para diferentes mecanismos de OTA con los tamaños del SO y OTA de Pixel.

Impacto del tamaño no A/B A/B A/B virtual A/B virtual (comprimido)
Imagen de fábrica original Super 4.5 GB (imagen de 3.8 GB + 700 M reservados)1 9 GB de almacenamiento super (3.8 G + 700 M reservados, para dos ranuras) 4.5 GB super (imagen de 3.8 GB + 700 M reservados) 4.5 GB super (imagen de 3.8 GB + 700 M reservados)
Otras particiones estáticas /cache Ninguno Ninguno Ninguno
Almacenamiento adicional durante la actualización inalámbrica (espacio que se muestra después de aplicar la actualización inalámbrica) 1.4 GB en /data 0 3.8 GB2 en /data 2.1 GB2 en /data
Almacenamiento total necesario para aplicar la actualización OTA 5.9 GB3 (super y datos) 9 GB (super) 8.3 GB3 (super y datos) 6.6 GB3 (super y datos)

1 Indica el diseño adoptado en función de la asignación de píxeles.

2Se supone que la nueva imagen del sistema tiene el mismo tamaño que la original.

3El requisito de espacio es transitorio hasta el reinicio.

A/B virtual de Android 11

El android 11 de Virtual A/B escribió en la partición dinámica con el formato COW de kernel. Con el tiempo, dejó de estar disponible, ya que el formato COW del kernel no admite la compresión.

A/B virtual de Android 12

En Android 12, la compresión se admite en forma de un formato COW específico de Android. Esta versión de A/B virtual requirió una traducción de la COW específica de Android al formato de COW del kernel. Con el tiempo, esto se reemplazó en Android 13, que quitó la dependencia del formato COW del kernel y también de dm-snapshot.

Para implementar A/B virtual o usar las funciones de instantáneas comprimidas, consulta Implementa un A/B virtual.