簡體   English   中英

在go中更改linux名稱空間

[英]Change linux namespace in go

我想在go中更改名稱空間。 當我在C中編譯和運行代碼時,它可以正常工作,但是在運行netns syscall時,出現了errno 22。 知道為什么會發生這種情況嗎?

走)

$ go build main.go ; ./main
setns mnt: Invalid argument
panic: -1

goroutine 1 [running]:
runtime.panic(0x423b80, 0xffffffffffffffff)
    /usr/local/go/src/pkg/runtime/panic.c:266 +0xb6
main.main()
    main.go:81 +0x86
$

C)

$ grep ^// main.go | sed 's/\/\///' | sed 's/__main/main/' > main.c; gcc main.c -o main; ./main
$

下面的代碼:

package main

//
// #define _GNU_SOURCE
// #include <fcntl.h>
// #include <sched.h>
// #include <sys/syscall.h>
// #include <sys/param.h>
// #include <sys/mount.h>
// #include <stdio.h>
// #include <unistd.h>
//
// #define NETNS_RUN_DIR "/run/netns"
// #define MNTNS_RUN_DIR "/run/mntns"
//
// #ifndef HAVE_SETNS
//
// int
// setns(int fd, int nstype) {
// #ifdef __NR_setns
//   return syscall(__NR_setns, fd, nstype);
// #else
//   errno = ENOSYS;
//   return -1;
// #endif
// }
//
// #endif /* HAVE_SETNS */
//
//
// int
// ChangeNamespace(char *name)
// {
//   char net_path[MAXPATHLEN];
//   char mnt_path[MAXPATHLEN];
//   int fd;
//
//   snprintf(net_path, sizeof(net_path), "%s/%s", NETNS_RUN_DIR, name);
//   snprintf(mnt_path, sizeof(mnt_path), "%s/%s", MNTNS_RUN_DIR, name);
//
//   fd = open(net_path, O_RDONLY);
//   if (fd < 0) {
//     perror("open net");
//     return -1;
//   }
//
//   if (setns(fd, 0) < 0) {
//     perror("setns net");
//     return -1;
//   }
//
//   fd = open(mnt_path, O_RDONLY);
//   if (fd < 0) {
//     perror("open mnt");
//     return -1;
//   }
//
//   if (setns(fd, 0) < 0) {
//     perror("setns mnt");
//     return -1;
//   }
//
//   return 0;
// }
//
// int
// __main(int argc, char *argv[]) {
//     ChangeNamespace("ns");
//     return 0;
// }
//
import "C"
import "unsafe"
func main() {
    name := C.CString("ns")
    defer C.free(unsafe.Pointer(name))
    i := int(C.ChangeNamespace(name))
    if i < 0 {
        panic(i)
    }
}

您可以使用類似這樣的方法一起跳過cgo,但現在無法測試:

const (
    netNS = "/run/netns/"
    mntNS = "/run/mntns/"
)
func ChangeNamespace(name string) error {
    fd, err := syscall.Open(netNS+name, syscall.O_RDONLY, 0666)
    if err != nil {
        return err
    }
    defer syscall.Close(fd)
    if _, _, err := syscall.RawSyscall(syscall.SYS_SETNS, uintptr(fd), 0, 0); err != nil {
        return err
    }

    fd1, err := syscall.Open(mntNS+name, syscall.O_RDONLY, 0666)
    if err != nil {
        return err
    }
    defer syscall.Close(fd1)
    if _, _, err := syscall.RawSyscall(syscall.SYS_SETNS, uintptr(fd1), 0, 0); err != nil {
        return err
    }
    return nil
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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