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

В 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 располагается между устройством и файловой системой. При монтировании раздела выдаётся команда TRIM, заставляющая файловую систему выдавать команды TRIM для всех свободных блоков. dm_bow перехватывает эти команды и использует их для формирования списка свободных блоков. После этого данные чтения и записи отправляются на устройство без изменений, но перед разрешением записи данные, необходимые для восстановления, резервируются в свободном блоке.

Процесс контрольной точки

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

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

Управление ключами KeyMint (ранее Keymaster)

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

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

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

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

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

API-интерфейсы контрольных точек

Функция UDC использует API контрольных точек. Сведения о других API, используемых UDC, см. в IVold.aidl .

void startCheckpoint(int retry)

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

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

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

void commitChanges()

Фиксирует изменения.

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

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

abortChanges()

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

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

bool needsRollback()

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

На устройствах без контрольной точки возвращает 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 требует раздел метаданных для хранения количества повторных попыток и ключей, не связанных с загрузчиком. Создайте раздел метаданных и заранее смонтируйте его в /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 .