簡體   English   中英

創建和使用 Linux 命名空間的問題

[英]Problems with creating and using Linux namespaces

我正在命名空間上制作一個 go 庫包裝器。 .net ns、ips ns 和 uts ns 沒有問題,但其他的有問題:

用戶名:

  • 嘗試創建時,出現“無效參數”(系統調用錯誤)。

MntNS:

  • mnt ns 正在創建,但不起作用,我使用 mount proc 檢查過。

進程:

  • proc ns 也已創建,但顯示主機進程,掛載不起作用。

時間NS:

  • time 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_THREADclone系統調用來判斷的那樣。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM