軟重啟 (適用於 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. 切換回 bootstrap 掛載命名空間。
    7. 觸發 userspace-reboot-resume 動作。

如果在軟重啟之前要求檔案系統檢查點,userdata 會在 userspace-reboot-fs-remount 動作期間重新掛載至檢查點模式 (詳情請參閱下節)。在 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 測試驗證軟重啟。