Miękkie ponowne uruchamianie (wersja AOSP 14 i starsze)

Android 11 obsługuje ponowne uruchomienie w tle, czyli ponowne uruchomienie procesów w przestrzeni użytkownika w czasie działania systemu. Jest ono używane do stosowania aktualizacji, które wymagają ponownego uruchomienia (np. aktualizacji pakietów APEX). Obecnie ponowne uruchomienie w tle jest ograniczone do procesów, które zostały uruchomione po zamontowaniu partycji userdata.

Ponowne uruchomienie w tle można wywołać na te sposoby:

  • z poziomu PowerManager przez wywołanie PowerManager.reboot(PowerManager.REBOOT_USERSPACE)

  • z poziomu powłoki za pomocą polecenia adb shell svc power reboot userspace lub adb reboot userspace

Po ponownym uruchomieniu w tle zaszyfrowany magazyn danych uwierzytelniających pozostaje odblokowany.

Jeśli urządzenie obsługuje ponowne uruchomienie w tle, metoda interfejsu API PowerManager.isRebootingUserspace() zwraca wartość true, a wartość właściwości systemowej init.userspace_reboot.is_supported jest równa 1.

Jeśli urządzenie nie obsługuje ponownego uruchomienia w tle, wywołania PowerManager.reboot(PowerManager.REBOOT_USERSPACE), adb reboot userspace, i adb shell svc power reboot userspace kończą się niepowodzeniem.

Wykonanie ponownego uruchomienia w tle

Gdy zażądane zostanie ponowne uruchomienie w tle (za pomocą PowerManager lub z poziomu powłoki), init wykona te czynności:

  1. Otrzyma sys.powerctl=reboot,userspace.

  2. Utworzy osobny UserspaceRebootWatchdogThread() proces do monitorowania ponownego uruchomienia w tle.

  3. Wywoła działanie userspace-reboot-requested, które zresetuje wszystkie właściwości systemowe, które mogą mieć wpływ na ponowne uruchomienie w tle. Właściwości, których to dotyczy:

    • sys.usb.config
    • sys.usb.state
    • sys.boot_completed
    • dev.bootcomplete
    • sys.init.updatable_crashing
    • sys.init.updatable_crashing_process_name
    • apexd.status
    • sys.user.0.ce_available
    • sys.shutdown.requested
    • service.bootanim.exit

    Powyższe właściwości należy ponownie ustawić podczas sekwencji uruchamiania. W razie potrzeby możesz zresetować dodatkowe właściwości. Przykłady znajdziesz w działaniu on userspace-reboot-requested w rootdir/init.rc.

  4. Uruchomi funkcję DoUserspaceReboot, która wykona te działania:

    1. Wyśle sygnał SIGTERM do procesów uruchomionych po zamontowaniu partycji userdata i poczeka na ich zatrzymanie.
    2. Po upływie limitu czasu wyśle sygnał SIGKILL, aby zakończyć wszystkie działające procesy.
    3. Wywoła polecenie /system/bin/vdc volume reset.
    4. Odmontuje urządzenie zRAM.
    5. Odmontuje aktywne pakiety APEX.
    6. Przełączy się z powrotem do przestrzeni nazw montowania bootstrap.
    7. Wywoła userspace-reboot-resume działanie.

Jeśli przed ponownym uruchomieniem w tle zażądano utworzenia punktu kontrolnego systemu plików, partycja userdata zostanie ponownie zamontowana w trybie punktu kontrolnego podczas działania userspace-reboot-fs-remount (szczegóły znajdziesz w następnej sekcji). Ponowne uruchomienie w tle jest uznawane za zakończone, gdy sys.boot_completed property zostanie ustawione na 1. Po zakończeniu ponownego uruchomienia w tle wyświetlacz pozostaje wyłączony i wymaga wyraźnej interakcji użytkownika, aby się wybudzić.

Punkty kontrolne systemu plików

Jeśli przed ponownym uruchomieniem w tle zażądano utworzenia punktu kontrolnego systemu plików, partycja userdata zostanie ponownie zamontowana w trybie punktu kontrolnego podczas ponownego uruchomienia w tle. Logika ponownego montowania jest zaimplementowana w funkcji fs_mgr_remount_userdata_into_checkpointing i różni się w zależności od metody tworzenia punktów kontrolnych. Gdy partycja userdata obsługuje:

  • punkty kontrolne na poziomie systemu plików (np. f2fs), partycja userdata jest ponownie montowana z opcją checkpoint=disable.

  • punkty kontrolne na poziomie bloków (np. ext4), partycja /data jest odmontowywana, a wszystkie nadrzędne urządzenia mapowania urządzeń, na których była zamontowana, są niszczone. Następnie partycja userdata jest montowana przy użyciu tej samej ścieżki kodu, która jest używana podczas normalnego uruchamiania z punktu kontrolnego.

