Android имеет два механизма обновления: A/B (бесшовные) обновления и не-A/B обновления. Чтобы уменьшить сложность кода и улучшить процесс обновления, в Android 11 эти два механизма объединены с помощью виртуального A/B, чтобы обеспечить бесшовные обновления на всех устройствах с минимальной стоимостью хранилища. Android 12 предлагает возможность виртуального сжатия A/B для сжатия моментальных снимков разделов. Как в Android 11, так и в Android 12 применимо следующее:
- Виртуальные обновления A/B не вызывают затруднений , как и обновления A/B. Виртуальные обновления A/B сводят к минимуму время, в течение которого устройство находится в автономном режиме и не используется.
- Виртуальные обновления A/B можно откатить . Если новая ОС не загружается, устройства автоматически возвращаются к предыдущей версии.
- Виртуальные обновления A/B занимают минимум дополнительного места , дублируя только те разделы, которые используются загрузчиком. Создаются моментальные снимки других обновляемых разделов.
Предыстория и терминология
В этом разделе определяется терминология и описывается технология, поддерживающая виртуальный A/B.
Устройство-сопоставитель
Device-mapper — это слой виртуальных блоков Linux, часто используемый в Android. При использовании динамических разделов такие разделы, как /system
, представляют собой стек многоуровневых устройств:
- Внизу стека находится физический суперраздел (например,
/dev/block/by-name/super
). - Посередине находится
dm-linear
устройство, указывающее, какие блоки суперраздела образуют данный раздел. Это отображается как/dev/block/mapper/system_[a|b]
на устройстве A/B или/dev/block/mapper/system
на устройстве без A/B. - Наверху находится устройство
dm-verity
, созданное для проверенных разделов. Это устройство проверяет правильность подписи блоков на устройствеdm-linear
. Он выглядит как/dev/block/mapper/system-verity
и является источником точки монтирования/system
.
На рис. 1 показано, как выглядит стек в точке монтирования /system
.
Рис. 1. Стек под точкой монтирования /system
дм-моментальный снимок
Виртуальный A/B использует dm-snapshot
, модуль сопоставления устройств для моментального снимка состояния устройства хранения. При использовании dm-snapshot
в игре участвуют четыре устройства:
- Базовое устройство — это устройство, на которое сделан снимок. На этой странице базовое устройство всегда является динамическим разделом, таким как системный или поставщик.
- Устройство копирования при записи (COW) для регистрации изменений в базовом устройстве. Он может быть любого размера, но он должен быть достаточно большим, чтобы вместить все изменения базового устройства.
- Устройство моментального снимка создается с использованием цели
snapshot
. Записи на устройство моментальных снимков записываются на устройство COW. Чтение с устройства моментального снимка выполняется либо с базового устройства, либо с устройства COW, в зависимости от того, были ли данные, к которым осуществляется доступ, были изменены моментальным снимком. - Исходное устройство создается с помощью цели
snapshot-origin
. Чтение на исходное устройство считывается непосредственно с базового устройства. Запись на исходное устройство записывается непосредственно на базовое устройство, но исходные данные резервируются путем записи на устройство COW.
Рисунок 2. Сопоставление устройств для dm-snapshot
Сжатые снимки
В Android 12, поскольку требования к пространству в разделе /data
могут быть высокими, вы можете включить сжатые моментальные снимки в своей сборке, чтобы удовлетворить более высокие требования к пространству в разделе /data
.
Виртуальные сжатые снимки A/B создаются на основе двух новых компонентов, доступных в Android 12:
-
dm-user
, модуль ядра, похожий на FUSE, который позволяет пользовательскому пространству реализовывать блочные устройства. -
snapuserd
— демон пользовательского пространства для реализации нового формата моментальных снимков.
Эти компоненты включают сжатие. Другие необходимые изменения, внесенные для реализации возможностей сжатых моментальных снимков, приведены в следующих разделах: формат COW для сжатых моментальных снимков , dm-user и Snapuserd .
Формат COW для сжатых моментальных снимков
В Android 12 сжатые снимки используют новый формат COW. Подобно встроенному формату ядра, используемому для несжатых моментальных снимков, формат COW для сжатых моментальных снимков имеет чередующиеся разделы метаданных и данных. Метаданные исходного формата допускали только операции «замены»: замена блока X в базовом образе содержимым блока Y в моментальном снимке. Формат сжатых снимков COW более выразителен и поддерживает три операции:
- Копировать — Блок X в базовом устройстве должен быть заменен блоком Y в базовом устройстве.
- Заменить — блок X в базовом устройстве должен быть заменен содержимым блока Y в моментальном снимке. Каждый из этих блоков сжат gz.
- Zero - Блок X в базовом устройстве должен быть заменен всеми нулями.
Полные OTA-обновления состоят только из операций замены и нуля . Добавочные обновления OTA могут дополнительно иметь операции копирования .
dm-пользователь в Android 12
Модуль ядра dm-user позволяет userspace
реализовывать блочные устройства device-mapper. Запись таблицы dm-user создает разное устройство в /dev/dm-user/<control-name>
. Процесс userspace
может опрашивать устройство для получения запросов на чтение и запись от ядра. У каждого запроса есть связанный буфер для пользовательского пространства, которое нужно либо заполнить (для чтения), либо распространить (для записи).
Модуль ядра dm-user
предоставляет новый видимый пользователю интерфейс для ядра, который не является частью исходной кодовой базы kernel.org. Пока это не так, Google оставляет за собой право изменять интерфейс dm-user
в Android.
Snapuserd
Компонент пользовательского пространства snapuserd
для dm-user
реализует виртуальное сжатие A/B.
В несжатой версии Virtual A/B (либо в Android 11 и ниже, либо в Android 12 без опции сжатого моментального снимка) устройство COW представляет собой необработанный файл. Когда сжатие включено, COW функционирует как устройство dm-user
, которое подключено к экземпляру демона snapuserd
.
Ядро не использует новый формат COW. Таким образом, компонент snapuserd
переводит запросы между форматом Android COW и встроенным форматом ядра:
Рисунок 3. Блок-схема snapuserd как переводчика между форматами Android и Kernel COW
Этот перевод и распаковка никогда не происходят на диске. Компонент snapuserd
перехватывает операции чтения и записи COW, происходящие в ядре, и реализует их с использованием формата Android COW.
Виртуальные процессы сжатия A/B
В этих разделах содержится подробная информация о процессах, используемых при виртуальном сжатии A/B: чтение метаданных, слияние и выполнение переходов инициализации.
Чтение метаданных
Метаданные создаются демоном snapuserd
. Метаданные — это прежде всего сопоставление двух идентификаторов, по 8 байтов каждый, которые представляют собой объединяемые сектора. В dm-snapshot
это называется disk_exception
.
struct disk_exception {
uint64_t old_chunk;
uint64_t new_chunk;
};
Дисковое исключение используется, когда старый блок данных заменяется новым.
Демон Snapuserd
считывает внутренний файл COW через библиотеку COW и создает метаданные для каждой из операций COW, представленных в файле COW.
Чтение метаданных инициируется из dm-snapshot
в ядре при dm- snapshot
устройства dm-snapshot.
На рисунке ниже представлена диаграмма последовательности пути ввода-вывода для создания метаданных.
Рис. 4. Последовательность действий для пути ввода-вывода при построении метаданных
Объединение
После завершения процесса загрузки механизм обновления помечает слот как успешную загрузку и инициирует слияние, переключая цель dm-snapshot
на цель dm-snapshot-merge
.
dm-snapshot
просматривает метаданные и инициирует операцию ввода-вывода слияния для каждого исключения диска. Общий обзор пути ввода-вывода слияния показан ниже.
Рис. 5. Обзор пути слияния ввода-вывода
Если устройство перезагружается во время процесса слияния, слияние возобновляется при следующей перезагрузке и завершается.
Начальные переходы
При загрузке со сжатыми моментальными снимками первый этап инициализации должен запускать snapuserd
для монтирования разделов. Это создает проблему: когда sepolicy
загружается и применяется, snapuserd
помещается в неправильный контекст, и его запросы на чтение терпят неудачу с отказами selinux.
Чтобы решить эту проблему, snapuserd
переходит в синхронный режим с init
следующим образом:
-
init
первого этапа запускаетsnapuserd
с виртуального диска и сохраняет в нем открытый файловый дескриптор в переменной окружения. - Первый этап
init
переключает корневую файловую систему на системный раздел, а затем выполняет системную копиюinit
. - Системная копия
init
считывает комбинированную политику sepolicy в строку. -
Init
вызываетmlock()
на всех страницах, поддерживаемых ext4. Затем он деактивирует все таблицы сопоставления устройств для устройств моментальных снимков и останавливаетsnapuserd
. После этого запрещается читать из разделов, так как это приводит к взаимоблокировке. - Используя дескриптор open копии
snapuserd
на виртуальном диске,init
перезапускает демон с правильным контекстом selinux. Таблицы сопоставления устройств для устройств моментальных снимков повторно активируются. - Init вызывает
munlockall()
- безопасно снова выполнить ввод-вывод.
Использование пространства
В следующей таблице представлено сравнение использования пространства для различных механизмов OTA с использованием ОС Pixel и размеров OTA.
Влияние размера | не-A/B | А/Б | Виртуальный А/Б | Виртуальный A/B (сжатый) |
---|---|---|---|---|
Оригинальное заводское изображение | 4,5 ГБ супер (3,8 ГБ изображения + 700 МБ зарезервировано) 1 | 9GB super (3.8G + 700M зарезервировано, для двух слотов) | 4,5 ГБ супер (3,8 ГБ изображения + 700 МБ зарезервировано) | 4,5 ГБ супер (3,8 ГБ изображения + 700 МБ зарезервировано) |
Другие статические разделы | /кэш | Никто | Никто | Никто |
Дополнительное хранилище во время OTA (пространство возвращается после применения OTA) | 1,4 ГБ в / данные | 0 | 3,8 ГБ 2 в / данные | 2,1 ГБ 2 в / данные |
Общий объем хранилища, необходимый для применения OTA | 5,9 ГБ 3 (супер и данные) | 9 ГБ (супер) | 8,3 ГБ 3 (супер и данные) | 6,6 ГБ 3 (супер и данные) |
1 Обозначает предполагаемую компоновку, основанную на сопоставлении пикселей.
2 Предполагается, что новый образ системы имеет тот же размер, что и исходный.
3 Требование к пространству является временным до перезагрузки.
Чтобы реализовать Virtual A/B или использовать возможности сжатых моментальных снимков, см. Реализация Virtual A/B.