Wirtualne przeglądy A/B

Wirtualna aktualizacja A/B to główny mechanizm aktualizacji Androida. Wirtualne testy A/B są oparte na starszych aktualizacjach A/B (patrz Aktualizacje systemu A/B) i niebędących testami A/B, które zostały wycofane w wersji 15, aby zmniejszyć ilość zajmowanego miejsca przez aktualizacje.

Testy A/B w wersji wirtualnej nie mają dodatkowego miejsca na dynamiczne partycje (patrz dynamiczne partycje). Zamiast tego delta jest zapisywana w zrzucie, a potem scalona z partycją podstawową po potwierdzeniu udanego rozruchu. Wirtualny A/B używa formatu zrzutu specyficznego dla Androida. Zapoznaj się z formatem COW dla skompresowanych migawek, który umożliwia kompresowanie migawek i minimalizowanie wykorzystania miejsca na dysku. W przypadku pełnego OTA rozmiar zrzutu ekranu zmniejsza się o około 45% dzięki kompresji, a w przypadku przyrostowego OTA – o około 55%.

Android 12 oferuje opcję kompresji wirtualnej A/B do kompresji partycji z migawkami. Wirtualne A/B:

  • Wirtualne aktualizacje A/B są płynne (aktualizacja odbywa się całkowicie w tle, gdy urządzenie jest w stanie gotowości) tak jak aktualizacje A/B. Wirtualne aktualizacje A/B minimalizują czas, przez jaki urządzenie jest offline i bezużyteczne.
  • Aktualizacje testów A/B w wersji testowej można cofnąć. Jeśli nowy system operacyjny nie uruchomi się, urządzenia automatycznie wrócą do poprzedniej wersji.
  • Wirtualne aktualizacje A/B zajmują minimalną ilość dodatkowego miejsca, ponieważ dublują tylko partycje używane przez bootloader. Pozostałe partycje, które można aktualizować, są zabezpieczone za pomocą migawki.

Informacje ogólne i terminologia

W tej sekcji znajdziesz definicje terminów i opis technologii, która obsługuje testy A/B w sieci. Podczas instalacji OTA nowe dane systemu operacyjnego są zapisywane w nowym gnieździe na partycje fizyczne lub na urządzeniu COW dla Androida. Po ponownym uruchomieniu urządzenia dane dynamicznej partycji są scalane z urządzeniem podstawowym za pomocą demona dm-user i snapuserd. Ten proces odbywa się całkowicie w przestrzeni użytkownika.

Device-mapper

