元件組軟體

元件是 Fauchsia 中執行軟體的基本構成要素。每個元件都是可組合的沙箱模組,可透過功能與其他元件互動。這麼做可提高系統安全性,並在個別元件之間建立清楚的介面,以便更新或取代元件。

在 Fuchsia 中,所有東西都是元件 (幾乎)。回顧之前的 Zircon 討論內容,我們刻意在核心的表層顯示規模較小,且大多數的核心服務都會在使用者空間中實作。這表示在 Fuchsia 上執行的大部分軟體都是利用元件架構實作,包括:

  • 使用者端應用程式
  • 裝置驅動程式
  • 檔案系統
  • 媒體轉碼器
  • 網路堆疊

在核心之外,只有幾個不使用元件架構的低階例外狀況,例如系統啟動載入程式和 userboot 程序。

元件管理員

元件架構的核心是「元件管理員」。您必須負責協調所有元件執行個體的執行作業,為他們提供其功能,並中介元件之間的連線。

您可以明確 (例如透過網址) 啟動元件,或是透過特定能力的要求以隱含方式啟動元件。元件管理員會執行必要的解析度,以判斷是否要啟動新元件,或將要求轉送至現有執行個體。為了完成這個轉送,每個元件都必須宣告自身「提供給系統」的任何功能,以及系統「消耗」的任何功能。

元件管理員會剖析每個元件的「宣告」,以決定如何執行元件並提供必要功能。系統通常會透過元件套件中的元件資訊清單檔案,向系統宣告元件。

以下為元件資訊清單的簡易範例,該資訊清單會說明 ELF 執行檔,以及一些額外的指令引數:

program: {
    runner: "elf",
    binary: "bin/hello",
    args: [ "Hello", "World!" ],
},

請注意,執行階段宣告會指示元件管理員使用此元件需要 ELF 執行器這是能力的範例!

元件功能

元件可透過capabilities存取較大系統的各個部分。每個元件都可以宣告自身向其他元件 (或架構) 所提供運作所需的新功能。

如您所見,runner 是宣告元件使用的執行階段的能力範例。其他常見能力類型的範例包括存取檔案系統資源的 directory,以及用於與其他元件通訊的 protocol

開發人員會透過元件資訊清單,宣告元件所需的能力類型。以下是要求兩項功能的元件資訊清單範例:讀取 example-data 目錄,以及 fuchsia.example.Foo FIDL 通訊協定描述的服務。

use: [
    {
        directory: "example-data",
        rights: [ "r*" ],
        path: "/example/data",
    },
    {
        protocol: "fuchsia.example.Foo",
    },
]

元件管理員會使用能力宣告,為每個元件的命名空間填入必要的目錄控制代碼。在這個範例中,元件會在其命名空間中接收 /example/data/svc/fuchsia.example.Foo

元件整理

系統中的所有元件都會組成單一已啟用 Root 權限的元件執行個體樹狀結構。這個樹狀結構結構會管理元件行為的幾個重要層面。

說明元件執行個體的組織方式的樹狀圖。這些父項和子項關係管理元件行為的多個方面。

樹狀結構中的父項元件負責建立其他元件的例項做為其子項,並提供必要的功能。同時,子項元件也能向父項公開功能。您可以透過下列任一方式建立子項元件:

  • 靜態:父項會在自己的元件宣告中宣告子項的存在。
  • 動態:父項使用 fuchsia.component.Realm 通訊協定,在執行階段將子項新增至元件集合。

在樹狀結構中,任何父項元件及其所有子項都會形成一個稱為「領域」的群組。容器可讓父項控管傳入及傳出元件子樹狀結構的功能,進而建立能力界線。元件可決定是否要使用 expose 關鍵字,將功能匯出至其領域之外:

expose: [
    {
        protocol: "fuchsia.example.Foo",
        from: "self",
    },
],

向領域公開特定能力後,父項就能與同一個領域內的其他元件共用該功能。方法是使用 offer 關鍵字:

offer: [
    {
        protocol: "fuchsia.example.Foo",
        from: "self",
    },
],

這就是「功能轉送」。元件管理服務只能解析在同一領域內「公開」和「提供」的功能。

這張圖表顯示元件如何透過「能力轉送」來共用功能,並說明如何在特定領域內提供資源。

運動:元件

在本練習中,您將探索元件執行個體樹狀結構,並深入瞭解如何使用某些核心系統元件執行能力轉送。

啟動模擬器

如果您尚未有一個執行中的執行個體,請透過網路支援啟動 FEMU:

ffx emu start workstation_eng.x64 --headless

瞭解系統元件

開啟另一個終端機視窗,然後使用 component list 指令傾印系統元件樹狀結構:

ffx component list

您會看到類似以下 (截斷) 清單的輸出內容:

/
/bootstrap
/bootstrap/archivist
/bootstrap/base_resolver
/bootstrap/console
/bootstrap/console-launcher
/bootstrap/decompressor
/bootstrap/device_name_provider
/bootstrap/driver_manager
/bootstrap/fshost
/bootstrap/kernel_debug_broker
/bootstrap/miscsvc
/bootstrap/netsvc
/bootstrap/power_manager
/bootstrap/ptysvc
/bootstrap/pwrbtn-monitor
/bootstrap/shutdown_shim
/bootstrap/sysinfo
/bootstrap/virtual_console
/core
/core/activity
...
/core/detect
/core/font_provider
/core/log-stats
/core/remote-control
/core/sampler
/core/system-update-committer
/core/temperature-logger
/core/test_manager
/core/full-resolver
/startup

此清單代表元件例項樹狀結構bootstrapcorestartup 等機構元件會在根層級之下形成子樹狀結構。

component show 指令提供每個元件的詳細資料。

請使用這個指令查看 http-client 的詳細資料,這是提供 HTTP 要求服務的元件:

ffx component show http-client.cm

這個指令會輸出下列報表:

               Moniker: /core/network/http-client
                   URL: #meta/http-client.cm
                  Type: CML static component
       Component State: Resolved
 Incoming Capabilities: config
                        fuchsia.logger.LogSink
                        fuchsia.net.name.Lookup
                        fuchsia.posix.socket.Provider
                        pkg
  Exposed Capabilities: fuchsia.net.http.Loader
           Merkle root: d9e73f5b061f2f227e596e2e0079ff3a095fc69e192cf85e0d7621826c76356c
       Execution State: Running
          Start reason: '/core/feedback' requested capability 'fuchsia.net.http.Loader'
         Running since: ...
                Job ID: 41268
            Process ID: 41311
 Outgoing Capabilities: fuchsia.net.http.Loader

請注意這裡回報的其中一些詳細資料:

  1. 元件執行個體的專屬 ID (稱為「捷徑」)。
  2. 載入這個元件的來源套件網址。
  3. 元件的執行狀態。
  4. 執行個體目前的工作/程序 ID。
  5. 元件要求和公開的一組功能。

繪製能力路徑

在先前的輸出內容中,列出了三個能力群組:

  • 傳入功能:元件使用 use 宣告的功能。這些元件會透過其「命名空間」提供給元件。
  • 傳出功能:元件已發布至其傳出目錄的功能。
  • 公開功能:元件使用 expose 宣告的功能。這些是元件的公開服務

http-client 向父項 realm 公開的其中一項功能為 fuchsia.net.http.Loader。 這可讓其他元件發出 HTTP 要求。

使用 component capability 指令判斷有多少元件與這項能力互動:

ffx component capability fuchsia.net.http.Loader

這個指令會列出所有相符的元件:

Exposed:
  /core/network/http-client
  /core/network
Used:
  /core/cobalt
  /core/feedback
  /core

這表示 cobaltfeedback 元件使用了這項能力 (即列於「Incoming Capabilities」(傳入的功能) 底下)。這些元件之間的共同祖系為 core,會處理此能力轉送到必要的子項。