軟體重新啟動 (<= 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 測試,驗證軟重新啟動。