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 MATLAB动图问题
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题