在CentOS6.5使用setns系统调用

| 分类 Linux  | 标签 namespace 

系统调用setns是内核在3.0引入的一个新的系统调用,参考这里

centos6.5的内核支持该系统调用,但用户态的glibc(2.12)并不支持该系统调用。

考虑下面的示例,引自这里

#define _GNU_SOURCE
#include <fcntl.h>
#include <sched.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

#define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
} while (0)

        int
main(int argc, char *argv[])
{
        int fd;

        if (argc < 3) {
                fprintf(stderr, "%s /proc/PID/ns/FILE cmd args...\n", argv[0]);
                exit(EXIT_FAILURE);
        }

        fd = open(argv[1], O_RDONLY);  /* Get descriptor for namespace */
        if (fd == -1)
                errExit("open");

        if (setns(fd, 0) == -1)        /* Join that namespace */
                errExit("setns");

        execvp(argv[2], &argv[2]);     /* Execute a command in namespace */
        errExit("execvp");
}
# gcc -o setns setns.c 
/tmp/ccYruvAB.o: In function `main':
setns.c:(.text+0x8c): undefined reference to `setns'
collect2: ld 返回 1

链接时会出错。

# grep "SYS_setns" /usr/include/bits/syscall.h  -n
220:#define SYS_setns __NR_setns

可以看到头文件的确有该系统调用的声明。

为了在CentOS6.5上也可以使用该系统调用,我们可以自己实现该函数:

// Use raw setns syscall for versions of glibc that don't include it (namely glibc-2.12)
#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 14
#include <sched.h>
#include "syscall.h"
#ifdef SYS_setns
int setns(int fd, int nstype)
{
	return syscall(SYS_setns, fd, nstype);
}
#endif
#endif

上一篇     下一篇