Контрольная точка данных пользователя

Android 10 представляет User Data Checkpoint (UDC), которая позволяет Android откатываться к предыдущему состоянию, если обновление Android по воздуху (OTA) не удается. С UDC, если обновление Android OTA не удается, устройство может безопасно откатиться к предыдущему состоянию. Хотя обновления A/B решают эту проблему для ранней загрузки, откат не поддерживается, если раздел пользовательских данных (смонтированный в /data ) изменен.

UDC позволяет устройству откатить раздел пользовательских данных даже после изменения. Функция UDC достигает этого с помощью возможностей контрольных точек для файловой системы, альтернативной реализации, когда файловая система не поддерживает контрольные точки, интеграции с механизмом загрузчика A/B, а также поддержки обновлений без A/B, а также поддержки привязки версии ключа и предотвращения отката ключа.

Влияние на пользователя

Функция UDC улучшает процесс обновления OTA для пользователей, поскольку меньше пользователей теряют свои данные при сбое обновления OTA. Это может сократить количество звонков в службу поддержки от пользователей, которые сталкиваются с проблемами в процессе обновления. Однако при сбое обновления OTA пользователи могут заметить, что устройство перезагружается несколько раз.

Как это работает

Функциональность контрольных точек в различных файловых системах

Для файловой системы F2FS UDC добавляет функционал контрольных точек в ядро ​​Linux 4.20 и портирует его на все распространенные ядра, поддерживаемые устройствами под управлением Android 10.

Для других файловых систем UDC использует виртуальное устройство сопоставления устройств, называемое dm_bow , для функциональности контрольной точки. dm_bow находится между устройством и файловой системой. Когда раздел монтируется, выдается команда обрезки, заставляющая файловую систему выдавать команды обрезки для всех свободных блоков. dm_bow перехватывает эти команды обрезки и использует их для настройки списка свободных блоков. Затем операции чтения и записи отправляются на устройство без изменений, но перед тем, как будет разрешена запись, данные, необходимые для восстановления, резервируются в свободном блоке.

Процесс контрольно-пропускного пункта

Когда монтируется раздел с флагом checkpoint=fs/block , Android вызывает restoreCheckpoint на диске, чтобы позволить устройству восстановить любую текущую контрольную точку. Затем init вызывает функцию needsCheckpoint , чтобы определить, находится ли устройство в состоянии загрузчика A/B или установило счетчик повторных попыток обновления. Если любое из этих значений истинно, Android вызывает createCheckpoint чтобы либо добавить флаги монтирования, либо создать устройство dm_bow .

После монтирования раздела вызывается код контрольной точки для выдачи обрезков. Затем процесс загрузки продолжается как обычно. В LOCKED_BOOT_COMPLETE Android вызывает commitCheckpoint для фиксации текущей контрольной точки, и обновление продолжается как обычно.

Управление мастер-ключами

Ключи Keymaster используются для шифрования устройства или других целей. Для управления этими ключами Android откладывает вызовы удаления ключей до тех пор, пока не будет зафиксирована контрольная точка.

Следите за здоровьем

Демон работоспособности проверяет, достаточно ли места на диске для создания контрольной точки. Демон работоспособности находится в cp_healthDaemon в Checkpoint.cpp .

Демон работоспособности имеет следующие варианты поведения, которые можно настроить:

  • ro.sys.cp_msleeptime : управляет частотой проверки устройством использования диска.
  • ro.sys.cp_min_free_bytes : управляет минимальным значением, которое ищет демон работоспособности.
  • ro.sys.cp_commit_on_full : управляет тем, будет ли демон работоспособности перезагружать устройство или фиксировать контрольную точку и продолжать работу после заполнения диска.

API контрольных точек

API контрольных точек используются функцией UDC. Для других API, используемых UDC, см. IVold.aidl .

void startCheckpoint(int retry)

Создает контрольную точку.

Фреймворк вызывает этот метод, когда он готов начать обновление. Контрольная точка создается до того, как файловые системы с контрольными точками, такие как пользовательские данные, монтируются для чтения/записи после перезагрузки. Если количество повторов положительное, API обрабатывает повторы отслеживания, а средство обновления вызывает needsRollback для проверки необходимости отката обновления. Если количество повторов равно -1 , API полагается на решение загрузчика A/B.

Этот метод не вызывается при выполнении обычного обновления A/B.

недействительный commitChanges()

Принимает изменения.

Фреймворк вызывает этот метод после перезагрузки, когда изменения готовы к фиксации. Он вызывается до того, как данные (такие как картинки, видео, SMS, серверное подтверждение приема) записываются в userdata и до BootComplete .

Если активных контрольных точек обновления не существует, этот метод не имеет эффекта.

abortChanges()

Принудительная перезагрузка и возврат к контрольной точке. Отменяет все изменения пользовательских данных с момента первой перезагрузки.

Фреймворк вызывает этот метод после перезагрузки, но до commitChanges . retry_counter уменьшается при вызове этого метода. Генерируются записи журнала.

bool требуетRollback()

Определяет, требуется ли откат.

На устройствах без контрольной точки возвращает false . На устройствах с контрольной точкой возвращает true во время загрузки без контрольной точки.

Внедрить УДК

Референтная реализация

Пример реализации UDC см. в dm-bow.c . Дополнительную документацию по этой функции см. в dm-bow.txt .

Настраивать

В on fs вашего файла init.hardware.rc убедитесь, что у вас есть:

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

В файле init.hardware.rc в on late-fs убедитесь, что у вас есть:

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

В файле fstab.hardware убедитесь, что /data помечен как 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

Добавить раздел метаданных

UDC требует раздел метаданных для хранения счетчика повторных попыток и ключей nonbootloader. Настройте раздел метаданных и заранее смонтируйте его в /metadata .

В файле fstab.hardware убедитесь, что /metadata помечен как earlymount или first_stage_mount .

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

Инициализируйте раздел нулями.

Добавьте следующие строки в BoardConfig.mk :

BOARD_USES_METADATA_PARTITION := true
BOARD_ROOT_EXTRA_FOLDERS := existing_folders metadata

Обновление систем

F2FS-системы

Для систем, использующих F2FS для форматирования данных, убедитесь, что ваша версия F2FS поддерживает контрольные точки. Для получения дополнительной информации см. раздел Функциональность контрольных точек в различных файловых системах .

Добавьте флаг checkpoint=fs в раздел <fs_mgr_flags> файла fstab для устройства, смонтированного в /data .

Системы, отличные от F2FS

Для систем, отличных от F2FS, dm-bow должен быть включен в конфигурации ядра.

Добавьте флаг checkpoint=block в раздел <fs_mgr_flags> файла fstab для устройства, смонтированного в /data .

Проверить журналы

Записи журнала генерируются при вызове API Checkpoint.

Проверка

Чтобы протестировать реализацию UDC, запустите набор тестов VTS VtsKernelCheckpointTest .