setns setting the wrong namespace

54 Views Asked by At

I am trying to create five processes in the same pid namespace. I understand they should share the inode number of /proc/<pid>/ns/pid link. However, the first child seems to have a different link from the other four.

Code:

/* tellns.c


*/
#define _GNU_SOURCE
#include <sys/wait.h>
#include <sys/utsname.h>
#include <fcntl.h>
#include <sched.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
                        } while (0)
#define STACK_SIZE (1024 * 1024)    
static char child_stack[5][STACK_SIZE];

int childfunc(void *nhn){
    chroot(".");
    sleep(100);
    return 0;
}
int
main(int argc, char *argv[])
{
    int numchildren = 5;
    pid_t childpid;
    char nhn[1024];
    sprintf(nhn,"wizardpot");
    childpid = clone(childfunc,child_stack[0]+STACK_SIZE,CLONE_NEWPID | SIGCHLD,nhn);
    if(childpid==-1){
        errExit("clone err");
    }
    printf("childpids: %ld ",(long)childpid);
    for(int i=0;i<numchildren-1;i++){
        int pid = fork();
        if(pid==0){
            char path[1024];
            sprintf(path,"/proc/%d/ns/pid",(int)childpid);
            // printf("%s\n",path);
            int fd = open(path,O_RDONLY);
            setns(fd,CLONE_NEWPID);
            return childfunc(nhn);
        }
        else{
            printf("%d ",pid);
            if(i==numchildren-2){
                printf("\n");
                waitpid(pid,NULL,0);
            }
        }
    }
    waitpid(childpid,0,0);
}
The file I'm using to check root and namespace values:
import os,sys
from subprocess import Popen,PIPE
def main(pids):
    for pid in pids:
        print("PID: ",pid)
        p,_ = Popen(f'readlink /proc/{pid}/root',shell=True,stdout=PIPE).communicate()
        print(f"\tRoot: {p.decode()}",end='')
        p,_ = Popen(f'readlink /proc/{pid}/ns/pid',shell=True,stdout=PIPE).communicate()
        print(f"\tPID NS: {p.decode()}",end='')
if __name__=='__main__':
    main(sys.argv[1:])

Output:

from p1.c:
childpids: 5977 5978 5979 5980 5981 
from checker.py:
PID:  5977
        Root: /home/hardik/CODE/cs695/a4/q3
        PID NS: pid:[4026532406]
PID:  5978
        Root: /home/hardik/CODE/cs695/a4/q3
        PID NS: pid:[4026532284]
PID:  5979
        Root: /home/hardik/CODE/cs695/a4/q3
        PID NS: pid:[4026532284]
PID:  5980
        Root: /home/hardik/CODE/cs695/a4/q3
        PID NS: pid:[4026532284]
PID:  5981
        Root: /home/hardik/CODE/cs695/a4/q3
        PID NS: pid:[4026532284]
I expect all five inode numbers printed after PID NS:... to be the same, as I am assigning the four children to the pid namespace of the first child.

0

There are 0 best solutions below