Wirtualne przeglądy A/B

Wirtualne 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 aktualizacjach innych niż A/B, które w wersji 15 zostały wycofane, aby zmniejszyć obciążenie przestrzeni aktualizacji.

Wirtualne testy A/B nie mają dodatkowego miejsca na dynamiczne podziały. Więcej informacji znajdziesz w sekcji dynamiczne podziały. Zamiast tego delta jest zapisywana w zrzucie, a następnie scalana z partycją podstawową po potwierdzeniu pomyślnego uruchomienia. Wirtualny test A/B korzysta z formatu migawki specyficznego dla Androida. Zapoznaj się z informacjami o formacie COW w przypadku 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 wirtualnej 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 wycofają zmiany do poprzedniej wersji.
  • Aktualizacje wirtualne A/B wykorzystują minimalną ilość dodatkowego miejsca, ponieważ duplikują tylko partycje używane przez program rozruchowy. Inne 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ą 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 oznaczone jako /dev/block/mapper/system_[a|b], a na urządzeniu bez podziału A/B – jako /dev/block/mapper/system.
  • U góry znajduje się urządzenie dm-verity utworzone dla zweryfikowanych partycji. To urządzenie sprawdza, czy bloki na urządzeniu dm-linear są prawidłowo podpisane. Wyświetla się jako /dev/block/mapper/system-verity i jest źródłem punktu podłączania /system.

Na ilustracji 1 widać, jak wygląda stos pod punktem podłączania /system.

Partycja ułożona pod systemem

Rysunek 1. Stos pod punktem podłączania /system

Skompresowane zrzuty

W Androidzie 12 i nowszych wersjach wymagania dotyczące miejsca na partycji /data mogą być wysokie, dlatego w kompilacji możesz włączyć skompresowane migawki, aby rozwiązać problem z większymi wymaganiami dotyczącymi miejsca na partycji /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-usersnapuserd.

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 nowszym).

Pełne aktualizacje OTA składają się tylko z operacji replacezero. Aktualizacje przyrostowe OTA mogą dodatkowo zawierać operacje kopiowania.

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

format krowy,

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żdą prośbą 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ą bazy kodu jądra upstream w witrynie 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 też odbywa się parsowanie metadanych i rozpakowywanie nowych danych bloków.

Kompresja XOR

W przypadku urządzeń z Androidem 13 lub nowszym domyślnie włączona funkcja kompresji XOR umożliwia migawkom przestrzeni użytkownika przechowywanie bajtów skompresowanych za pomocą XOR między starymi i nowymi blokami. Gdy w 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 wirtualnego testu A/B wygląda tak:

  1. Platforma montuje partycję /system na urządzeniu dm-verity, które jest umieszczone na urządzeniu dm-user. Oznacza to, że wszystkie operacje wejścia/wyjścia z głównego systemu plików 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 wejścia/wyjścia.
  3. Po zakończeniu operacji scalania ramka dm-verity zostanie umieszczona na ramce dm-linear (system_base), a ramka dm-user zostanie usunięta.

Wirtualna kompresja A/B

Rysunek 3. Wirtualny proces kompresji A/B

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

Przejścia inicjujące

Podczas uruchamiania z użyciem skompresowanych migawek inicjowanie pierwszego etapu musi rozpocząć snapuserd, aby zamontować partycje. Stanowi to problem: gdy sepolicy jest wczytywany i wymuszany, snapuserd jest umieszczany w niewłaściwym kontekście, a jego żądania odczytu kończą się niepowodzeniem z powodu odmowy SELinux.

Aby to zmienić, snapuserd przechodzi na init w następujący sposób:

  1. Na pierwszym etapie init uruchamia snapuserd z dysku RAM i zapisuje w zmiennej środowiskowej otwarty deskryptor pliku.
  2. Pierwszy etap init przełącza główny system plików na partycję systemową, a następnie wykonuje kopię systemową init.
  3. Kopia systemowa init odczytuje połączony plik sepolicy do ciągu tekstowego.
  4. Init wywołuje mlock() na wszystkich stronach obsługiwanych przez system ext4. Następnie dezaktywuje wszystkie tabele device-mapper dla urządzeń z migawkami i zatrzymuje snapuserd. Po tym kroku nie można odczytywać danych z partycji, ponieważ powoduje to zakleszczenie.
  5. Użycie otwartego deskryptora do kopii snapuserd w ramdysku init ponownie uruchamia demona z prawidłowym kontekstem SELinux. Tabele mapowania urządzeń dla urządzeń z migawkami są ponownie aktywowane.
  6. 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 aktualizacji OTA na podstawie rozmiarów systemu operacyjnego i aktualizacji OTA na urządzeniach Pixel.

Wpływ rozmiaru nie A/B, A/B Wirtualny test A/B Wirtualne testy A/B (skompresowane)
Oryginalny obraz fabryczny 4,5 GB super (3,8 GB obraz + 700 MB zarezerwowane)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 /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 pikseli.

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 zapisuje w partycji dynamicznej dane w formacie Kernel COW. Zostało ono ostatecznie wycofane, ponieważ format COW jądra nie obsługuje kompresji.

Wirtualne aktualizacje A/B w Androidzie 12

W Androidzie 12 kompresja jest obsługiwana w formacie COW specyficznym dla Androida. Ta wersja wirtualnego testu A/B wymagała przetłumaczenia COW specyficznego dla Androida na format COW jądra. W Androidzie 13 zastąpiono go 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.