Device-mapper to wirtualna warstwa bloków Linuksa często używana w Androidzie. W przypadku dynamicznych partycji partycje takie jak /system to zestaw urządzeń ułożonych warstwowo:

  • Na dole stosu znajduje się fizyczna superpartycja (na przykład /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 z testami A/B jest to /dev/block/mapper/system_[a|b], a na urządzeniu bez testów A/B – /dev/block/mapper/system.
  • U góry znajduje się urządzenie dm-verity utworzone dla zweryfikowanych partycji. To urządzenie sprawdza, czy blokady na urządzeniu dm-linear są prawidłowo podpisane. Wyświetla się jako /dev/block/mapper/system-verity i jest źródłem punktu montowania /system.

Rysunek 1 przedstawia zespół elementów pod punktem mocowania /system.

Umieszczanie partycji pod systemem

Rysunek 1. stos pod punktem podłączenia /system;

skompresowane zrzuty,

W Androidzie 12 i nowszych wersjach, ponieważ wymagania dotyczące miejsca na partycji /data mogą być wysokie, możesz włączyć skompresowane migawki w wersji kompilacji, aby zaspokoić większe wymagania dotyczące miejsca na partycji /data.

Wirtualne migawki z kompresją A/B są tworzone na podstawie tych komponentów dostępnych w Androidzie 12 i nowszych:

  • dm-user, moduł jądra podobny do FUSE, który umożliwia implementację blokowania urządzeń w przestrzeni użytkownika.
  • snapuserd, demon w przestrzeni użytkownika do implementacji nowego formatu zrzutu.

Te komponenty umożliwiają kompresję. Pozostałe zmiany niezbędne do wdrożenia funkcji skompresowanych zrzutów zostały opisane w następnych sekcjach: format COW dla skompresowanych zrzutów, dm-usersnapuserd.

Format COW dla skompresowanych zrzutów

W Androidzie 12 i nowszych skompresowane zrzuty dysku korzystają z formatu COW specyficznego dla Androida. Format COW zawiera metadane dotyczące OTA oraz oddzielne bufory z operacjami COW i nowymi danymi systemu operacyjnego. W porównaniu z formatem zrzutu jądra, który dopuszczał jedynie operacje zastąp (zastąp blok X w obrazie podstawowym treścią bloku Y w zrzucie), format COW skompresowanych zrzutów Androida jest bardziej ekspresyjny i obsługuje te operacje:

  • Copy: Block X in the base device should be replaced with block Y in the base device.
  • Zastąp: blok X na urządzeniu bazowym należy zastąpić zawartością bloku Y na zrzucie ekranu. Każdy z tych bloków jest skompresowany w formacie gz.
  • Zero: blok X na urządzeniu bazowym powinien zostać zastąpiony przez wszystkie zera.
  • XOR: urządzenie COW przechowuje bajty skompresowane za pomocą XOR między blokiem X a blokiem Y. (dostępne w Androidzie 13 i nowszych).

Pełne aktualizacje OTA składają się tylko z operacji zastępowaniazera. Przyrostowe aktualizacje OTA mogą dodatkowo zawierać operacje kopiowania.

Pełny układ zrzutu na dysku wygląda tak:

format krowy

Rysunek 2. Format COW Androida na dysku

dm-user

Moduł jądra systemu dm-user umożliwia usłudze userspace wdrażanie urządzeń blokowych platformy mapowania urządzeń. Wpis w tabeli dm-user tworzy urządzenie różne w grupie /dev/dm-user/<control-name>. Proces userspace może przeprowadzać sondowanie urządzenia w celu otrzymywania żądań odczytu i zapisu z jądra. Każde żądanie ma powiązany bufor dla przestrzeni użytkownika, który może być wypełniany (w przypadku odczytu) lub rozpowszechniany (w przypadku zapisu).

Moduł jądra dm-user udostępnia nowy interfejs jądra widoczny dla użytkownika, który nie jest częścią bazy kodu kernel.org. Do tego czasu Google zastrzega sobie prawo do modyfikowania interfejsu dm-user w Androidzie.

snapuserd

Komponent snapuserd w przestrzeni użytkownika w dm-user implementuje kompresję A/B wirtualną. Snapuserd to demon przestrzeni użytkownika, który zapisuje i odczytuje urządzenia COW z Androidem. Wszystkie operacje wejścia-wyjścia dla zrzutu muszą przechodzić przez tę usługę. Podczas instalacji OTA nowe dane systemu operacyjnego są zapisywane w zrzutu przez przyciągnięty element (z kompresją). Tutaj też odbywa się analizowanie metadanych i rozpakowywanie nowych bloków danych.

Kompresja XOR

W przypadku urządzeń uruchamianych z Androidem 13 lub nowszym funkcja kompresji XOR, która jest domyślnie włączona, umożliwia migawek w przestrzeni użytkownika przechowywanie bajtów za pomocą kompresji XOR między starymi blokami a nowymi blokami. Gdy w ramach aktualizacji Virtual A/B zmienia się tylko kilka bajtów w bloku, schemat kompresji XOR zajmuje mniej miejsca niż domyślny schemat przechowywania, ponieważ migawki nie przechowują pełnych bajtów 4K. Zmniejszenie rozmiaru zrzutu ekranu jest możliwe, ponieważ dane XOR zawierają wiele zer i są łatwiejsze do skompresowania niż dane bloku w formacie RAW. Na urządzeniach Pixel kompresja XOR zmniejsza rozmiar zrzutu ekranu o 25–40%.

W przypadku urządzeń aktualizowanych do Androida 13 lub nowszego kompresja XOR musi być włączona. Więcej informacji znajdziesz w artykule Kompresja XOR.

Scalanie zrzutów

W przypadku urządzeń z Androidem 13 lub nowszym procesy tworzenia kopii zapasowej i łączenia kopii zapasowych w ramach kompresji wirtualnej metody A/B są wykonywane przez komponent snapuserd w przestrzeni użytkownika. Na urządzeniach z Androidem 13 lub nowszym ta funkcja musi być włączona. Więcej informacji znajdziesz w artykule Połączenie przestrzeni użytkownika.

Poniżej opisujemy proces wirtualnej kompresji A/B:

  1. Platforma montuje partycję /system z urządzenia dm-verity, które jest umieszczone na urządzeniu dm-user. Oznacza to, że wszystkie operacje wejścia/wyjścia z systemu plików katalogu głównego są kierowane do dm-user.
  2. dm-user kieruje operacje wejścia/wyjścia do demona snapuserd w przestrzeni użytkownika, który obsługuje żądanie operacji wejścia/wyjścia.
  3. Po zakończeniu operacji scalania framework łączy dm-verity z poziomu dm-linear (system_base) i usuwa dm-user.

Wirtualny proces kompresji A/B

Rysunek 3. Proces wirtualnej kompresji A/B

Proces łączenia zrzutów może zostać przerwany. Jeśli podczas procesu łączenia urządzenie zostanie ponownie uruchomione, proces ten zostanie wznowiony po ponownym uruchomieniu.

Przejścia początkowe

Aby można było podłączyć partycje, w przypadku uruchamiania ze skompresowanymi zrzutami musi rozpoczynać się pierwszy etap inicjowania snapuserd. To powoduje problem: gdy sepolicy zostanie załadowany i wdrożony, snapuserd zostanie umieszczony w niewłaściwym kontekście, a jego żądania odczytu będą się nieudać z powodu odmów ze strony selinux.

Aby to rozwiązać, snapuserd przechodzi w tryb synchroniczny z init w taki sposób:

  1. Pierwszy etap init uruchamia snapuserd z dysku RAM i zapisuje do niego otwarty deskryptor pliku w zmiennej środowiskowej.
  2. Pierwszy etap init przełącza system plików /root na partycję systemową, a następnie uruchamia kopię systemową init.
  3. Kopie init odczytuje połączoną politykę bezpieczeństwa jako ciąg znaków.
  4. Na wszystkich stronach obsługiwanych przez ext4 funkcja Init wywołuje metodę mlock(). Następnie dezaktywuje wszystkie tabele mapowania urządzeń dla urządzeń z migawkami i zatrzymuje snapuserd. Po tym nie można odczytywać danych z partycji, ponieważ powoduje to blokadę.
  5. Za pomocą otwartego deskryptora kopii snapuserd na dysku ramdysk init ponownie uruchamia demona z poprawnym kontekstem selinux. Tabele mapowania urządzeń dla urządzeń z migawką zostały ponownie aktywowane.
  6. Init wywołuje munlockall() – można ponownie bezpiecznie wykonywać operacje wejścia/wyjścia.

Wykorzystanie miejsca

W tabeli poniżej porównano wykorzystanie miejsca na potrzeby różnych mechanizmów OTA, korzystając z rozmiarów systemu operacyjnego i OTA w Pixelu.

Wpływ na rozmiar nie A/B A/B Wirtualny test A/B Wirtualny test A/B (skompresowany)
Oryginalne zdjęcie fabryczne 4,5 GB super (3,8 GB obraz + 700 M zarezerwowane)1 9 GB super (3, 8 GB + 700 M MB zarezerwowane na 2 miejsca) 4,5 GB super (3,8 GB obraz + 700 MB zarezerwowane) Super 4,5 GB (obraz 3,8 G + 700 MB zarezerwowane)
Inne partycje statyczne /cache Brak Brak Brak
Dodatkowe miejsce podczas aktualizacji OTA (miejsce zwrócone po zastosowaniu aktualizacji OTA) 1,4 GB na /data 0 3,8 GB2 w folderze /data 2,1 GB2 wł. /data
Łączna ilość miejsca na dane wymagana do stosowania aktualizacji OTA 5,9 GB3 (super i dane) 9GB (super) 8,3 GB3 (super i dane) 6,6 GB3 (superczat i dane)

1 Wskazuje przypuszczalny układ na podstawie mapowania Pixela.

2 Zakładamy, że nowy obraz systemu ma taki sam rozmiar jak oryginalny.

3 Wymagania dotyczące miejsca są tymczasowe do czasu ponownego uruchomienia.

Android 11 Virtual A/B

Android 11 środowiska wirtualnego A/B zapisał dane do partycji dynamicznej za pomocą formatu COW jądra. Zostało to ostatecznie wycofane, ponieważ format COW jądra nie obsługuje kompresji.

Android 12 Virtual A/B

W Androidzie 12 kompresja jest obsługiwana w postaci formatu COW specyficznego dla tego systemu. Ta wersja wirtualnego A/B wymaga tłumaczenia COW dla Androida na format COW jądra. Ostatecznie w Androidzie 13 został on zastąpiony, co wyeliminowało zależność od formatu Kernel COW i z funkcji dm-snapshot.

Aby wdrożyć testy A/B wirtualnych lub korzystać z możliwości skompresowanych zrzutów, przeczytaj artykuł Wdrażanie testów A/B wirtualnych.