Wdrażanie testów A/B wirtualnych

Aby wdrożyć wirtualne testy A/B na nowym urządzeniu lub dostosować do nich urządzenie, które zostało już wprowadzone na rynek, musisz wprowadzić zmiany w kodzie specyficznym dla urządzenia.

Flagi kompilacji

Urządzenia korzystające z wirtualnego A/B muszą być skonfigurowane jako urządzenia A/B i muszą uruchamiać się z dynamicznymi partycjami.

W przypadku urządzeń, które są wprowadzane na rynek z wirtualnym A/B, ustaw je tak, aby dziedziczyły podstawową konfigurację urządzenia z wirtualnym A/B:

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

Urządzenia z wirtualnym A/B potrzebują o połowę mniejszej płyty głównej, ponieważ gniazda B nie są już w trybie super.BOARD_SUPER_PARTITION_SIZE Oznacza to, że BOARD_SUPER_PARTITION_SIZE musi być większe lub równe sum(rozmiar grup aktualizacji) + narzut, co z kolei musi być większe lub równe sum(rozmiar partycji) + narzut.

Aby włączyć skompresowane migawki w przypadku Androida 13 lub nowszego z wirtualnym A/B, odziedzicz poniższą konfigurację podstawową:

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

Umożliwia to tworzenie migawek przestrzeni użytkownika z wirtualnym A/B przy użyciu metody kompresji no-op. Następnie możesz skonfigurować metodę kompresji,wybierając jedną z obsługiwanych metodzstdlz4. W przypadku Androida 15 kompresję można jeszcze bardziej dostosować do potrzeb urządzenia. Więcej informacji znajdziesz w artykule Dostrajanie kompresji.

PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4
PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 65536

Aby w Androidzie 12 włączyć skompresowane zrzuty z wirtualnym testowaniem A/B, odziedzicz tę konfigurację podstawową:

