RFC-0008:移除 zx_clock_get 和 zx_clock_adjust

RFC-0008:移除 zx_clock_get 和 zx_clock_adjust
狀態已接受
區域
  • Kernel
說明

定義淘汰並移除 zx_clock_get 和 zx_clock_adjust 系統呼叫的計畫。

問題
Gerrit 變更
作者
審查人員
提交日期 (年-月-日)2020-10-12
審查日期 (年-月-日)2020-10-29

摘要

我們建議採取五個步驟,逐步淘汰 zx_clock_getzx_clock_adjust 系統呼叫,將剩餘使用者遷移至 2019 年推出的替代系統呼叫,最後移除原始系統呼叫。

提振精神

Fuchsia 目前包含兩組獨立的系統呼叫,可與時間互動:

  1. 原始設計使用 zx_clock_get 讀取核心維護的單調、UTC 和執行緒時鐘,並使用 zx_clock_adjust 寫入 UTC 時鐘。這個設計無法提供任何時脈擺動方式、在不同產品上定義額外時脈,或傳達時脈狀態。
  2. 2019 年新增了 zx_clock_createzx_clock_readzx_clock_updatezx_clock_get_details 系統呼叫,可對時鐘物件執行豐富的管理作業,讓使用者空間定義及維護任意數量的時鐘。zx_clock_get_monotonic 也已新增,可讀取核心的單調時鐘。

Fuchsia 目前定義了兩種不同的世界標準時間時鐘:可使用 zx_clock_get 讀取的 Kernel 世界標準時間時鐘,以及可使用 zx_clock_read 讀取的 Userspace 世界標準時間時鐘。時間同步系統會嘗試讓這些時鐘保持一致,但由於功能不同,因此難免會出現差異。

這項提案定義了原始時間系統呼叫的淘汰計畫,完成 2019 年開始的遷移作業,當時設計的替代系統呼叫已新增。移除這些系統呼叫可解決持續 (且不斷增加) 的作業和認知成本,因為維護兩種半相容的時間管理方式需要這些成本。

實作

zx_clock_getzx_clock_adjust 各自接受 clock_id 引數,用來指定應使用三種可能時間軸中的哪一個。建議您分別考量這三個時間軸的遷移作業:

  • ZX_CLOCK_MONOTONIC - 對 zx_clock_get(ZX_CLOCK_MONOTONIC) 的呼叫可以直接替換為對 zx_clock_get_monotonic 的呼叫。這個替代系統呼叫較容易使用,且通常效能較佳。
  • ZX_CLOCK_THREAD - 對 zx_clock_get(ZX_CLOCK_THREAD) 的呼叫可能會使用主題 ZX_INFO_THREAD_STATS,改為對 zx_object_get_info 的呼叫。這項替代方案更具彈性,且更符合執行緒執行時間 (做為執行緒屬性)。
  • ZX_CLOCK_UTC - 在 2019 年的時間系統呼叫中,UTC 是由 Fuchsia 平台在使用者空間中管理,而非直接由核心管理。大多數語言執行階段都已修改為讀取使用者空間的 UTC 時鐘,因此在大多數情況下,對 zx_clock_get(ZX_CLOCK_UTC) 的呼叫應由語言執行階段中的標準 UTC 呼叫取代。如有必要,可以使用 zx_utc_reference_get 函式取得唯讀時鐘控制代碼,並傳遞至 zx_clock_read。對 zx_clock_adjust(ZX_CLOCK_UTC) 的呼叫可能會由對 zx_clock_update 的呼叫取代,後者使用從 fuchsia.time.Maintenance 取得的讀取/寫入時鐘控制代碼。

我們建議採取以下五個步驟,移除 zx_clock_getzx_clock_adjust

  1. 更新說明文件,將系統呼叫標示為已淘汰
  2. 將所有已知使用者遷移至替代系統呼叫
  3. 停止維護核心 UTC 時鐘,並移除 zx_clock_adjust
  4. 從 SDK 移除 zx_clock_get 宣告
  5. 從 Zircon 移除「zx_clock_get」實作項目

步驟 1 - 更新說明文件,將系統呼叫標示為已淘汰

這個步驟已完成。zx_clock_getzx_clock_adjust 呼叫已明確標示為已淘汰,且說明文件包含我們建議的替代解決方案。

步驟 2 - 將所有已知使用者遷移至替代系統呼叫

這項步驟正在進行中。fxr/433865 最近將標準語言執行階段世界標準時間函式移至使用者空間世界標準時間時鐘。這項做法已移除大部分的 zx_clock_get 用法,但不同存放區中各種不同的呼叫網站仍有長尾效應。

