無線更新 (OTA) 是一種作業系統更新機制 紫紅色。本文件將詳細說明 OTA 更新機制在 Fuchsia 上的運作方式。
更新程序分為以下幾個階段:
正在檢查更新
作業系統更新程序的兩個進入點是 omaha-client
和 system-update-checker
元件
omaha-client
和 system-update-checker
都放送相同廣告
來確認是否有作業系統更新,並開始更新。
一般來說,產品應使用 omaha-client
才能
並使用 Omaha 來判斷更新的可用性。產品應使用
如果不想使用 Omaha,請system-update-checker
直接從套件存放區檢查更新。
在任何指定的 Fuchsia 系統上,只能執行下列其中一項元件:
更新 omaha-client 檢查流程
在啟動程序中,omaha-client
會啟動並開始定期更新
檢查。進行這些檢查時,omaha-client
會輪詢 Omaha 伺服器進行檢查
更新。
使用 Omaha 的好處如下:
- 可在多個階段中分批推出系統更新 Fuchsia 裝置。舉例來說,您可以設定為 裝置機群都會更新換言之,這類裝置中只有 10%。 會在輪詢 Omaha 時看到可用的更新。 剩餘的 90% 裝置都沒有可用的更新。
- 這種方式有多種更新管道。舉例來說,測試裝置 並取得最新版本 (可能不穩定) 軟體這可讓正式版裝置從正式版中取得更新 並取得最穩定的軟體頻道資訊可以 視需要一併提供產品和版本給 Omaha。
圖 1. 簡化版更新檢查程序,使用 omaha-client
。另有
用於限制「omaha-client
」可否檢查更新或套用更新的政策。
omaha-client
從 Omaha 伺服器取得更新套件網址後,omaha-client
會指示 system-updater
開始更新。
使用 system-update-checker 更新檢查
非使用 omaha-client
的裝置會採用 system-update-checker
。視情況而定
的設定方式,system-update-checker
會定期輪詢
更新套件如果沒有 auto_update
,這些檢查會預設為停用
。
如要檢查是否有可用的更新,system-update-checker
會檢查
下列情況:
- 目前執行中系統映像檔 (位於
/pkgfs/system/meta
) 的雜湊與 更新套件中系統映像檔的雜湊值 (位於packages.json
中)? - 如果系統映像檔並非不同,表示系統目前執行的 vbmeta 不同 是否與更新套件的 vbmeta 不同?
- 如果沒有 vbmeta,表示目前在系統上執行的 ZBI 和 ZBI 不同 更新套件?
如果上述任一答案皆為「是」,則 system-update-checker
知道
update 套件已變更。System-update-checker 偵測到更新後
套件已變更,system-update-checker
會觸發 system-updater
使用預設更新套件 (fuchsia-pkg://fuchsia.com/update) 來開始更新。
圖 2. 使用 system-update-checker
的簡化版更新檢查程序。
如果不需要更新,更新檢查工具會儲存上次已知的 並更新在伺服器上看到的套件後續檢查更新時 系統會根據上次檢查的更新套件,檢查擷取的更新套件 伺服器上已知的雜湊值如果最新更新套件的雜湊值 更新檢查工具會比對 vbmeta 和 更新中相關映像檔的 ZBI 套件。如果 vbmeta 或 ZBI 在 並安裝更新套件後,檢查工具就會開始系統更新。
監控
如果客戶想監控更新進度和狀態,可以
fuchsia.update.AttemptsMonitor
通訊協定和用戶端
fuchsia.update.Manager
FIDL 的 MonitorAllUpdateChecks()
方法
因此效能相當卓越fuchsia.update.AttemptsMonitor
執行個體只會接收
訊息。這個
不會觸發新的更新
fuchsia.update.AttemptsMonitor
執行個體會收到 OnStart
訊息
來包含伺服器端的 fuchsia.update.Monitor
通訊協定。這樣一來,
用戶端接收及處理 OnState
訊息,告知更新狀態變更。
另一種做法是實作 fuchsia.update.Monitor
並提供用戶端
變更為 fuchsia.update.Manager
通訊協定的 CheckNow()
方法。這將
開始檢查更新。它只會監控
並在更新完成後關閉控點。
暫存更新
無論更新是否由 omaha-client
、system-update-checker
觸發,
或甚至強制更新檢查時,必須將更新寫入磁碟。
更新程序分為下列步驟:
圖 3. 裝置目前正在執行假設的 OS 版本 1 (位於插槽 A),並且開始執行 更新至假設 OS 第 2 版 (至插槽 B)。警告:這可能與磁碟不同 各行各業
擷取更新套件
system-updater
會使用
提供的更新套件網址。接著,動態索引會更新為
參照新的更新套件更新套件範例如下所示:
/board
/epoch.json
/firmware
/fuchsia.vbmeta
/packages.json
/recovery.vbmeta
/version
/zbi.signed
/zedboot.signed
/meta/contents
/meta/package
如果因空間不足而擷取失敗,system-updater
會觸發垃圾
「集合」來刪除未在靜態或動態索引中參照的所有 BLOB,或是
保留套件組合垃圾收集後,system-updater
會重試擷取。如果
重試失敗,system-updater
會替換
僅含有其嘗試擷取的更新套件 (如果更新套件網址) 設定的套件
包含雜湊,否則系統會清除
保留套件集),然後再次觸發垃圾收集作業,並重試更新套件
擷取。
圖 4. system-updater
會指示 pkg-resolver
解析版本 2
update 套件。我們假設 system-updater
無法擷取更新套件,原因如下:
空間不足,觸發垃圾收集以收回運算單元 B 參照的第 0 版 blob。
然後重試以成功擷取第 2 版的更新套件。
如有需要,更新套件可能包含 update-mode
檔案。這個檔案
判斷系統更新是發生在一般復原還是 ForceRecovery 程序中
模式。如果找不到更新模式檔案,system-updater
會預設為一般模式
模式為 ForceRecovery 時,system-updater
會將映像檔寫入復原。
將運算單元 A 和 B 標示為無法啟動,然後啟動復原作業。如需更多資訊
請參閱 ForceRecovery 的實作。
確認董事會相符
目前執行系統中的 Jamboard 檔案位於 /config/build-info/board
。
system-updater
會驗證系統上的主面板檔案是否與面板相符
該檔案位於更新套件中
圖 5:system-updater
會驗證更新套件中的 Jamboard 與主機板相符
版位 A。
確認是否支援 Epoch
update 套件含有 Epoch 檔案 (epoch.json
)。如果更新週期
套件 (目標週期) 小於 system-updater
的週期
(來源週期),OTA 會失敗。如需其他相關資訊
請參閱 RFC-0071。
圖 6. system-updater
會驗證下列執行個體是否支援更新套件中的 Epoch:
並與目前 OS 的週期進行比較
取代保留的套件組合
以目前更新套件替換保留的套件設定 以及之後在 OTA 程序中擷取的所有套件。
保留的套件集是一組受到垃圾收集 (
靜態和動態索引中的套件)。可用來防止垃圾流量
收集不會刪除目前更新程序所需的 BLOB。舉個例子,假設
擷取更新作業所需的部分套件,隨後因不相關原因而重新啟動。時間
裝置會再次啟動 OTA,重新啟動前仍需要擷取到的套件,
套件不受動態索引保護 (就像已保留的套件集一樣)
時)。將這些套件新增至保留的套件組合後,system-updater
就可以
觸發垃圾收集 (例如移除舊版系統版本所使用的 blob) 而不復原
過去的工作
觸發垃圾收集作業
已觸發垃圾收集,刪除了舊系統獨有的所有 BLOB。 這個步驟可以釋出額外空間,供任何新的套裝方案使用。
圖 7. system-updater
會指示 pkg-cache
垃圾收集專屬 BLOB ,
以及舊系統在這個範例中,這代表 pkg-cache
只會剔除 BLOB 參照的 BLOB
第 1 版更新套件
擷取其餘套件
system-updater 會剖析更新套件中的 packages.json
檔案。
packages.json
如下所示:
{
"version": “1”,
"content": [
"fuchsia-pkg://fuchsia.com/sshd-host/0?hash=123..abc",
"fuchsia-pkg://fuchsia.com/system-image/0?hash=456..def"
...
]
}
system-updater
會指示 pkg-resolver
解析所有套件網址。解決方式
套件管理系統只會擷取更新所需的 BLOB,即
也就是尚未出現的 BLOB。套件管理系統會擷取整個 BLOB
而不是目前系統上任何元件的差異
擷取完所有套件後,會觸發 BlobFS 同步處理作業來清除 從 BLOB 轉換為永久儲存空間。此程序可確保所有必要的 BLOB ,更新就在 BlobFS。
圖 8. system-updater
會指示 pkg-Resolver 解析版本 2
packages.json
中參照的套件。
寫入圖片即可封鎖裝置
system-updater
決定要將哪些圖片寫入區塊
裝置。映像檔、資產和韌體有兩種。
接著,system-updater
會指示分區映像檔安裝工具編寫系統啟動載入程式,並
韌體。這些圖片的最終位置不會因
裝置支援
ABR
,直接在 Google Cloud 控制台實際操作。為了避免閃光燈
只有在映像檔不同於
封鎖裝置上現有的映像檔。
接著,system-updater
會指示分區映像檔安裝工具編寫 Fuchsia ZBI 及其其
vbmeta。這些圖片的最終位置取決於裝置是否
支持
ABR
,直接在 Google Cloud 控制台實際操作。如果裝置支援
ABR
,分區映像檔安裝工具寫出 Fuchsia ZBI,
將 vbmeta 與目前未啟動的插槽 (替代運算單元) 相同。
否則,分區映像檔安裝工具會將資料寫入 A 和 B 分區 (假設為 B
分區已存在)。
最後,system-updater
會指示分區映像檔安裝工具寫入復原作業
ZBI 及其 vbmeta。如同系統啟動載入程式和韌體,
位置不會取決於裝置是否支援
ABR
,直接在 Google Cloud 控制台實際操作。
圖 9. system-updater
會透過分區映像檔安裝工具將第 2 版映像檔寫入插槽 B。
將替代分區設為有效
如果裝置支援 ABR,system-updater
會使用分區映像檔安裝工具設定
同時啟用替代分區功能如此一來,裝置就會開機
都會在下次啟動
參照運算單元狀態的方法有很多種。例如,內部
分區映像檔安裝工具使用 Successful
,FIDL 服務會使用 Healthy
,而其他
案例可以使用主動、閒置、可開機、無法啟動、目前、替代等...
重要的中繼資料是為每個核心儲存的 3 項資訊 。這項資訊有助於判斷每個核心運算單元的狀態。適用對象 例如,在版位 B 標示為有效前,中繼資料可能如下所示:
中繼資料 | 插槽 A | 插槽 B |
---|---|---|
優先順序 | 15 | 0 |
剩餘行程數 | 0 | 0 |
健康* | 1 | 0 |
將版位 B 標示為有效後,中繼資料看起來會像這樣:
中繼資料 | 插槽 A | 插槽 B |
---|---|---|
優先順序 | 14 | 15** |
剩餘行程數 | 0 | 7** |
健康料理 | 1 | 0 |
如果裝置不支援 ABR,由於沒有替代分區,因此系統會略過這項檢查。 如果有一項更新,系統會寫入一個使用中的分區。
圖 10. system-updater
會將插槽 B 設為使用中,以便裝置啟動到插槽 B
下次啟動時
這個功能會相當實用
重新啟動
視更新設定而定,裝置不一定會重新啟動。裝置之後 裝置就會開機,並移至新的插槽。
圖 11. 裝置會重新啟動進入插槽 B,並開始執行版本 2。
驗證更新
驗證更新後,系統會提交更新。
系統會按照以下方式驗證更新:
正在重新啟動,以進入更新版本
下次啟動時,系統啟動載入程式需要決定要開機的運算單元。 在此範例中,系統啟動載入程式決定啟動位置 B, 版位 B 的優先順序較高,剩餘嘗試次數超過 0 次 (請參閱 將替代分區設為有效)。接著, 系統啟動載入程式會驗證 B 的 ZBI 與 B 的 vbmeta 相符,最後啟動 插槽 B。
早期啟動後,fshost
會使用新的系統映像檔套件啟動 pkgfs
。
這是 packages.json
中參照的系統映像檔套件
同時執行更新作業system-image 套件含有 static_packages
檔案
裡面會列出新系統的基本套件。例如:
pkg-resolver/0 = new-version-hash-pkg-resolver
foo/0 = new-version-hash-foo
bar/0 = new-version-hash-bar
...
// Note the system-image package is not referenced in static_packages
// because it's impossible for it to refer to its own hash.
pkgfs
接著,將這些套件載入為基本套件。套件會顯示在
/pkgfs/{packages, versions}
,表示已安裝套件
已啟用或已啟動然後啟動 pkg-resolver
、pkg-cache
。
netstack
等...
提交更新
system-update-committer
元件會執行多項檢查,確認
已成功更新例如,它會指示 BlobF
讀取 1 MiB 的資料。如果系統在啟動時已承諾執行,這些檢查就會
略過。如果檢查失敗,並且視系統的設定方式而定,
system-update-committer
可能會觸發重新啟動作業。
更新驗證完畢後,目前的分區 (版位 B) 會標示為
Healthy
。請參考
將替代分區設為有效 (啟動)
中繼資料現在看起來可能像這樣:
中繼資料 | 插槽 A | 插槽 B |
---|---|---|
優先順序 | 14 | 15 |
剩餘行程數 | 7 | 0 |
健康料理 | 0 | 1 |
接著,替代分區 (運算單元 A) 會標示為無法啟動。現在, 開機中繼資料可能如下所示:
中繼資料 | 插槽 A | 插槽 B |
---|---|---|
優先順序 | 0 | 15 |
剩餘行程數 | 0 | 0 |
健康料理 | 0 | 1 |
之後,系統會將更新視為已確認。因此:
- 系統一律會啟動至插槽 B,直到下一次系統更新為止。
- 系統將啟動到插槽 A,直到下一次系統更新 覆寫運算單元 A。
- 運算單元 A 參照的 BLOB 現在可以進行垃圾收集作業。
- 現已允許後續的系統更新。更新檢查工具之後 如果發現新的更新,整個更新程序就會重新啟動。