Wdróż wirtualne testy A/B

Aby wdrożyć funkcję wirtualnego A/B na nowym urządzeniu lub zmodernizować urządzenie, należy: musi wprowadzić zmiany w kodzie urządzenia.

Flagi kompilacji

Urządzenia korzystające z wirtualnego testu A/B muszą być skonfigurowane jako poziom A/B. urządzenia i musi uruchomić się za pomocą dynamiczny .

W przypadku urządzeń uruchamianych za pomocą wirtualnego A/B skonfiguruj je tak, aby dziedziczyły wirtualne środowisko A/B podstawowej konfiguracji urządzenia:

$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)

Urządzenia uruchamiane z użyciem technologii A/B potrzebują tylko o połowę mniejszego rozmiaru planszy BOARD_SUPER_PARTITION_SIZE, ponieważ przedziały B nie są już w trybie Super. To znaczy, Wartość BOARD_SUPER_PARTITION_SIZE nie może być mniejsza niż sum(size of update groups) + narzut, który z kolei musi być większy co najmniej suma(rozmiar partycji) + narzut.

W przypadku Androida 13 lub nowszego, aby włączyć skompresowane zrzuty z funkcją wirtualnego A/B dziedziczą następującą konfigurację podstawową:

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/android_t_baseline.mk)

Umożliwia to tworzenie zrzutów przestrzeni użytkownika z użyciem wirtualnych testów A/B przy jednoczesnym korzystaniu z środowiska bezobsługowego metody kompresji. Następnie możesz skonfigurować metodę kompresji jedną z obsługiwane metody: gz, zstd i lz4.

PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4

W Androidzie 12: aby włączyć skompresowane zrzuty dysku za pomocą Wirtualne A/B – dziedziczenie tej konfiguracji podstawowej:

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)

Kompresja XOR

W przypadku urządzeń z Androidem 13 lub nowszym parametr Funkcja kompresji XOR nie jest domyślnie włączone. Aby włączyć kompresję XOR, dodaj ten kod do .mk.

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true

Kompresja XOR jest domyślnie włączona w przypadku urządzeń dziedziczących dane z android_t_baseline.mk

Scalanie przestrzeni użytkownika

W przypadku urządzeń z Androidem 13 lub nowszym parametr proces scalania przestrzeni użytkownika opisany w artykule Device-mapper nakładania warstw nie jest włączone przez wartość domyślną. Aby włączyć scalanie przestrzeni użytkownika, dodaj ten wiersz do pola .mk urządzenia plik:

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true

Scalanie przestrzeni użytkownika jest domyślnie włączone na urządzeniach uruchamianych z 13 lub więcej.

HAL do sterowania rozruchem

Element sterujący uruchamiania HAL udostępnia interfejs klientów OTA do sterowania przedziałami rozruchowymi. Wirtualne A/B wymaga uaktualnienia HAL do wersji podrzędnej, ponieważ dodatkowe interfejsy API są wymagane, by program rozruchowy był chroniony podczas flashowania lub przywracania ustawień fabrycznych. Zobacz IBootControl.hal oraz types.hal aby uzyskać najnowszą wersję definicji HAL.

// hardware/interfaces/boot/1.1/types.hal
enum MergeStatus : uint8_t {
    NONE, UNKNOWN, SNAPSHOTTED, MERGING, CANCELLED };

// hardware/interfaces/boot/1.1/IBootControl.hal
package android.hardware.boot@1.1;
interface IBootControl extends @1.0::IBootControl {
    setSnapshotMergeStatus(MergeStatus status)
        generates (bool success);
    getSnapshotMergeStatus()
        generates (MergeStatus status);
}
// Recommended implementation

Return<bool> BootControl::setSnapshotMergeStatus(MergeStatus v) {
    // Write value to persistent storage
    // e.g. misc partition (using libbootloader_message)
    // bootloader rejects wipe when status is SNAPSHOTTED
    // or MERGING
}

Zmiany Fstab

Integralność partycji metadanych jest kluczowa dla procesu rozruchu, zwłaszcza zaraz po aktualizacji OTA. Partycja metadanych musi więc zostanie sprawdzone, zanim first_stage_init go zamontuje. Aby tak się stało, dodaj parametr check – flaga fs_mgr do wpisu dotyczącego /metadata. Poniżej znajdziesz przykład:

/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check

Wymagania jądra systemu

Aby włączyć tworzenie zrzutów, ustaw CONFIG_DM_SNAPSHOT na true.

W przypadku urządzeń korzystających z F2FS uwzględnij flagę f2fs: export FS_NOCOW_FL do poprawki jądra użytkownika. Uwzględnij atrybut f2fs: support aligns (przypięta) file.

