새로운 네임스페이스로 프로세스를 생성하려고 합니다. 이를 위해서는 적절한 플래그와 함께 clone(2)을 사용해야 합니다. 여기에 상위 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와 동일하다는 점입니다. 네임스페이스에 있는 하위 프로세스의 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
glibc clone()
래퍼는 함수 포인터를 첫 번째 인수로 사용합니다.
함수 포인터를 전달하지 않고 ( 부모 프로세스의 호출에서 int
반환 값을 전달합니다 .child_main
앞으로클론을 호출합니다). 첫 번째 인수( 귀하에서 반환됨 )로 포인터 child_main
를 전달 하면 -1이 반환되고 로 설정되지만 반환 값을 확인하지 않은 것 같습니다.NULL
0
child_main
errno
EINVAL
clone()
맨페이지 에서 :
EINVAL
또는 가 NULL 로 지정된 경우 glibc 래퍼 함수에 의해clone()
반환됩니다 .fn
child_stack
따라서 child_main
상위 프로세스에서 실행되고 하위 프로세스나 네임스페이스가 생성되지 않으며 child_main
호스트 이름은 초기 네임스페이스, 즉 전체 시스템에 설정됩니다.