在CentOS中使用setns系統呼叫
系統呼叫setns是核心在3.0引入的一個新的系統呼叫,參考http://kernelnewbies.org/Linux_3.0#head-69fb31d5d1d284f3a95e56d0ec43a2b23c30c4f3
centos6.5的核心支援該系統呼叫,但使用者態的glibc(2.12)並不支援該系統呼叫。
考慮下面的示例,引自http://man7.org/linux/man-pages/man2/setns.2.html
#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