軟重啟 (適用於 AOSP 14 以下版本)

Android 11 支援軟重新啟動,也就是在使用者空間中執行程序重新啟動,以便套用需要重新啟動的更新 (例如 APEX 套件更新)。目前軟重新啟動僅限於 userdata 掛接後啟動的程序。

要求軟重新啟動的方式如下:

  • PowerManager 起,撥打 PowerManager.reboot(PowerManager.REBOOT_USERSPACE)

  • 透過殼層使用 adb shell svc power reboot userspaceadb reboot userspace

軟重新啟動後,憑證加密儲存空間仍會保持解鎖狀態。

如果裝置支援軟重新啟動,則 PowerManager.isRebootingUserspace() API 方法會傳回 true,且系統屬性 init.userspace_reboot.is_supported 的值等於 1

如果裝置不支援軟重新啟動,對 PowerManager.reboot(PowerManager.REBOOT_USERSPACE)adb reboot userspaceadb shell svc power reboot userspace 的呼叫就會失敗。

軟性重新啟動執行作業

要求軟重新啟動 (透過 PowerManager 或從殼層) 後,init 會執行下列步驟:

  1. 接收 sys.powerctl=reboot,userspace

  2. 分叉獨立的 UserspaceRebootWatchdogThread() 程序,監控軟重新啟動。

  3. 觸發 userspace-reboot-requested 動作,重設所有可能影響軟重啟的系統屬性。受影響的房源:

    • 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

    啟動順序期間應再次設定上述屬性。如有需要,可以重設其他屬性。如需範例,請參閱 rootdir/init.rc 中的 on userspace-reboot-requested 動作。

  4. 執行 DoUserspaceReboot 函式,該函式會執行下列動作:

    1. SIGTERM 傳送至 userdata 掛接後啟動的程序,並等待這些程序停止。
    2. 達到逾時時間後,傳送 SIGKILL 終止所有執行中的程序。
    3. 通話 /system/bin/vdc volume reset
    4. 卸載 zRAM 後端裝置。
    5. 卸載使用中的 APEX 套件。
    6. 切換回啟動掛接命名空間。
    7. 觸發 userspace-reboot-resume 動作。

如果軟重新啟動前要求了檔案系統檢查點,則在 userspace-reboot-fs-remount 動作期間,userdata 會重新掛接到檢查點模式 (詳情請參閱下一節)。將 sys.boot_completed property 設為 1 後,系統會視為軟重新啟動。軟重啟結束後,螢幕會保持關閉狀態,必須由使用者明確互動才能喚醒。

檔案系統檢查點

如果在軟重新啟動前要求檔案系統檢查點,則 userdata 會在軟重新啟動期間以檢查點模式重新掛接。重新掛接邏輯是在 fs_mgr_remount_userdata_into_checkpointing 函式中實作,且因檢查點方法而異。具體來說,當 userdata支援:

  • 檔案系統層級檢查點 (例如 f2fs),userdata 會以 checkpoint=disable 選項重新掛接。

  • 區塊層級檢查點 (例如 ext4),然後 /data 會卸載,且其所掛載的所有父項裝置對應程式裝置都會遭到毀損。接著,userdata 會使用與一般檢查點開機相同的程式碼路徑掛接。

如果使用檔案系統層級的鑰匙圈管理憑證加密 (CE) 和裝置加密 (DE) 金鑰,則在卸載 userdata 後,金鑰會遺失。如要允許金鑰還原,將金鑰安裝至檔案系統金鑰環時,vold也會將相同類型的金鑰 fscrypt-provisioning 安裝至工作階段層級金鑰環。呼叫 init_user0 時,vold 會在檔案系統金鑰環中重新安裝金鑰。

改用強制重新啟動

為確保軟重新啟動不會導致裝置無法使用,Android 11 包含硬重新啟動的備援機制,會在符合下列任一條件時觸發:

  • 裝置在指定逾時時間內無法啟動軟重新啟動 (即 sys.init.userspace_reboot.in_progress=1)。
  • 程序未在指定逾時時間內停止。
  • /system/bin/vdc volume reset 作業失敗。
  • 無法卸載 zRAM 裝置。
  • 作用中的 APEX 套件卸載不正確。
  • 嘗試以檢查點模式重新掛接 userdata 時失敗。
  • 裝置在指定逾時時間內無法順利啟動 (即 sys.boot_completed=1)。

依裝置設定

您可以變更下列屬性的值,調整部分軟重新啟動功能:

  • init.userspace_reboot.is_supported 可控管裝置執行軟重新啟動的時機。如果這個屬性的值為 false0 或未指定,系統會拒絕重新啟動要求。
  • init.userspace_reboot.sigkill.timeoutmillis 會控制收到 SIGKILL 訊號停止的程序逾時時間 (以毫秒為單位)。如果其中一個程序在指定逾時時間內無法停止,就會觸發強制重新啟動。
  • init.userspace_reboot.sigterm.timeoutmillis 可控制程序在收到 SIGTERM 終止訊號後,以毫秒為單位的逾時時間。在指定逾時時間內無法終止的所有程序,都會收到 SIGKILL 信號。
  • init.userspace_reboot.started.timeoutmillis 會控制啟動背景模式重啟的逾時時間 (以毫秒為單位),也就是 sys.init.userspace_reboot.in_progress=1。如果裝置未在指定逾時時間內啟動背景模式重啟,系統會觸發強制重新啟動。
  • init.userspace_reboot.userdata_remount.timeoutmillis 會控制卸載 userdata 的逾時時間 (以毫秒為單位)。如果裝置在指定逾時時間內無法解除掛接 userdata,系統會觸發強制重新啟動。
  • init.userspace_reboot.watchdog.timeoutmillis 可控制裝置成功啟動 (即 sys.boot_completed=1) 的逾時時間。如果裝置在指定逾時時間內無法啟動,系統會觸發強制重新啟動。

自訂軟重啟期間的動畫

柔性重新啟動的參考實作包括自訂柔性重新啟動期間顯示動畫的功能。

userspace-reboot-fs-remount 動作結束時,init 會啟動 bootanim 服務。這項服務會依下列順序尋找動畫檔案,並播放找到的第一個檔案:

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

如未指定任何軟重新啟動專屬動畫檔案,bootanim 會顯示預設的 android 動畫。

測試

Android 11 包含軟重新啟動的參考實作項目。此外,您也可以使用 UserspaceRebootHostTest 中的 CTS 測試驗證軟體重新啟動。