hostname 是用来标识一台主机的,比如登录时的提示,在 Shell 的提示符上,都可以显示出来,这样的话,使用者可以知道自己用的是哪台机器。比如下图中的 nick@tigger:

_GNU_SOURCE<.h>
<span style="color: #0000ff">#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)
<span style="color: #008000">// <span style="color: #008000"> 调用 clone 时执行的函数
<span style="color: #0000ff">static <span style="color: #0000ff">int childFunc(<span style="color: #0000ff">void <span style="color: #000000">arg)
{
<span style="color: #0000ff">struct<span style="color: #000000"> utsname uts;
<span style="color: #0000ff">char <span style="color: #000000">shellname;
<span style="color: #008000">//<span style="color: #008000"> 在子进程的 UTS namespace 中设置 hostname
<span style="color: #0000ff">if (sethostname(arg,strlen(arg)) == -<span style="color: #800080">1<span style="color: #000000">)
errExit(<span style="color: #800000">"<span style="color: #800000">sethostname<span style="color: #800000">"<span style="color: #000000">);
</span><span style="color: #008000">//</span><span style="color: #008000"> 显示子进程的 hostname</span>
<span style="color: #0000ff">if</span> (uname(&uts) == -<span style="color: #800080">1</span><span style="color: #000000">)
errExit(</span><span style="color: #800000">"</span><span style="color: #800000">uname</span><span style="color: #800000">"</span><span style="color: #000000">);
printf(</span><span style="color: #800000">"</span><span style="color: #800000">uts.nodename in child: %sn</span><span style="color: #800000">"</span><span style="color: #000000">,uts.nodename);
printf(</span><span style="color: #800000">"</span><span style="color: #800000">My PID is: %dn</span><span style="color: #800000">"</span><span style="color: #000000">,getpid());
printf(</span><span style="color: #800000">"</span><span style="color: #800000">My parent PID is: %dn</span><span style="color: #800000">"</span><span style="color: #000000">,getppid());
</span><span style="color: #008000">//</span><span style="color: #008000"> 获取系统的默认 shell</span>
shellname = getenv(<span style="color: #800000">"</span><span style="color: #800000">SHELL</span><span style="color: #800000">"</span><span style="color: #000000">);
</span><span style="color: #0000ff">if</span>(!<span style="color: #000000">shellname){
shellname </span>= (<span style="color: #0000ff">char</span> *)<span style="color: #800000">"</span><span style="color: #800000">/bin/sh</span><span style="color: #800000">"</span><span style="color: #000000">;
}
</span><span style="color: #008000">//</span><span style="color: #008000"> 在子进程中执行 shell</span>
execlp(shellname,shellname,(<span style="color: #0000ff">char</span> *<span style="color: #000000">)NULL);
</span><span style="color: #0000ff">return</span> <span style="color: #800080">0</span><span style="color: #000000">;
}
<span style="color: #008000">//<span style="color: #008000"> 设置子进程的堆栈大小为 1M
<span style="color: #0000ff">#define STACK_SIZE (1024 * 1024)
<span style="color: #0000ff">int main(<span style="color: #0000ff">int argc,<span style="color: #0000ff">char <span style="color: #000000">argv[])
{
<span style="color: #0000ff">char <span style="color: #000000">stack;
<span style="color: #0000ff">char *<span style="color: #000000">stackTop;
pid_t pid;
</span><span style="color: #0000ff">if</span> (argc < <span style="color: #800080">2</span><span style="color: #000000">) {
fprintf(stderr,</span><span style="color: #800000">"</span><span style="color: #800000">Usage: %s <child-hostname>n</span><span style="color: #800000">"</span>,argv[<span style="color: #800080">0</span><span style="color: #000000">]);
exit(EXIT_SUCCESS);
}
</span><span style="color: #008000">//</span><span style="color: #008000"> 为子进程分配堆栈空间,大小为 1M</span>
stack = <span style="color: #0000ff">malloc</span><span style="color: #000000">(STACK_SIZE);
</span><span style="color: #0000ff">if</span> (stack ==<span style="color: #000000"> NULL)
errExit(</span><span style="color: #800000">"</span><span style="color: #800000">malloc</span><span style="color: #800000">"</span><span style="color: #000000">);
stackTop </span>= stack + STACK_SIZE; <span style="color: #008000">/*</span><span style="color: #008000"> Assume stack grows downward </span><span style="color: #008000">*/</span>
<span style="color: #008000">//</span><span style="color: #008000"> 通过 clone 函数创建子进程
</span><span style="color: #008000">//</span><span style="color: #008000"> CLONE_NEWUTS 标识指明为新进程创建新的 UTS namespace</span>
pid = clone(childFunc,stackTop,CLONE_NEWUTS | SIGCHLD,argv[<span style="color: #800080">1</span><span style="color: #000000">]);
</span><span style="color: #0000ff">if</span> (pid == -<span style="color: #800080">1</span><span style="color: #000000">)
errExit(</span><span style="color: #800000">"</span><span style="color: #800000">clone</span><span style="color: #800000">"</span><span style="color: #000000">);
</span><span style="color: #008000">//</span><span style="color: #008000"> 等待子进程退出</span>
<span style="color: #0000ff">if</span> (waitpid(pid,NULL,<span style="color: #800080">0</span>) == -<span style="color: #800080">1</span><span style="color: #000000">)
errExit(</span><span style="color: #800000">"</span><span style="color: #800000">waitpid</span><span style="color: #800000">"</span><span style="color: #000000">);
printf(</span><span style="color: #800000">"</span><span style="color: #800000">child has terminatedn</span><span style="color: #800000">"</span><span style="color: #000000">);
exit(EXIT_SUCCESS);
}
$ -Wall uts_clone.c -o uts_clone_demo
$ ./uts_clone_demo


_GNU_SOURCE
<span style="color: #0000ff">#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)
<span style="color: #0000ff">int main(<span style="color: #0000ff">int argc,<span style="color: #0000ff">char *<span style="color: #000000">argv[])
{
<span style="color: #0000ff">int<span style="color: #000000"> fd;
</span><span style="color: #0000ff">if</span> (argc < <span style="color: #800080">3</span><span style="color: #000000">) {
fprintf(stderr,</span><span style="color: #800000">"</span><span style="color: #800000">%s /proc/PID/ns/FILE cmd args...n</span><span style="color: #800000">"</span>,argv[<span style="color: #800080">0</span><span style="color: #000000">]);
exit(EXIT_FAILURE);
}
</span><span style="color: #008000">//</span><span style="color: #008000"> 打开一个现存的 UTS namespace 文件</span>
fd = open(argv[<span style="color: #800080">1</span><span style="color: #000000">],O_RDONLY);
</span><span style="color: #0000ff">if</span> (fd == -<span style="color: #800080">1</span><span style="color: #000000">)
errExit(</span><span style="color: #800000">"</span><span style="color: #800000">open</span><span style="color: #800000">"</span><span style="color: #000000">);
</span><span style="color: #008000">//</span><span style="color: #008000"> 把当前进程的 UTS namespace 设置为命令行参数传入的 namespace</span>
<span style="color: #0000ff">if</span> (setns(fd,<span style="color: #800080">0</span>) == -<span style="color: #800080">1</span><span style="color: #000000">)
errExit(</span><span style="color: #800000">"</span><span style="color: #800000">setns</span><span style="color: #800000">"</span><span style="color: #000000">);
</span><span style="color: #008000">//</span><span style="color: #008000"> 在新的 UTS namespace 中运行用户指定的程序</span>
execvp(argv[<span style="color: #800080">2</span>],&argv[<span style="color: #800080">2</span><span style="color: #000000">]);
errExit(</span><span style="color: #800000">"</span><span style="color: #800000">execvp</span><span style="color: #800000">"</span><span style="color: #000000">);
}
$ -Wall uts_setns.c -o uts_setns_demo
$ ./uts_clone_demo myhost

$ ./uts_setns_demo /proc//ns/uts ${SHELL}

_GNU_SOURCE
<span style="color: #0000ff">#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)<span style="color: #000000">
static void usage( <span style="color: #0000ff">char *<span style="color: #000000">pname)
{
fprintf(stderr,<span style="color: #800000">"<span style="color: #800000">Usage: %s [options] program [arg...]n<span style="color: #800000">"<span style="color: #000000">,pname);
fprintf(stderr,<span style="color: #800000">"<span style="color: #800000">Options can be:n<span style="color: #800000">"<span style="color: #000000">);
fprintf(stderr,<span style="color: #800000">"<span style="color: #800000"> -i unshare IPC namespacen<span style="color: #800000">"<span style="color: #000000">);
fprintf(stderr,<span style="color: #800000">"<span style="color: #800000"> -m unshare mount namespacen<span style="color: #800000">"<span style="color: #000000">);
fprintf(stderr,<span style="color: #800000">"<span style="color: #800000"> -n unshare network namespacen<span style="color: #800000">"<span style="color: #000000">);
fprintf(stderr,<span style="color: #800000">"<span style="color: #800000"> -p unshare PID namespacen<span style="color: #800000">"<span style="color: #000000">);
fprintf(stderr,<span style="color: #800000">"<span style="color: #800000"> -u unshare UTS namespacen<span style="color: #800000">"<span style="color: #000000">);
fprintf(stderr,<span style="color: #800000">"<span style="color: #800000"> -U unshare user namespacen<span style="color: #800000">"<span style="color: #000000">);
exit(EXIT_FAILURE);
}
<span style="color: #0000ff">int main(<span style="color: #0000ff">int argc,<span style="color: #0000ff">char *<span style="color: #000000">argv[])
{
<span style="color: #0000ff">int<span style="color: #000000"> flags,opt;
flags = <span style="color: #800080">0<span style="color: #000000">;
</span><span style="color: #0000ff">while</span> ((opt = <span style="color: #0000ff">getopt</span>(argc,argv,<span style="color: #800000">"</span><span style="color: #800000">imnpuU</span><span style="color: #800000">"</span>)) != -<span style="color: #800080">1</span><span style="color: #000000">) {
switch (opt) {
</span><span style="color: #0000ff">case</span> <span style="color: #800000">'</span><span style="color: #800000">i</span><span style="color: #800000">'</span>: flags |=<span style="color: #000000"> CLONE_NEWIPC; break;
</span><span style="color: #0000ff">case</span> <span style="color: #800000">'</span><span style="color: #800000">m</span><span style="color: #800000">'</span>: flags |=<span style="color: #000000"> CLONE_NEWNS; break;
</span><span style="color: #0000ff">case</span> <span style="color: #800000">'</span><span style="color: #800000">n</span><span style="color: #800000">'</span>: flags |=<span style="color: #000000"> CLONE_NEWNET; break;
</span><span style="color: #0000ff">case</span> <span style="color: #800000">'</span><span style="color: #800000">p</span><span style="color: #800000">'</span>: flags |=<span style="color: #000000"> CLONE_NEWPID; break;
</span><span style="color: #0000ff">case</span> <span style="color: #800000">'</span><span style="color: #800000">u</span><span style="color: #800000">'</span>: flags |=<span style="color: #000000"> CLONE_NEWUTS; break;
</span><span style="color: #0000ff">case</span> <span style="color: #800000">'</span><span style="color: #800000">U</span><span style="color: #800000">'</span>: flags |=<span style="color: #000000"> CLONE_NEWUSER; break;
default: usage(argv[</span><span style="color: #800080">0</span><span style="color: #000000">]);
}
}
</span><span style="color: #0000ff">if</span> (optind >=<span style="color: #000000"> argc)
usage(argv[</span><span style="color: #800080">0</span><span style="color: #000000">]);
</span><span style="color: #0000ff">if</span> (unshare(flags) == -<span style="color: #800080">1</span><span style="color: #000000">)
errExit(</span><span style="color: #800000">"</span><span style="color: #800000">unshare</span><span style="color: #800000">"</span><span style="color: #000000">);
execvp(argv[optind],</span>&<span style="color: #000000">argv[optind]);
errExit(</span><span style="color: #800000">"</span><span style="color: #800000">execvp</span><span style="color: #800000">"</span><span style="color: #000000">);
}
$ -Wall uts_unshare.c -o uts_unshare_demo



SYSCALL_DEFINE2(gethostname, __user *,name, new_utsname *= (copy_to_user(name,u->= -

(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|