duanhuang1699 2014-09-04 15:07
浏览 62

在go中更改linux名称空间

I want to change namespace in go. When I'm compiling and running code in C it works fine, but in go I got errno 22 on netns syscall. Any Idea why this could occur?

go)

$ 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
$

The code below:

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)
    }
}
  • 写回答

1条回答 默认 最新

  • dongzha0149 2014-09-04 15:38
    关注

    You could use something like this skipping the cgo all together, I can't test it right now:

    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
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题