Ripartenze morbide

Android 11 supporta i riavvii graduali, ovvero i riavvii di runtime dei processi nello spazio utente utilizzati per applicare gli aggiornamenti che richiedono un riavvio (ad esempio, aggiornamenti ai pacchetti APEX). Attualmente, il riavvio graduale è limitato ai processi avviati dopo il montaggio userdata .

Un riavvio graduale viene richiesto nei seguenti modi:

  • Da PowerManager , chiamando PowerManager.reboot(PowerManager.REBOOT_USERSPACE)

  • Dalla shell, utilizzando adb shell svc power reboot userspace o adb reboot userspace

Dopo un riavvio graduale, l'archivio crittografato delle credenziali rimane sbloccato.

Se un dispositivo supporta i riavvii graduali, il metodo API PowerManager.isRebootingUserspace() restituisce true e il valore della proprietà di sistema init.userspace_reboot.is_supported è uguale a 1 .

Se il dispositivo non supporta i riavvii graduali, le chiamate a PowerManager.reboot(PowerManager.REBOOT_USERSPACE) , adb reboot userspace e adb shell svc power reboot userspace falliscono.

Esecuzione del riavvio graduale

Dopo che è stato richiesto un riavvio graduale (tramite PowerManager o da una shell), init esegue i seguenti passaggi:

  1. Riceve sys.powerctl=reboot,userspace .

  2. Effettua il fork di un processo UserspaceRebootWatchdogThread() separato per monitorare il riavvio graduale.

  3. Attiva un'azione userspace-reboot-requested , che reimposta tutte le proprietà del sistema che potrebbero influire sul riavvio graduale. Proprietà interessate:

    • 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

    Le proprietà di cui sopra dovrebbero essere impostate nuovamente durante la sequenza di avvio. Se necessario, puoi reimpostare proprietà aggiuntive. Per esempi, fare riferimento all'azione on userspace-reboot-requested in rootdir/init.rc .

  4. Esegue la funzione DoUserspaceReboot , che esegue le seguenti azioni:

    1. Invia SIGTERM ai processi avviati dopo che userdata è stato montato e attende che si interrompano.
    2. Una volta raggiunto il timeout, invia SIGKILL per terminare tutti i processi in esecuzione.
    3. Richiama /system/bin/vdc volume reset .
    4. Smonta il dispositivo di supporto zRAM.
    5. Smonta i pacchetti APEX attivi.
    6. Torna allo spazio dei nomi del montaggio bootstrap.
    7. Attiva l'azione userspace-reboot-resume .

Se il checkpoint del file system è stato richiesto prima del riavvio graduale, userdata vengono rimontati in modalità checkpoint durante l'azione userspace-reboot-fs-remount (vedere la sezione seguente per i dettagli). Viene preso in considerazione un riavvio graduale dopo che la sys.boot_completed property è impostata su 1 . Al termine del riavvio graduale, il display viene mantenuto spento ed è necessaria l'interazione esplicita dell'utente per riattivarlo.

Checkpoint del file system

Se è stato richiesto un checkpoint del file system prima del riavvio graduale, userdata vengono rimontati in modalità checkpoint durante il riavvio graduale. La logica di rimontaggio è implementata nella funzione fs_mgr_remount_userdata_into_checkpointing e differisce tra i metodi di checkpoint. Nello specifico, quando userdata supportano:

  • Checkpoint a livello di file system (ad esempio, f2fs ), userdata vengono rimontati con l'opzione checkpoint=disable .

  • Checkpoint a livello di blocco (ad esempio, ext4 ), quindi /data viene smontato e tutti i dispositivi di mappatura dei dispositivi principali su cui era montato vengono distrutti. Successivamente, userdata viene montato utilizzando lo stesso percorso del codice utilizzato nel normale avvio con checkpoint.

Se viene utilizzato un portachiavi a livello di file system per gestire le chiavi crittografate con credenziali (CE) e crittografate con dispositivo (DE), le chiavi verranno perse dopo lo smontaggio userdata . Per consentire il ripristino della chiave, quando si installa una chiave su un portachiavi del file system, vold installa anche la stessa chiave di tipo fscrypt-provisioning sul portachiavi a livello di sessione. Quando viene chiamato init_user0 , vold reinstalla le chiavi nel portachiavi del file system.

Fallback al riavvio forzato

Per garantire che un riavvio graduale non lasci un dispositivo in uno stato inutilizzabile, Android 11 include un fallback per il riavvio forzato che viene attivato quando viene soddisfatta una delle seguenti condizioni:

  • Un dispositivo non riesce ad avviare il riavvio graduale (ovvero sys.init.userspace_reboot.in_progress=1 ) entro un determinato timeout.
  • Un processo non si arresta entro un determinato timeout.
  • L'operazione /system/bin/vdc volume reset non riesce.
  • Lo smontaggio del dispositivo zRAM non riesce.
  • Un pacchetto APEX attivo viene smontato in modo errato.
  • Un tentativo di rimontare userdata in modalità checkpoint non riesce.
  • Un dispositivo non riesce ad avviarsi correttamente (ovvero, sys.boot_completed=1 ) entro un determinato timeout.

Configurazione per dispositivo

Alcuni aspetti del riavvio graduale possono essere ottimizzati modificando i valori delle seguenti proprietà:

  • init.userspace_reboot.is_supported controlla quando un dispositivo può eseguire un riavvio graduale. Se il valore di questa proprietà è false , 0 o non specificato, i tentativi di riavvio vengono rifiutati.
  • init.userspace_reboot.sigkill.timeoutmillis controlla il timeout in millisecondi per l'arresto dei processi che hanno ricevuto un segnale SIGKILL . Se uno dei processi non si arresta entro il timeout specificato, viene attivato un fallback al riavvio forzato.
  • init.userspace_reboot.sigterm.timeoutmillis controlla il timeout in millisecondi per la terminazione dei processi che hanno ricevuto un segnale SIGTERM . Tutti i processi che non sono riusciti a terminare entro il timeout specificato ricevono un segnale SIGKILL .
  • init.userspace_reboot.started.timeoutmillis controlla il timeout in millisecondi per l'avvio del riavvio graduale (ovvero, sys.init.userspace_reboot.in_progress=1 ). Se un dispositivo non riesce ad avviare il riavvio graduale entro il timeout specificato, viene attivato un fallback al riavvio forzato.
  • init.userspace_reboot.userdata_remount.timeoutmillis controlla il timeout in millisecondi per smontare userdata . Se un dispositivo non riesce a smontare userdata entro il timeout specificato, viene attivato un fallback al riavvio forzato.
  • init.userspace_reboot.watchdog.timeoutmillis controlla il timeout per l'avvio corretto di un dispositivo (ovvero, sys.boot_completed=1 ). Se un dispositivo non riesce ad avviarsi entro il timeout specificato, viene attivato un fallback al riavvio forzato.

Personalizza l'animazione durante il riavvio graduale

L'implementazione di riferimento di un riavvio graduale include la possibilità di personalizzare l'animazione mostrata durante il riavvio graduale.

Alla fine dell'azione userspace-reboot-fs-remount , init avvia il servizio bootanim . Questo servizio cerca l'esistenza dei seguenti file di animazione, nell'ordine elencato, e riproduce il primo che trova:

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

Se non vengono specificati file di animazione specifici per il riavvio graduale, bootanim mostra un'animazione android predefinita.

Test

Android 11 include un'implementazione di riferimento di un riavvio graduale. Inoltre, puoi verificare un riavvio graduale utilizzando i test CTS in UserspaceRebootHostTest .