![](/img/trans.png)
[英]Problems while creating a Linux-executable file from C# sourcecode using mkbundle
[英]Problems with creating and using Linux namespaces
我正在命名空間上制作一個 go 庫包裝器。 .net ns、ips ns 和 uts ns 沒有問題,但其他的有問題:
用戶名:
MntNS:
進程:
時間NS:
創建命名空間代碼:
func NewNamespace(NSs []string) (*Namespace, error) {
var flag int = 0
for _, ns := range NSs {
if val, ok := CloneFlags[ns]; ok == true {
flag = flag | val
continue
}
return nil, errors.New("unsupported ns " + ns)
}
if err := unix.Unshare(flag); err != nil {
return nil, err
}
return GetCurrent()
}
獲取當前 NS 代碼:
func GetCurrent() (*Namespace, error) {
return GetFromThread(os.Getpid(), unix.Gettid())
}
func GetFromThread(pid, tid int) (*Namespace, error) {
ns := newNamespace()
for _, n := range NSs {
if entry, ok := ns.ns[n]; ok {
entry.path = fmt.Sprintf("/proc/%d/task/%d/ns/%s", pid, tid, n)
fd, err := OpenNS(entry.path)
if err != nil {
return nil, err
}
entry.fd = fd
ns.ns[n] = entry
}
}
return ns, nil
}
設置 NS 代碼:
func SetNamespace(ns *Namespace, NSs []string) error {
for _, n := range NSs {
if entry, ok := ns.ns[n]; ok {
entry.share = true
ns.ns[n] = entry
}
}
for key, val := range ns.ns {
if !val.share {
continue
}
fmt.Printf("Preparing %s...\n", key)
err := unix.Setns(val.fd, CloneFlags[key])
if err != nil {
return err
}
fmt.Printf("Set %s\n", key)
}
return nil
}
掛載過程代碼:
func mountProc() error {
if err := syscall.Mount("proc", "/proc", "proc", 0, ""); err != nil {
return err
}
return nil
}
標志:
const (
CLONE_NEWUTS = unix.CLONE_NEWUTS //Work
CLONE_NEWNS = unix.CLONE_NEWNS
CLONE_NEWCGROUP = unix.CLONE_NEWCGROUP
CLONE_NEWTIME = unix.CLONE_NEWTIME
CLONE_NEWIPC = unix.CLONE_NEWIPC //Work
CLONE_NEWUSER = unix.CLONE_NEWUSER
CLONE_NEWPID = unix.CLONE_NEWPID
CLONE_NEWNET = unix.CLONE_NEWNET //Work
CLONE_IO = unix.CLONE_IO
)
我想我遺漏了一些東西,但我不知道是什么,也許需要 ns 的組合。
用戶名:
- 嘗試創建時,出現“無效參數”(系統調用錯誤)。
根據man 2 unshare
,“ CLONE_NEWUSER
要求調用進程不是線程化的”,但是您的進程是線程化的,正如您可以通過 strace output 中帶有CLONE_THREAD
的clone
系統調用來判斷的那樣。
MntNS:
- mnt ns 正在創建,但不起作用,我使用 mount proc 檢查過。
我不知道你檢查了什么,但我猜你遇到了什么之后您需要立即做的第一件事就是將其改回。 看看在創建掛載命名空間后立即執行類似syscall.Mount("none", "/", nil, syscall.MS_REC | syscall.MS_PRIVATE, "")
操作是否有幫助。
進程:
- proc ns 也已創建,但顯示主機進程,掛載不起作用。
我假設你的意思是 PID 命名空間,因為沒有 proc 命名空間這樣的東西。 這一次,我可以想到兩個可能出錯的原因。 首先,再次根據man 2 unshare
,“調用進程為其子進程有一個新的 PID 命名空間”和“調用進程未移入新的命名空間。” 因此,這不會影響您的流程,並且要使其執行任何操作,您需要啟動一個子流程。 其次,根據man 7 pid_namespaces
,您需要從 PID 命名空間內掛載 proc 文件系統的新實例,以查看其中的 PID。
時間NS:
- time ns 沒有創建錯誤“太多用戶”(系統調用錯誤)。
看起來這是正在創建,只是未能設置。 很難找到明確說明這一點的文檔,但通過閱讀 kernel 源代碼,它看起來與用戶命名空間一樣,您不能在多線程進程上設置時間命名空間,但與 PID 命名空間一樣,如果您生成子進程,它應該有它設置。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.