Wirtualne A/B bazuje na funkcjach dodanych w jądrze w wersji 4.3: overflow. bit stanu w celach snapshot i snapshot-merge. Uruchamiam wszystkie urządzenia w Androidzie 9 lub nowszym powinno już być jądro w wersji 4.4 lub nowszej.

Aby można było włączyć skompresowane zrzuty, minimalna obsługiwana wersja jądra to 4.19. Ustaw CONFIG_DM_USER=m lub CONFIG_DM_USER=y. Jeśli korzystasz z poprzedniej wersji (modułu), moduł musi być załadowany na dysku RAM pierwszego etapu. Jest to możliwe dzięki dodając ten wiersz do pliku Makefile na urządzeniu:

BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko

Odświeżanie na urządzeniach z Androidem 11

Po zaktualizowaniu Androida do wersji 11 urządzenia z uruchomionymi partycjami dynamicznymi mogą opcjonalnie zmodernizować wirtualne testy A/B. Proces aktualizacji wygląda prawie tak samo jak w przypadku urządzeń z funkcją wirtualnego A/B, z kilkoma niewielkimi różnicami:

  • Lokalizacja plików COW – w przypadku urządzeń po uruchomieniu klient OTA używa całego wolnego miejsca na superpartycji przed użyciem spacji w /data W przypadku zmodernizowanych urządzeń w panelu Super partycji, dzięki czemu plik COW nigdy nie zostanie utworzony w /data.

  • Flagi funkcji podczas kompilacji – w przypadku urządzeń ze zmodyfikowanymi wirtualnymi A/B: zarówno PRODUCT_VIRTUAL_AB_OTA, jak i PRODUCT_VIRTUAL_AB_OTA_RETROFIT są ustawione do true w następujący sposób:

    (call inherit-product, \
      (SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
    
  • Superparty rozmiar – na urządzeniach uruchamianych z funkcją wirtualnego A/B można wycinać BOARD_SUPER_PARTITION_SIZE na pół, ponieważ przedziały B nie znajdują się w superczacie partycji danych. Urządzenia aktualizujące wirtualną partycję A/B zachowują starą superpartycję rozmiar, więc BOARD_SUPER_PARTITION_SIZE jest większy lub równy 2 * suma(rozmiar grup aktualizacji) + narzut, który z kolei jest większy lub równy 2 * suma(rozmiar partycji) + .

Zmiany programu rozruchowego

Na etapie scalania aktualizacji /data przechowuje jedyne całe wystąpienie instancji System operacyjny Android. Po rozpoczęciu migracji system, vendor i Partycje (product) są niepełne, dopóki kopiowanie nie zostanie ukończone. Jeśli urządzenie jest zresetowany w trakcie tego procesu do ustawień fabrycznych, przy użyciu procedury odzyskiwania lub ustawień, nie będzie można uruchomić urządzenia.

Przed wykasowaniem danych /data dokończ scalanie w ramach przywracania lub wycofywanie, w zależności od stan urządzenia:

  • Jeśli nowa kompilacja uruchomiła się wcześniej, dokończ migrację.
  • W przeciwnym razie wróć do starego przedziału:
    • W przypadku partycji dynamicznych przywróć poprzedni stan.
    • W przypadku partycji statycznych ustaw aktywny przedział na stary.

Zarówno program rozruchowy, jak i fastbootd mogą wymazać partycję /data, jeśli urządzenie jest odblokowane. Parametr fastbootd może wymusić migrację, ale adres programu rozruchowego nie może. Program rozruchowy nie wie, czy trwa scalanie lub jakie bloki w /data tworzą partycje systemu operacyjnego. Urządzenia muszą zapobiec nieświadomemu dezaktualizacji urządzenia (cegły) przez wykonując te czynności:

  1. Wdróż kod HAL elementu sterującego rozruchem, aby program rozruchowy mógł odczytywać ustawioną wartość za pomocą metody setSnapshotMergeStatus().
  2. Jeśli stan scalania to MERGING lub SNAPSHOTTED a boks zmienił się na zaktualizowany, a następnie pojawi się prośba o wyczyszczenie pamięci. userdata, metadata lub partycja, w której jest przechowywany stan scalania, musi mieć wartość odrzucone w programie rozruchowym.
  3. Wdróż polecenie fastboot snapshot-update cancel, aby użytkownicy mogli zasygnalizować programowi rozruchowemu, że chce ominąć ten mechanizm zabezpieczający.
  4. Zmodyfikuj niestandardowe narzędzia lub skrypty do flashowania, aby w przypadku całego urządzenia włączały kod fastboot snapshot-update cancel. Jest to bezpieczne, ponieważ aktualizacja całego urządzenia powoduje usunięcie OTA. Narzędzia mogą wykryć to polecenie w czasie działania, implementując interfejs fastboot getvar snapshot-update-status. Ten ułatwia rozróżnianie warunków błędu.

Przykład

struct VirtualAbState {
    uint8_t StructVersion;
    uint8_t MergeStatus;
    uint8_t SourceSlot;
};

bool ShouldPreventUserdataWipe() {
    VirtualAbState state;
    if (!ReadVirtualAbState(&state)) ...
    return state.MergeStatus == MergeStatus::MERGING ||
           (state.MergeStatus == MergeStatus::SNAPSHOTTED &&
            state.SourceSlot != CurrentSlot()));
}

Zmiany w narzędziach Fastboot Tool

Android 11 wprowadza te zmiany w szybkim rozruchu protokół:

  • getvar snapshot-update-status – zwraca wartość ustawienia rozruchu. element sterujący HAL przekazywany do programu rozruchowego:
    • Jeśli stan to MERGING, program rozruchowy musi zwrócić wartość merging.
    • Jeśli stan to SNAPSHOTTED, program rozruchowy musi zwrócić wartość snapshotted.
    • W przeciwnym razie program rozruchowy musi zwracać wartość none.
  • snapshot-update merge – wykonuje operację scalania, uruchamia się w razie potrzeby przy użyciu systemu odzyskiwania/szybkiego rozruchu. To polecenie jest prawidłowe tylko wtedy, gdy Komponent snapshot-update-status to merging i jest obsługiwany tylko w trybie szybkiego rozruchu.
  • snapshot-update cancel – ustawia stan scalania elementu sterującego rozruchem na CANCELLED To polecenie jest nieprawidłowe, gdy urządzenie jest zablokowane.
  • erase lub wipeerase lub wipe o wartości metadata, userdata lub partycja ze stanem scalania dla HAL kontroli rozruchu powinna sprawdzić oraz stan scalania zrzutów. Jeśli stan to MERGING lub SNAPSHOTTED, parametr powinno przerwać operację.
  • set_active – polecenie set_active, które zmienia aktywny przedział powinien sprawdzić stan scalania zrzutów. Jeśli stan to MERGING, powinno przerwać operację. Przedział można bezpiecznie zmienić w SNAPSHOTTED stan.

Te zmiany mają na celu zapobieganie przypadkowemu odłączeniu urządzenia od rozruchu. ale mogą też zakłócać pracę zautomatyzowanych narzędzi. Gdy te polecenia są używane jako Flashowanie wszystkich partycji, np. uruchamianie programu fastboot flashall, zalecamy użycie tego procesu:

  1. Zapytanie getvar snapshot-update-status.
  2. Jeśli merging lub snapshotted, wydanie snapshot-update cancel.
  3. Kontynuuj miganie ekranu.
.

Zmniejszanie wymagań dotyczących miejsca na dane

Urządzenia, które nie mają pełnej pamięci A/B przydzielonej w trybie Super i oczekują do użycia w razie potrzeby funkcji /data, zdecydowanie zalecamy użycie mapowania bloków . Narzędzie do mapowania bloków dba o spójność przydziału bloków między kompilacjami, z myślą o ograniczeniu niepotrzebnych zapisów do zrzutu. Zostało to opisane w sekcji Zmniejszanie rozmiar OTA.

Metody kompresji OTA

Pakiety OTA można dostroić pod kątem różnych wskaźników wydajności. Android zapewnia kilka obsługiwanych metod kompresji (gz, lz4, zstd i none), które między czasem instalacji, wykorzystaniem przestrzeni COW, czasem uruchamiania i zrzutem ekranu. czas scalania. Domyślna opcja włączona dla wirtualnego panelu ab z kompresją to gz compression method (Uwaga: względna wydajność różnych metod kompresji różni się w zależności od szybkości procesora i przepustowości pamięci masowej, które mogą się zmieniać w zależności na urządzeniu. Wszystkie wygenerowane poniżej pakiety OTA mają wyłączoną opcję PostInstall, która może nieco spowolnić uruchamianie. Całkowity rozmiar partycji dynamicznej pełna wersja OTA bez kompresji wynosi 4,81 GB).

Przyrostowa aktualizacja OTA na Pixelu 6 Pro

Czas instalacji bez etapu po instalacji Wykorzystanie miejsca na dane w COW Czas po uruchomieniu OTA Czas scalenia zrzutu
GZ 24 min 1,18 GB 40,2 s 45,5 s
LZ4 13 min 1,49 GB 37,4 s 37,1 s
brak 13 min 2,90 GB 37,6 s 40,7 s

Pełna aktualizacja OTA w telefonie Pixel 6 Pro

Czas instalacji bez etapu po instalacji Korzystanie z przestrzeni COW Czas po uruchomieniu OTA Czas scalenia zrzutu
GZ 23 min 2,79 GB 24,9 s 41,7 s
LZ4 12 min 3,46 GB 20,0 s 25,3 s
brak 10 min 4,85 GB 20,6 s 29,8 s