命名空間是 Fuchsia 中檔案存取和服務探索的基礎。
定義
命名空間是提供給元件的檔案、目錄、通訊端、服務、裝置和其他命名物件的複合階層。
讓我們進一步瞭解。
物件有名稱:命名空間包含可依名稱列舉及存取的 物件,就像列出目錄或開啟檔案一樣。
複合式階層:命名空間是物件的樹狀結構,這些物件是透過組合其他命名空間的物件子樹狀結構,組合成複合式結構,其中每個部分都會依慣例指定路徑前置字串。
每個元件都有自己的命名空間:每個元件都會收到專屬的命名空間,以滿足自身需求。它也可以發布自己的物件,以便納入其他命名空間。
您也可以不使用元件,單獨建立及使用命名空間,不過本文件著重於說明一般元件綁定的使用方式。
命名空間的實際應用
您可能已經花了一些時間探索 Fuchsia 命名空間,因為它無所不在。如果您在指令列殼層提示中輸入 ls /
,系統會列出可透過殼層命名空間存取的部分物件。
與其他作業系統不同,Fuchsia 沒有「根目錄」。如先前所述,命名空間是依元件定義,而非全域或依程序定義。
這會產生一些有趣的影響:
- 沒有全域「root」命名空間。
- 由於每個元件實際上都有自己的私人「root」,因此沒有「在 chroot 環境中執行」的概念。
- 元件會收到專為其特定需求量身打造的命名空間。
- 物件路徑在命名空間邊界中可能沒有意義。
- 一個程序可能會同時存取多個不同的命名空間。
- 用於控管檔案存取權的機制,也可以用於控管服務和其他命名物件的存取權 (依個別元件為準)。
物件
命名空間中的項目稱為物件。這些變體版本包括:
- 檔案:包含二進位資料的物件
- 目錄:包含其他物件的物件
- Sockets:開啟時會建立連線的物件,例如命名管道
- 服務:在開啟時提供 FIDL 服務的物件
- 裝置:提供硬體資源存取權的物件
存取物件
如要存取命名空間中的物件,您必須先擁有另一個物件。在命名空間轉移期間,元件通常會收到其命名空間範圍內物件的管道句柄。
您也可以實作適當的 FIDL 通訊協定,從無到有建立新物件。
針對物件的管道,您可以為其其中一個子物件開啟管道,方法是傳送 FIDL 訊息,其中包含可識別所需子物件的物件相對路徑運算式。這很像在目錄中開啟檔案。
請注意,您只能存取可從您已存取的物件存取的物件。沒有環境權限。
我們現在將定義物件名稱和路徑的建構方式。
物件名稱
物件名稱是本機專屬標籤,可用於在容器 (例如目錄) 中找到物件。請注意,名稱是容器子物件表格的屬性,而非物件本身的屬性。
例如,cat
會指定位於 Open()
要求中某個未指定收件者的毛茸茸物件。
物件基本上是沒有名稱的,但其他人可能會以多種名稱稱呼物件。
物件名稱會以二進位八位元字串 (任意位元組序列) 表示,並遵守下列限制:
- 長度下限為 1 個位元組。
- 長度上限為 255 位元組。
- 不含 NUL (零值位元組)。
- 不含
/
。 - 不等於
.
或..
。 - 一律使用位元組與位元組的等同性進行比較 (表示區分大小寫)。
物件名稱是容器 Open()
方法的有效引數。請參閱「FIDL 通訊協定」。
物件名稱應經過編碼,並解讀為人類可讀的 UTF-8 圖形字元序列,但命名空間本身不會強制執行這項屬性。
因此,用戶端負責決定如何向使用者顯示含有無效、無法顯示或模糊字元序列的名稱。
物件相對路徑運算式
物件相對路徑運算式是物件名稱,或以 /
分隔的物件名稱序列,用於指定要遍歷的巢狀物件序列,以便在容器 (例如目錄) 中尋找物件。
舉例來說,house/box/cat
會指定位於其包含物件 (稱為 box
) 中的毛茸物件,該包含物件位於其包含物件 (稱為 house
) 中,而該包含物件位於 Open()
要求的某個未指定收件者中。
物件相對路徑運算式一律會深入命名空間。值得注意的是,命名空間不直接支援從容器向上探索 (例如透過 ..
),但用戶端可能會部分模擬這項功能 (請參閱下文)。
物件相對於路徑運算式的限制如下:
- 長度下限為 1 個位元組。
- 長度上限為 4095 位元組。
- 開頭或結尾不是
/
。 - 所有區隔都是有效的物件名稱。
- 一律使用位元組與位元組的等同性進行比較 (表示區分大小寫)。
物件相對於路徑運算式是容器 Open()
方法的有效引數。請參閱「FIDL 通訊協定」。
由用戶端解讀的路徑運算式
用戶端解譯的路徑運算式是物件相對路徑運算式的概括,但包含可選功能,可由用戶端程式碼模擬,以便與預期有根目錄的類似檔案介面程式提升相容性。
從技術層面來說,這些功能超出 Fuchsia 命名空間通訊協定本身的範圍,但這些功能經常被使用,因此我們在此處加以說明。
- 用戶端可以將其中一個命名空間指定為「根」命名空間。這個命名空間會標示為
/
。 - 用戶端可以透過在前面加上單一
/
,建構相對於其指定根命名空間的路徑。 - 用戶端可以使用
..
路徑區段,透過稱為用戶端「標準化」的程序,將路徑從容器向上建構,方法是將區段摺疊在一起 (假設容器的路徑已知)。 - 這些功能可能會合併使用。
舉例來說,/places/house/box/../sofa/cat
會指定位於某個用戶端指定「root」容器內的 places/house/sofa/cat
中的 furry 物件。
包含這些選用功能的用戶端解譯路徑運算式,並非容器 Open()
方法的有效引數;用戶端必須先將這些運算式轉譯,才能與命名空間通訊。請參閱「FIDL 通訊協定」。
舉例來說,fdio
會在檔案操作 API 中實作用戶端對 ..
路徑的解讀,例如 open()
、stat()
、unlink()
等。
命名空間轉移
啟動元件 (例如啟動程序) 時,元件會收到一或多個命名空間路徑前置字串對應至物件句柄的資料表。
表格中的路徑前置字元會依慣例編碼,以便為相關聯物件指定預期的重要性。舉例來說,pkg
前置字元應與目錄物件相關聯,該物件包含元件的原生二進位檔和資產。
詳情請參閱下一節。
命名空間慣例
本節說明在 Fuchsia 上執行的一般元件慣用命名空間版面配置。
元件的命名空間具體內容和組織方式會因元件的角色、類型、身分、範圍、與其他元件的關係和權限而有很大差異。如要瞭解如何使用命名空間為元件建立沙箱,請參閱「沙箱」。
如要進一步瞭解元件可接收的命名空間,請參閱與您要實作的元件類型相關的說明文件。
常見物件
元件命名空間可能包含一些常見的物件:
- 元件套件中的唯讀可執行檔和資產。
- 私人的本機永久儲存空間。
- 私人臨時儲存空間。
- 系統、元件架構或啟動元件的用戶端,向元件提供的服務。
- 裝置節點 (適用於驅動程式和特權元件)。
- 設定資訊。
典型目錄結構
pkg/
:目前程式套件的內容,與套件簽署時的內容相同bin/
:套件中的可執行二進位檔lib/
:套件中的共用程式庫data/
:套件中的資料,例如資產
data/
:本機永久儲存空間 (讀取/寫入,元件專屬)tmp/
:臨時儲存空間 (讀取/寫入,專屬於元件)svc/
:提供給元件的通訊協定和服務fuchsia.process.Launcher
:啟動程序fuchsia.logger.Log
:記錄訊息vendor.topic.Interface
:由供應商定義的服務
dev/
:裝置樹狀結構 (需要時,特權元件可看見的相關部分)class/
……
config/
:元件的設定資料build-info/
:建構資訊檔案的標準路徑。ssl/
:SSL 憑證的標準路徑tzdata/
:時區資料檔案。第一個子路徑應為資料格式名稱,例如tzif2/...
或icudata/...
。
命名空間參與者
以下提供一些資訊,說明與 Fuchsia 命名空間通訊協定互動並支援該通訊協定的幾個抽象項目。
檔案系統
檔案系統會在命名空間中提供檔案。
檔案系統只是一個元件,可從其他人的命名空間發布類似檔案的物件。
通訊協定
通訊協定句柄是指由 FIDL 通訊協定實作項目所支援的管道物件,可透過命名空間進行探索。通訊協定名稱會對應至命名空間 /svc
分支中的路徑,元件可透過該路徑存取實作項目。
舉例來說,預設的 Fuchsia 記錄通訊協定為 fuchsia.logger.Log
,其在命名空間中的路徑為 /svc/fuchsia.logger.Log
。
如要進一步瞭解通訊協定和元件,請參閱「通訊協定功能」。
服務
服務句柄是包含相關 FIDL 通訊協定的目錄。您可以使用命名空間來探索這些通訊協定的實作方式。服務名稱會對應至命名空間 /svc
分支中的路徑,元件可透過該路徑存取實作項目。
如要進一步瞭解服務和元件,請參閱「服務功能」。
元件
元件會使用及擴充命名空間。
元件是可執行的程式物件,已在某些拓樸中例項化並提供命名空間。
元件參與 Fuchsia 命名空間的方式有兩種:
- 它可以使用提供給它的命名空間中的物件,例如傳入的通訊協定和服務,或是其本身的套件內容。
- 它可以透過其傳出目錄,以命名空間的形式將物件發布至其他元件。