$(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ń, które przechodzą na Androida 13 lub nowszego, funkcja kompresji XOR nie jest domyślnie włączona. Aby włączyć kompresję XOR, dodaj te informacje do pliku .mk urządzenia.

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

Kompresja XOR jest domyślnie włączona na urządzeniach, które dziedziczą z android_t_baseline.mk.

Scalanie przestrzeni użytkownika

W nowoczesnej wersji testów A/B wirtualnych (Android T i nowsze) proces scalania migawek odbywa się w całości w przestrzeni użytkownika. Zmiana ta jest możliwa dzięki snapuserd i dm-user. Na urządzeniach wprowadzanych na rynek z Androidem 13 lub nowszym scalanie przestrzeni użytkownika jest domyślnie włączone. W przypadku starszych urządzeń, które są aktualizowane, tę właściwość można ustawić w ten sposób:

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

Warstwa HAL sterowania uruchamianiem

Warstwa HAL boot control udostępnia interfejs, za pomocą którego klienci OTA mogą sterować gniazdami rozruchowymi. Wirtualne testy A/B wymagają aktualizacji do nowszej wersji HAL sterowania rozruchem, ponieważ do ochrony bootloadera podczas flashowania lub przywracania ustawień fabrycznych potrzebne są dodatkowe interfejsy API. Najnowszą wersję definicji HAL znajdziesz w plikach IBootControl.haltypes.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 w pliku fstab

Integralność partycji metadanych ma kluczowe znaczenie dla procesu uruchamiania, zwłaszcza bezpośrednio po zastosowaniu aktualizacji OTA. Dlatego przed zamontowaniem woluminu first_stage_init musi sprawdzić partycję metadanych. Aby to zapewnić, dodaj do wpisu dla /metadata flagę check fs_mgr. Oto przykład:

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

Wymagania dotyczące jądra

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

W przypadku urządzeń korzystających z systemu F2FS dodaj flagę f2fs: export FS_NOCOW_FL flag to user do poprawki jądra, aby naprawić przypinanie plików. Dołącz też łatkę jądra f2fs: support aligned pinned file.

Wirtualne testy A/B korzystają z funkcji dodanych w wersji jądra 4.3: bitu stanu overflow w elementach docelowych snapshotsnapshot-merge. Wszystkie urządzenia z Androidem 9 lub nowszym powinny mieć już jądro w wersji 4.4 lub nowszej.

Aby 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 używasz pierwszej opcji (modułu), musi on być załadowany w ramdysku pierwszego etapu. Można to osiągnąć, dodając ten wiersz do pliku Makefile urządzenia:

BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko

Zmiany w narzędziach Fastboot

W Androidzie 11 wprowadzono te zmiany w protokole fastboot:

  • getvar snapshot-update-status – zwraca wartość, którą interfejs HAL boot control przekazał 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 zwrócić wartość none.
  • snapshot-update merge – kończy operację scalania, w razie potrzeby uruchamiając tryb recovery lub fastbootd. To polecenie jest prawidłowe tylko wtedy, gdy snapshot-update-status ma wartość merging, i jest obsługiwane tylko w trybie fastbootd.
  • snapshot-update cancel – ustawia stan scalania interfejsu HAL sterowania uruchamianiem na CANCELLED. To polecenie jest nieprawidłowe, gdy urządzenie jest zablokowane.
  • erase lub wipe – erase lub wipe w przypadku metadata, userdata lub partycji zawierającej stan scalania dla HAL kontroli rozruchu powinny sprawdzać stan scalania migawki. Jeśli stan to MERGING lub SNAPSHOTTED, urządzenie powinno przerwać działanie.
  • set_active – polecenie set_active, które zmienia aktywny slot, powinno sprawdzać stan scalania migawki. Jeśli stan to MERGING, urządzenie powinno przerwać operację. Gniazdo można bezpiecznie zmienić w stanie SNAPSHOTTED.

Te zmiany mają zapobiegać przypadkowemu uniemożliwieniu uruchomienia urządzenia, ale mogą zakłócać działanie zautomatyzowanych narzędzi. Jeśli polecenia są używane jako element flashowania wszystkich partycji, np. podczas uruchamiania polecenia fastboot flashall, zalecamy wykonanie tych czynności:

  1. Zapytanie getvar snapshot-update-status
  2. Jeśli merging lub snapshotted, zgłoś snapshot-update cancel.
  3. Wykonaj czynności związane z flashowaniem.

Zmniejsz wymagania dotyczące miejsca na dane

Urządzenia, które nie mają w superprzestrzeni w pełni przydzielonej pamięci A/B i w razie potrzeby mają korzystać z /data, zdecydowanie powinny używać narzędzia do mapowania bloków. Narzędzie do mapowania bloków zapewnia spójność przydzielania bloków między kompilacjami, co ogranicza niepotrzebne zapisywanie w zrzucie. Jest to opisane w sekcji Zmniejszanie rozmiaru aktualizacji OTA.

Algorytmy kompresji OTA

Pakiety OTA można dostosowywać do różnych wskaźników wydajności. Android obsługuje kilka metod kompresji (lz4, zstdnone), które mają różne zalety i wady w zakresie czasu instalacji, wykorzystania przestrzeni COW, czasu rozruchu i czasu scalania migawek. Domyślnie w przypadku wirtualnego konta bankowego z kompresją włączona jest opcja lz4 compression method.

Dostrajanie kompresji

Algorytmy kompresji można dodatkowo dostosowywać za pomocą 2 metod: poziomu kompresji (wielkość kompresji osiągnięta kosztem szybkości) i współczynnika kompresji (maksymalny rozmiar okna kompresji). Poziom kompresji jest dostępny w przypadku niektórych algorytmów, np. zstd. Zmiana poziomu wiąże się z kompromisem między szybkością a współczynnikiem kompresji. Współczynnik kompresji określa maksymalny rozmiar okna kompresji używanego podczas instalacji OTA. Domyślna wartość to 64 tys., ale można ją zastąpić, dostosowując parametr kompilacji PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR. Obsługiwane współczynniki kompresji: 4 tys., 8 tys., 16 tys., 32 tys., 64 tys., 128 tys. i 256 tys.

PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 65536

Przyrostowa aktualizacja OTA na Pixelu 8 Pro

Czas instalacji bez fazy po instalacji Wykorzystanie miejsca COW Czas uruchamiania po aktualizacji OTA Czas scalania zrzutu
lz4 18 min 15 s 2,5 GB 32,7 s 98,6 s
zstd 24 min 49 s 2,05 GB 36,3 s 133,2 s
brak 16 min 42 s 4,76 GB 28,7 s 76,6 s

Pełna aktualizacja OTA na Pixelu 8 Pro

Czas instalacji bez fazy po instalacji Wykorzystanie miejsca COW Czas uruchamiania po aktualizacji OTA Czas scalania zrzutu
lz4 15 min 11 s 4,16 GB 17,6 s 82,2 s
zstd 16 min 19 s 3,46 GB 21,0 s 106,3 s
brak 13 min 33 s 6,39 GB 18,5 s 92,5 s