创建命名空间时出错

创建命名空间时出错

我正在尝试使用新的命名空间创建一个进程,为此我需要使用带有适当标志的clone(2),以下是clone系统调用和打印父PID的printf()语句:

printf("clone() = %ld\n", (long)getpid());
printf("PID: %ld\n", (long)getpid());
struct utsname utsname;
uname(&utsname);
printf("parent namespace hostname: %s\n", utsname.nodename);

clone(child_main(&process_struct, checkpoint), stack + process_struct.Stack,
  CLONE_NEWCGROUP
 |CLONE_NEWIPC
 |CLONE_NEWNET
 |CLONE_NEWNS
 |CLONE_NEWPID
 |CLONE_NEWUTS|SIGCHLD, &process_struct)

而child_main()函数,子函数将设置主机名,然后打印子进程的PID,问题是系统的主机名改变的不仅仅是命名空间的主机名,而且子进程的PID与父进程的PID相同,这错误,命名空间内的子进程 PID 应该为 1,其 PPID 为 0(意味着没有父进程),sethostname(2) 也必须只影响子进程命名空间

int child_main(struct process *process, int *checkpoint){

  char c;

  fprintf(stderr,"=> IPC setup...");
  //double check the IPC
  close(checkpoint[1]);
  fprintf(stderr,"Done\n");
  if ( sethostname(process->Hostname, strlen(process->Hostname)){

    //close(process->File_descriptor);
    return -1;
  }


  printf("PID: %ld\n", (long)getpid());
  struct utsname utsname;
  uname(&utsname);
  printf("child namespace hostname: %s\n", utsname.nodename);

  // startup the IPC pipes
  read(checkpoint[0], &c, 1);
  char* argv[]={(char*)0};
  if(execve("/bin/bash", argv, NULL) == -1 ){
    fprintf(stderr,"--> Launching process Failed %m\n");
    return -1;
  }

  return 0;

}

答案1

glibcclone()包装器将函数指针作为第一个参数。

您没有向它传递一个函数指针,而是一个(在父进程中调用的int返回值,child_main调用克隆)。如果child_main传递一个NULL指针作为第一个参数(0从您的返回child_main),它将返回 -1 并设置errnoEINVAL,但我猜您没有检查它的返回值。

clone()联机帮助页:

EINVAL当or指定为 NULL时,由 glibcclone()包装函数返回。fnchild_stack

因此,child_main将在父进程中运行,不会创建任何子进程或命名空间,并child_main在初始命名空间中设置主机名,即为您的整个机器设置主机名。

相关内容