我們將使用程式碼搜尋,找出 Global Integration 中主幹和花瓣的呼叫和 syscalls_zx_clock_get_type_* kcounter,以追蹤進度,並用完剩餘用量。由於可用資源有限,且將上游變更推送至下游存放區通常需要數週或數月,因此這項程序會很漫長。

如果語言執行階段提供 zx_clock_getzx_clock_adjust 的包裝函式 (例如 Rust 中的 fuchsia_zircon::Time::get 函式),我們會在沒有任何用戶端使用包裝函式時移除。

步驟 3 - 停止維護核心 UTC 時鐘,並移除 zx_clock_adjust

如要在 ZX_CLOCK_UTC 中維持準確時間,需要從駕駛人和多個測試元件呼叫 zx_clock_getzx_clock_adjust。步驟 4 完成後,這些呼叫將無法再進行,因此我們不再將核心 UTC 維護作業視為獨立步驟。

在步驟 3 中,我們會移除 ZX_CLOCK_UTC 同步處理,導致嘗試讀取 ZX_CLOCK_UTC 的任何用戶端發生當機,並完全移除 zx_clock_adjust 系統呼叫 (這個系統呼叫僅用於設定 UTC,且只有少數具備權限的用戶端會叫用)。

完成步驟 2 後,我們應該已相當有把握,Global Integration 中沒有任何使用 UTC 的元件,但如果讀取嘗試導致用戶端當機,我們就能快速偵測到任何遺漏項目。

具體來說,我們會:

  1. 移除所有驗證 ZX_CLOCK_UTC 的測試。
  2. 修改 zx_clock_get(ZX_CLOCK_UTC),將來電者標示為政策違規者。
  3. 從即時時鐘驅動程式中移除對 zx_clock_adjust 的呼叫 (並完全移除備援 RTC 驅動程式庫,因為這是其唯一用途)
  4. 完全移除 zx_clock_adjust

步驟 4 - 從 SDK 移除 zx_clock_get 宣告

完成步驟 3 後,我們可能已成功移除標頭中的所有 zx_clock_get 呼叫,但仍需支援依附於 zx_clock_get 的舊版預先建構二進位檔。在這種情況下,我們會移除 SDK 中的 zx_clock_get 宣告,但不會移除 zircon 實作項目。在這個階段,任何嘗試使用 zx_clock_get 編譯程式碼的行為都會導致編譯失敗。

如果沒有任何預先建構的二進位檔依附於 zx_clock_get,我們會直接進行步驟 5。

步驟 5 - 從 Zircon 移除 zx_clock_get 實作項目

一旦沒有預先建構的二進位檔依附於 zx_clock_get (取決於符號匯入),我們就會完全移除 zx_clock_get 和相關文件。

效能

這項提案將鼓勵更廣泛地使用效率更高的 zx_clock_get_monotonic 系統呼叫,並簡化 RTC 驅動程式的操作,因此整體系統效能只會略微提升。

安全性考量

這項提案不會影響管理單調或執行緒時間的安全性。

在其他作業系統中,UTC 管理安全漏洞遭到利用,以執行各種回溯攻擊。這項提案提供更精細的存取權控管機制,可提升 UTC 時間管理作業的安全性。

使用 zx_clock_adjust 系統呼叫時,需要根資源才能變更 UTC 時間。也就是說,需要調整時間的元件也會獲得強大的無關功能,且任何具有根資源的元件都有權修改 UTC,無論是否需要這項權力。

這項提案實施後,您只能透過 fuchsia.utc.Maintenance 分發的讀取/寫入時鐘控制代碼修改 UTC。這個通訊協定會明確地只傳送給需要的元件,且這些元件不會因此獲得額外功能。

隱私權注意事項

這項提案不會影響實作時的隱私權。

這項提案可望在日後移除 UTC 時間做為環境授權 (程序可啟動,不必使用使用者空間 UTC 時鐘控制代碼,且不再能存取核心 UTC 時鐘)。這項技術可能可用於提升特定類型資料處理作業的隱私權。

測試

目前,單元、整合和端對端測試涵蓋了每個時間管理系統呼叫,以及依附於這些呼叫的時間同步基礎架構。移除這兩個系統呼叫和第二個 UTC 時鐘後,這些測試會稍微簡化。

說明文件

如要瞭解說明文件更新內容,請參閱上方的實作部分。

缺點、替代方案和未知事項

這項提案的成本不高,我們預估元件平台和核心團隊的 2 到 3 位工程師,在 1 到 3 季內每週只需投入幾小時。

替代方案主要是不清理或減少清理這項技術債;舉例來說,可以停止維護核心 UTC 時鐘,但不移除相關的系統呼叫。這些替代方案短期內可降低成本,但長期來看會大幅增加成本。

既有技術和參考資料

kernel_objects/clock 清楚說明瞭使用者空間時鐘的運作方式,建議您閱讀。