IPC namespace 用來隔離 System V IPC 對象和 POSIX message queues。其中 System V IPC 對象包含共享內存、信號量和消息隊列,筆者在《System V IPC 之共享內存》、《System V IPC 之信號量》和《System V IPC 之消息隊列》三篇博文中對它們分別進行過介紹。本文我們將通過 demo 演示如何通過 IPC namespace 對 IPC 資源進行隔離,本文的演示環境為 ubuntu 16.04。
操作 IPC 資源的工具
Linux 系統中默認自帶了操作 IPC 資源的命令行工具,如 ipcmk、ipcs 和 ipcrm 等。我們可以使用這些工具創建、查看和刪除 IPC 資源。
ipcmk
ipcmk 命令用來創建 IPC資源:共享內存、信號量和消息隊列。下面的命令用來創建包含 10 個信號量的信號量集:
$ ipcmk -S 10

ipcs
ipcs 命令顯示當前系統中 IPC 資源的信息。默認會顯示所有的 IPC 資源,包括共享內存、信號量和消息隊列。可以通過命令行中的選項來控制顯示的資源類型,比如通過應用 -s 選項,下面的命令只顯示系統中 IPC 信號量的信息:
$ ipcs -s

ipcrm
ipcrm 命令用來刪除系統中的 IPC 資源,此時必須指定資源的類型和標識。比如刪除我們剛才創建的 IPC 信號量集:
$ ipcrm -s

與 namespace 相關的工具
unshare 命令
unshare 命令把當前進程加入到一個新建的 namespace 中,然后運行指定的程序(不指定目標程序則運行系統的默認 shell)。在前文《Linux Namespace: UTS》中我們介紹了一些與 namespace 相關的 API,比如 unshare 函數。unshare 函數的功能是把當前進程加入到一個新建的 namespace 中。比起我們自己寫的小 demo,系統工具中已經內置了 unshare 命令行工具,本文將使用系統中的 unshare 命令進行相關的演示。對 unshare 命令的實現感興趣的朋友可以參考其源代碼,它也是通過調用 unshare 函數實現的。
下面的例子就是通過 unshare 命令讓新建的 bash 進程屬於新的 IPC namespace:
$ sudo unshare -i

nsenter 命令
nsenter 命令把當前進程加入到指定進程的 namespace 中,然后運行指定的程序(不指定目標程序則運行系統的默認 shell)。其實這個命令的核心功能也是通過我們在前文《Linux Namespace: UTS》中介紹的 setns 函數實現的。這個命令和 unshare 命令一樣,也屬於 linux 的 sys-utiles 工具,對其實現感興趣的朋友可以參考其源代碼。
我們接上面的例子,使用 nsenter 命令把一個 bash 進程加入到 4956 號進程的 IPC namespace 中:

此時當前 bash 進程的 IPC namespace 已經和 4956 號進程的 IPC namespace 是同一個了。
演示 IPC namespace 隔離
接下來讓我們通過 IPC 信號量的隔離來了解如何隔離 IPC namespace。
首先我們打開兩個 bash shell,為了方便區分,分別把它們稱為為 shell1 和 shell2。先在 shell2 中執行 sudo unshare -i,然后分別執行 readlink /proc/$$/ns/ipc 命令:

圖中左側為 shell1,右側為 shell2。可以看出它們的 IPC namespace 是不同的。
然后我們在 shell2 中創建 IPC 信號量集,並分別在兩個 shell 中進行查看:

結果顯示,shell1 中不能觀察到 shell2 中創建的 IPC 信號量集,這是因為 shell1 和 shell2 此時分別在不同的 IPC namespace 中。
接下來我們在 shell1 中啟動一個新的 bash 進程,並通過 nsenter 命令把它加入到 shell2 的 IPC namespace 中,然后再次查看 IPC 信號量信息:

這次 shell1 中顯示的信號量信息和 shell2 中是一樣的。
最后讓我們看看此時 shell1 和 shell2 中當前進程的 IPC namespace:

此時這兩個進程屬於同一個 IPC namespace,這才是他們可以看到相同的 IPC 資源的根本原因。
總結
總體來看,在我們了解了 linux namespace 的一些基本概念后,IPC namespace 隔離的觀察和理解還是比較簡單的。下篇我們將介紹 Mount namespace 的相關內容。
參考:
Linux Namespace系列(03):IPC namespace (CLONE_NEWIPC)
Namespaces man page
Ipcmk man page
Ipcs man page
Ipcrm man page
Unshare man page
Nsenter man page
