Punto de control de datos de usuario (UDC)

Android 10 presenta el punto de control de datos de usuario (UDC), que permite que Android vuelva a su estado anterior cuando falla una actualización inalámbrica (OTA) de Android. Con UDC, si falla una actualización OTA de Android, el dispositivo puede volver a su estado anterior de manera segura. Aunque las actualizaciones A/B solucionan este problema para el arranque anticipado, la reversión no se admite cuando se modifica la partición de datos del usuario (montada en /data ).

UDC permite que el dispositivo revierta la partición de datos de usuario incluso después de haber sido modificado. La función UDC logra esto con capacidades de punto de control para el sistema de archivos, una implementación alternativa cuando el sistema de archivos no admite puntos de control, integración con el mecanismo A/B del cargador de arranque y compatibilidad con actualizaciones que no son A/B y compatibilidad con el enlace de versión clave. y prevención de reversión de claves.

Impacto del usuario

La función UDC mejora la experiencia de actualización OTA para los usuarios, ya que menos usuarios pierden sus datos cuando falla una actualización OTA. Esto puede reducir la cantidad de llamadas de soporte de los usuarios que tienen problemas durante el proceso de actualización. Sin embargo, cuando falla una actualización OTA, los usuarios pueden notar que el dispositivo se reinicia varias veces.

Cómo funciona

Funcionalidad de punto de control en diferentes sistemas de archivos

Para el sistema de archivos F2FS, UDC agrega la funcionalidad de punto de control al kernel de Linux 4.20 ascendente y lo transfiere a todos los kernels comunes compatibles con dispositivos que ejecutan Android 10.

Para otros sistemas de archivos, UDC utiliza un dispositivo virtual asignador de dispositivos llamado dm_bow para la funcionalidad de punto de control. dm_bow se encuentra entre el dispositivo y el sistema de archivos. Cuando se monta una partición, se emite un recorte que hace que el sistema de archivos emita comandos de recorte en todos los bloques libres. dm_bow intercepta estos recortes y los usa para configurar una lista de bloqueo libre. Luego, las lecturas y escrituras se envían al dispositivo sin modificar, pero antes de que se permita una escritura, los datos necesarios para una restauración se respaldan en un bloque libre.

Proceso de puntos de control

Cuando se monta una partición con el indicador checkpoint=fs/block , Android llama a restoreCheckpoint en la unidad para permitir que el dispositivo restaure cualquier punto de control actual. Luego, init llama a la función needsCheckpoint para determinar si el dispositivo se encuentra en un estado A/B del cargador de arranque o ha establecido el número de reintentos de actualización. Si cualquiera de los dos es cierto, Android llama a createCheckpoint para agregar indicadores de montaje o crear un dispositivo dm_bow .

Una vez montada la partición, se llama al código de punto de control para emitir recortes. El proceso de arranque continúa normalmente. En LOCKED_BOOT_COMPLETE , Android llama a commitCheckpoint para confirmar el punto de control actual y la actualización continúa con normalidad.

Gestión de claves maestras

Las claves maestras de claves se utilizan para el cifrado de dispositivos u otros fines. Para administrar estas claves, Android retrasa las llamadas de eliminación de claves hasta que se confirme el punto de control.

Monitoreo de la salud

Un demonio de salud verifica que haya suficiente espacio en disco para crear un punto de control. El demonio de salud se encuentra en cp_healthDaemon en Checkpoint.cpp .

El demonio de salud tiene los siguientes comportamientos que se pueden configurar:

  • ro.sys.cp_msleeptime : controla la frecuencia con la que el dispositivo comprueba el uso del disco.
  • ro.sys.cp_min_free_bytes : controla el valor mínimo que busca el demonio de salud.
  • ro.sys.cp_commit_on_full : controla si el demonio de estado reinicia el dispositivo o confirma el punto de control y continúa cuando el disco está lleno.

API de punto de control

La función UDC utiliza las API de punto de control. Para conocer otras API utilizadas por UDC, consulte IVoid.aidl .

void startCheckpoint(int reintentar)

Crea un punto de control.

El marco llama a este método cuando está listo para iniciar una actualización. El punto de control se crea antes de que los sistemas de archivos con puntos de control, como los datos de usuario, se monten R/W después del reinicio. Si el recuento de reintentos es positivo, la API gestiona los reintentos de seguimiento y el actualizador llama a needsRollback para comprobar si se requiere una reversión de la actualización. Si el recuento de reintentos es -1 , la API se remite al juicio del gestor de arranque A/B.

Este método no se llama cuando se realiza una actualización A/B normal.

anular cambios de compromiso ()

Confirma los cambios.

El marco llama a este método después de reiniciar cuando los cambios están listos para confirmarse. Esto se llama antes de que los datos (como imágenes, video, SMS, recepción del servidor) se escriban en los datos de usuario y antes BootComplete .

Si no existe una actualización activa con puntos de control, este método no tiene efecto.

abortar cambios ()

Fuerza el reinicio y vuelve al punto de control. Abandona todas las modificaciones de datos de usuario desde el primer reinicio.

El marco llama a este método después de reiniciar pero antes commitChanges . retry_counter se reduce cuando se llama a este método. Se generan entradas de registro.

bool necesitaRollback()

Determina si se requiere una reversión.

En dispositivos que no son puntos de control, devuelve false . En dispositivos de punto de control, devuelve true durante un arranque sin punto de control.

Implementación de UDC

Implementación de referencia

Para ver un ejemplo de cómo se puede implementar UDC, consulte dm-bow.c . Para obtener documentación adicional sobre la función, consulte dm-bow.txt .

Configuración

En on fs en su archivo init.hardware.rc , asegúrese de tener:

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

En on late-fs en su archivo init.hardware.rc , asegúrese de tener:

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

En su archivo fstab.hardware , asegúrese de que /data esté etiquetado 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

Agregar partición de metadatos

UDC requiere una partición de metadatos para almacenar las claves y el recuento de reintentos que no son del cargador de arranque. Configure una partición de metadatos y móntela antes en /metadata .

En su archivo fstab.hardware , asegúrese de que /metadata esté etiquetado como earlymount o first_stage_mount .

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

Inicialice la partición a todos ceros.

Agregue las siguientes líneas a BoardConfig.mk :

BOARD_USES_METADATA_PARTITION := true
BOARD_ROOT_EXTRA_FOLDERS := existing_folders metadata

Actualización de sistemas

Sistemas F2FS

Para los sistemas que usan F2FS para formatear datos, asegúrese de que su versión de F2FS admita puntos de control. Para obtener más información, consulte Funcionalidad de punto de control en diferentes sistemas de archivos .

Agregue el indicador checkpoint=fs a la sección <fs_mgr_flags> de fstab para el dispositivo montado en /data .

Sistemas no F2FS

Para sistemas que no sean F2FS, dm-bow debe estar habilitado en la configuración del kernel.

Agregue el indicador checkpoint=block a la sección <fs_mgr_flags> de fstab para el dispositivo montado en /data .

Comprobación de registros

Las entradas de registro se generan cuando se llama a las API de Checkpoint.

Validación

Para probar su implementación de UDC, ejecute el conjunto de pruebas VTS VtsKernelCheckpointTest .