Wirtualne A/B to główny mechanizm aktualizacji Androida. Wirtualne testy A/B są oparte na starszych aktualizacjach testów A/B (patrz Aktualizacje systemu A/B) i aktualizacjach innych niż A/B, które w wersji 15 zostały wycofane, aby zmniejszyć rozmiar aktualizacji.
Wirtualne testy A/B nie mają dodatkowego miejsca na partycje dynamiczne. Więcej informacji znajdziesz w sekcji partycje dynamiczne. Zamiast tego delta jest zapisywana w migawce, a następnie scalana z partycją podstawową po potwierdzeniu pomyślnego uruchomienia. Wirtualny test A/B korzysta z formatu migawki specyficznego dla Androida. Więcej informacji znajdziesz w artykule Format COW dla skompresowanych migawek, który umożliwia kompresowanie migawek i minimalizuje wykorzystanie miejsca na dysku. W przypadku pełnej aktualizacji OTA rozmiar migawki jest zmniejszany o około 45% dzięki kompresji, a w przypadku przyrostowej aktualizacji OTA – o około 55%.
Android 12 oferuje opcję kompresji Virtual A/B, która umożliwia kompresowanie migawek partycji. Wirtualne testy A/B oferują:
- Aktualizacje wirtualne A/B są płynne (aktualizacja odbywa się w całości w tle, gdy urządzenie jest włączone), podobnie jak aktualizacje A/B. Aktualizacje wirtualne A/B minimalizują czas, w którym urządzenie jest offline i nie można go używać.
- Aktualizacje wirtualnego testu A/B można wycofać. Jeśli nowy system operacyjny nie uruchomi się, urządzenia automatycznie przywrócą poprzednią wersję.
- Aktualizacje wirtualne A/B wykorzystują minimalną ilość dodatkowego miejsca, ponieważ duplikują tylko partycje używane przez program rozruchowy. Pozostałe partycje, które można zaktualizować, są zapisywane w postaci migawek.
Wprowadzenie i terminologia
W tej sekcji znajdziesz definicje terminów i opis technologii, która obsługuje wirtualne testy A/B. Podczas instalacji OTA nowe dane systemu operacyjnego są zapisywane w nowym slocie w przypadku partycji fizycznych lub na urządzeniu COW specyficznym dla Androida. Po ponownym uruchomieniu urządzenia dane partycji dynamicznej są ponownie scalane z urządzeniem bazowym za pomocą demona dm-user i snapuserd. Ten proces odbywa się w całości w przestrzeni użytkownika.
Device-mapper
Device-mapper to wirtualna warstwa blokowa systemu Linux, która jest często używana w Androidzie. W przypadku partycji dynamicznych partycje takie jak /system
to stos warstwowych urządzeń:
- Na dole stosu znajduje się fizyczna superpartycja (np.
/dev/block/by-name/super
). - Pośrodku znajduje się urządzenie
dm-linear
, które określa, które bloki w superpartycji tworzą daną partycję dynamiczną. Na urządzeniu A/B jest to/dev/block/mapper/system_[a|b]
, a na urządzeniu bez podziału A/B –/dev/block/mapper/system
. - U góry znajduje się
dm-verity
urządzenie utworzone dla zweryfikowanych partycji. To urządzenie sprawdza, czy bloki na urządzeniudm-linear
są prawidłowo podpisane. Wyświetla się jako/dev/block/mapper/system-verity
i jest źródłem punktu montowania/system
.
Na ilustracji 1 widać, jak wygląda stos pod punktem montażowym /system
.
Rysunek 1. Stos pod punktem montowania /system
Skompresowane zrzuty
W Androidzie 12 i nowszych wersjach wymagania dotyczące miejsca na partycji /data
mogą być wysokie. Aby rozwiązać ten problem, możesz włączyć w kompilacji skompresowane migawki./data
Skompresowane migawki wirtualnego testu A/B są oparte na tych komponentach, które są dostępne w Androidzie 12 i nowszym:
dm-user
, moduł jądra podobny do FUSE, który umożliwia przestrzeni użytkownika implementowanie urządzeń blokowych.snapuserd
, demon przestrzeni użytkownika do implementacji nowego formatu zrzutu.
Te komponenty umożliwiają kompresję. Pozostałe niezbędne zmiany wprowadzone w celu wdrożenia funkcji skompresowanych zrzutów są opisane w kolejnych sekcjach: format COW dla skompresowanych zrzutów, dm-user i snapuserd.
Format COW dla skompresowanych zrzutów
W Androidzie 12 i nowszych wersjach skompresowane migawki używają formatu COW specyficznego dla Androida. Format COW zawiera metadane dotyczące aktualizacji OTA i ma odrębne bufory zawierające operacje COW oraz nowe dane systemu operacyjnego. W porównaniu z formatem zrzutu jądra, który umożliwiał tylko operacje zastępowania (zastąp blok X w obrazie podstawowym zawartością bloku Y w zrzucie), format COW skompresowanych zrzutów Androida jest bardziej wyrazisty i obsługuje te operacje:
- Kopiowanie: blok X w urządzeniu podstawowym należy zastąpić blokiem Y w urządzeniu podstawowym.
- Zastąp: blok X na urządzeniu podstawowym należy zastąpić zawartością bloku Y w migawce. Każdy z tych bloków jest skompresowany za pomocą algorytmu gzip.
- Zero: blok X w urządzeniu podstawowym należy zastąpić zerami.
- XOR: urządzenie COW przechowuje bajty skompresowane za pomocą XOR między blokiem X a blokiem Y. (Dostępne na Androidzie 13 i nowszych wersjach).
Pełne aktualizacje OTA składają się tylko z operacji replace i zero. Aktualizacje OTA przyrostowe mogą dodatkowo zawierać operacje kopiowania.
Pełny układ zrzutu na dysku wygląda tak:
Rysunek 2. Format COW na dysku w Androidzie
dm-user
Moduł jądra dm-user umożliwia userspace
implementację urządzeń blokowych device-mapper. Wpis w tabeli dm-user tworzy urządzenie różne w sekcji/dev/dm-user/<control-name>
. userspace
proces może odpytywać urządzenie, aby odbierać żądania odczytu i zapisu z jądra. Z każdym żądaniem jest powiązany bufor przestrzeni użytkownika, który może być wypełniany (w przypadku odczytu) lub propagowany (w przypadku zapisu).
Moduł jądra dm-user
udostępnia nowy interfejs widoczny dla użytkownika, który nie jest częścią kodu źródłowego jądra w kernel.org. Do tego czasu Google zastrzega sobie prawo do modyfikowania interfejsu dm-user
na Androidzie.
snapuserd
Komponent snapuserd
przestrzeni użytkownika dm-user
implementuje kompresję Virtual A/B. Snapuserd to demon przestrzeni użytkownika odpowiedzialny za zapisywanie i odczytywanie urządzeń COW w Androidzie. Cała operacja wejścia/wyjścia do migawki musi przechodzić przez tę usługę.
Podczas instalacji OTA nowe dane systemu operacyjnego są zapisywane w migawce przez proces snapuserd (z kompresją). Tutaj odbywa się też parsowanie metadanych i rozpakowywanie nowych danych bloków.
Kompresja XOR
W przypadku urządzeń z Androidem 13 lub nowszym funkcja kompresji XOR, która jest domyślnie włączona, umożliwia migawkom przestrzeni użytkownika przechowywanie bajtów skompresowanych za pomocą XOR między starymi i nowymi blokami. Gdy w ramach aktualizacji wirtualnego testu A/B zmieni się tylko kilka bajtów w bloku, schemat przechowywania danych z kompresją XOR zajmuje mniej miejsca niż domyślny schemat przechowywania danych, ponieważ migawki nie przechowują pełnych 4096 bajtów. Zmniejszenie rozmiaru migawki jest możliwe, ponieważ dane XOR zawierają wiele zer i łatwiej je skompresować niż surowe dane blokowe. Na urządzeniach Pixel kompresja XOR zmniejsza rozmiar migawki o 25–40%.
W przypadku urządzeń, na których zainstalowano Androida 13 lub nowszego, musi być włączona kompresja XOR. Więcej informacji znajdziesz w artykule Kompresja XOR.
Scalanie zrzutów
W przypadku urządzeń z Androidem 13 lub nowszym procesy tworzenia i scalania migawek w kompresji Virtual A/B są wykonywane przez komponent snapuserd
w przestrzeni użytkownika. W przypadku urządzeń, na których zainstalowano Androida 13 lub nowszego, ta funkcja musi być włączona. Więcej informacji znajdziesz w sekcji Scalanie przestrzeni użytkownika.
Proces kompresji wirtualnych testów A/B wygląda tak:
- Platforma montuje partycję
/system
z urządzeniadm-verity
, które jest umieszczone na urządzeniudm-user
. Oznacza to, że wszystkie operacje wejścia/wyjścia z głównego systemu plików są kierowane dodm-user
. dm-user
kieruje operacje wejścia/wyjścia do demonasnapuserd
przestrzeni użytkownika, który obsługuje żądanie wejścia/wyjścia.- Po zakończeniu operacji scalania ramka
dm-verity
zostanie umieszczona na ramcedm-linear
(system_base
), a ramkadm-user
zostanie usunięta.
Rysunek 3. Wirtualny proces kompresji A/B
Proces scalania zrzutów można przerwać. Jeśli urządzenie zostanie ponownie uruchomione podczas procesu scalania, proces scalania zostanie wznowiony po ponownym uruchomieniu.
Przejścia inicjujące
Podczas uruchamiania z użyciem skompresowanych migawek inicjowanie pierwszego etapu musi rozpocząć się od zamontowania partycji.snapuserd
Stanowi to problem: gdy sepolicy
jest wczytywany i wymuszany, snapuserd
trafia do niewłaściwego kontekstu, a jego żądania odczytu kończą się niepowodzeniem z powodu odmowy SELinux.
Aby to zmienić, snapuserd
przechodzi w tryb zsynchronizowany z init
w ten sposób:
- Na pierwszym etapie
init
uruchamiasnapuserd
z dysku RAM i zapisuje w nim otwarty deskryptor pliku w zmiennej środowiskowej. - Pierwszy etap
init
przełącza główny system plików na partycję systemową, a następnie wykonuje kopię systemowąinit
. - Kopia systemowa
init
odczytuje połączony plik sepolicy do ciągu tekstowego. Init
wywołujemlock()
na wszystkich stronach obsługiwanych przez system ext4. Następnie dezaktywuje wszystkie tabele device-mapper dla urządzeń z migawkami i zatrzymujesnapuserd
. Po tym kroku nie można odczytywać danych z partycji, ponieważ powoduje to zakleszczenie.- Użycie otwartego deskryptora do kopii
snapuserd
w pamięci RAMinit
ponownie uruchamia demona z prawidłowym kontekstem SELinux. Tabele mapowania urządzeń dla urządzeń z migawkami są ponownie aktywowane. - Funkcja Init wywołuje
munlockall()
– można ponownie wykonać operację wejścia/wyjścia.
Wykorzystanie miejsca
W tabeli poniżej znajdziesz porównanie wykorzystania miejsca w przypadku różnych mechanizmów OTA na podstawie rozmiarów systemu operacyjnego i aktualizacji OTA na urządzeniach Pixel.
Wpływ rozmiaru | non-A/B | A/B | Wirtualny test A/B | Wirtualne testy A/B (skompresowane) |
---|---|---|---|---|
Oryginalny obraz fabryczny | 4,5 GB super (3,8 GB obrazu + 700 MB zarezerwowanych)1 | 9 GB super (3, 8 GB + 700 MB zarezerwowane na 2 gniazda) | 4,5 GB super (3,8 GB obrazu + 700 MB zarezerwowanych) | 4,5 GB super (3,8 GB obrazu + 700 MB zarezerwowanych) |
Inne statyczne partycje | /cache | Brak | Brak | Brak |
Dodatkowe miejsce na dane podczas aktualizacji OTA (miejsce jest zwracane po zastosowaniu aktualizacji OTA) | 1,4 GB na partycji /data | 0 | 3,8 GB2 na /data | 2,1 GB2 na /data |
Łączna ilość miejsca na dane wymagana do zastosowania aktualizacji OTA | 5,9 GB3 (super i dane) | 9 GB (super) | 8,3 GB3 (super i dane) | 6,6 GB3 (super i dane) |
1 Wskazuje zakładany układ na podstawie mapowania Pixela.
2Zakłada, że nowy obraz systemu ma taki sam rozmiar jak oryginalny.
3Wymagania dotyczące miejsca są tymczasowe do momentu ponownego uruchomienia.
Wirtualne A/B w Androidzie 11
Android 11 w przypadku wirtualnego A/B zapisywał na partycji dynamicznej dane w formacie Kernel COW. Został on ostatecznie wycofany, ponieważ format Kernel COW nie obsługuje kompresji.
Wirtualne A/B w Androidzie 12
W Androidzie 12 kompresja jest obsługiwana w formacie COW specyficznym dla Androida. Ta wersja wirtualnych testów A/B wymagała przetłumaczenia COW specyficznego dla Androida na format COW jądra. W Androidzie 13 zastąpiono go innym rozwiązaniem, które nie wymagało formatu COW jądra i dm-snapshot
.
Aby wdrożyć wirtualny test A/B lub korzystać ze skompresowanych zrzutów, zapoznaj się z artykułem Wdrażanie wirtualnego testu A/B.