我正在尝试实现一个容器,为此,我使用带有适当标志的clone(2)系统调用创建了一个进程:
if ((child_pid = clone(child_main, process_struct.Stack + process_struct.StackPtr,
CLONE_NEWCGROUP
|CLONE_NEWIPC
|CLONE_NEWNET
|CLONE_NEWNS
|CLONE_NEWPID
|CLONE_NEWUTS
|SIGCHLD, &process_struct, checkpoint)) == -1){
fprintf(stderr,"Failed...%m \n");
exit(EXIT_FAILURE);
}else{
fprintf(stderr,"Done\n");
waitpid(child_pid, NULL, 0);
}
inside child_main()我更改了进程名称空间的主机名,也设置了安装名称空间,我在分区上像普通的Linux安装一样安装了Linux文件系统层次结构(我这样做是为了创建干净的文件系统映像清除我的文件和二进制文件),然后将传播类型设置为MS_UNBINDABLE,然后我ivot_root(2)更改进程的根目录。
const int child_main(struct process *process_struct, int *checkpoint){
char c;
fprintf(stderr,"=> IPC setup...");
//double check the IPC
close(checkpoint[1]);
fprintf(stderr,"Done\n");
if ( sethostname(process_struct->Hostname,
strlen(process_struct->Hostname)) || mounting(process_struct)){
return -1;
}
// startup the IPC pipes
read(checkpoint[0], &c, 1);
if(execve("/bin/bash", (char*)0, NULL) == -1 ){
fprintf(stderr,"--> Launching process Failed %m\n");
return -1;
}
return 0;
}
问题是我的系统通过了execve(2)并没有启动/ bin / bash,并且程序正常运行。当我在execve(2)之前添加system(2)语句:system("ls");
时,它将列出适当的文件系统和当前工作目录。另外,当我将execve(2)参数更改为:
execve("/bin/ls", (char*)0, NULL)
或execve("/bin/pstree", (char*)0, NULL)
或任何其他参数将返回以下错误:无此文件或目录或通过exec系统传递了NULL argv [0] ,同样,当我在execve(2)系统调用中跟踪程序时,它也会给出: NULL,0,NULL)= 17992
该错误与文件系统映像无关,我已经执行了更多测试,并且正作为后续操作,我将其文件系统用于系统的文件系统,而不是我安装在分区上并运行/ bin / bash的系统。仍然无法正常工作,我创建了一个简单的C程序并对其进行了编译,因此运行良好,因此出现了一些错误,阻止了bin / bash的执行,从而进一步测试了这些结果,这些结果我已重新用于我的安装命名空间中的文件系统将相同的可执行文件首先移至"/"
下的文件系统,然后将其移至同一路径下的文件系统
我的可执行文件的主系统路径= /home/omar/docs/test.out
我从分区路径到可执行文件的已挂载文件系统= /home/omar/docs/test.out
由于我想在向每个可执行文件添加语句时检查同一路径是否会引起混乱,因此可以判断我的程序采用了哪个路径,并且它可以正常工作而没有任何问题并且可以按预期正确进行,因此问题就在于该系统基本命令将不起作用。
答案 0 :(得分:0)
您需要将适当的argv
数组传递给execve
。而且,如果您只是想传递当前环境,请使用execv
而不是execve
。
char *argv[] = {"bash", NULL};
if(execv("/bin/bash", argv) == -1 ){
perror("execv");
return -1;
}