Jeśli do zarządzania kluczami zaszyfrowanymi za pomocą danych uwierzytelniających (CE) i kluczami zaszyfrowanymi za pomocą urządzenia (DE) używany jest pęk kluczy na poziomie systemu plików, klucze są tracone po odmontowaniu partycji userdata. Aby umożliwić przywrócenie klucza, podczas instalowania klucza w pęku kluczy systemu plików usługa vold instaluje też ten sam klucz typu fscrypt-provisioning w pęku kluczy na poziomie sesji. Gdy wywoływana jest funkcja init_user0, usługa vold ponownie instaluje klucze w pęku kluczy systemu plików.

Powrót do ponownego uruchomienia

Aby ponowne uruchomienie w tle nie spowodowało, że urządzenie będzie bezużyteczne, Android 11 zawiera powrót do ponownego uruchomienia, który jest wywoływany, gdy zostanie spełniony jeden z tych warunków:

  • Urządzenie nie może rozpocząć ponownego uruchomienia w tle (czyli sys.init.userspace_reboot.in_progress=1) w określonym limicie czasu.
  • Proces nie może się zatrzymać w określonym limicie czasu.
  • Operacja /system/bin/vdc volume reset nie powiodła się.
  • Odmontowanie urządzenia zRAM nie powiodło się.
  • Aktywny pakiet APEX został nieprawidłowo odmontowany.
  • Próba ponownego zamontowania partycji userdata w trybie punktu kontrolnego nie powiodła się.
  • Urządzenie nie może się prawidłowo uruchomić (czyli sys.boot_completed=1) w określonym limicie czasu.

Konfiguracja na urządzenie

Niektóre aspekty ponownego uruchomienia w tle można dostosować, zmieniając wartości tych właściwości:

  • init.userspace_reboot.is_supported określa, kiedy urządzenie może wykonać ponowne uruchomienie w tle. Jeśli wartość tej właściwości to false, 0 lub nie jest określona, próby ponownego uruchomienia są odrzucane.
  • init.userspace_reboot.sigkill.timeoutmillis określa limit czasu w milisekundach na zatrzymanie procesów, które otrzymały sygnał SIGKILL. Jeśli jeden z procesów nie zatrzyma się w określonym limicie czasu, zostanie wywołany powrót do ponownego uruchomienia.
  • init.userspace_reboot.sigterm.timeoutmillis określa limit czasu w milisekundach na zakończenie procesów, które otrzymały sygnał SIGTERM. Wszystkie procesy, które nie zakończyły się w określonym limicie czasu, otrzymają sygnał SIGKILL.
  • init.userspace_reboot.started.timeoutmillis określa limit czasu w milisekundach na rozpoczęcie ponownego uruchomienia w tle (czyli sys.init.userspace_reboot.in_progress=1). Jeśli urządzenie nie może rozpocząć ponownego uruchomienia w tle w określonym limicie czasu, zostanie wywołany powrót do ponownego uruchomienia.
  • init.userspace_reboot.userdata_remount.timeoutmillis określa limit czasu w milisekundach na odmontowanie partycji userdata. Jeśli urządzenie nie może odmontować partycji userdata w określonym limicie czasu, zostanie wywołany powrót do ponownego uruchomienia.
  • init.userspace_reboot.watchdog.timeoutmillis określa limit czasu na prawidłowe uruchomienie urządzenia (czyli sys.boot_completed=1). Jeśli urządzenie nie może się uruchomić w określonym limicie czasu, zostanie wywołany powrót do ponownego uruchomienia.

Dostosowywanie animacji podczas ponownego uruchomienia w tle

Implementacja referencyjna ponownego uruchomienia w tle umożliwia dostosowanie animacji wyświetlanej podczas ponownego uruchomienia w tle.

Po zakończeniu działania userspace-reboot-fs-remount usługa init uruchamia usługę bootanim. Ta usługa szuka w podanej kolejności tych plików animacji i odtwarza pierwszy znaleziony:

  • /product/media/userspace-reboot.zip
  • /oem/media/userspace-reboot.zip
  • /system/media/userspace-reboot.zip

Jeśli nie określono plików animacji specyficznych dla ponownego uruchomienia w tle, usługa bootanim wyświetla domyślną animację android.

Testowanie

Android 11 zawiera implementację referencyjną ponownego uruchomienia w tle. Ponadto możesz sprawdzić ponowne uruchomienie w tle za pomocą testów CTS w UserspaceRebootHostTest.