В 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
.