clone: support CLONE_PARENT
This commit is contained in:
@@ -1859,6 +1859,7 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock)
|
||||
struct fork_sync_container *fsc;
|
||||
struct fork_sync_container *fp;
|
||||
struct fork_sync_container *fb;
|
||||
int flag = w.sr.args[0];
|
||||
int rc = -1;
|
||||
pid_t pid;
|
||||
|
||||
@@ -1878,7 +1879,41 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock)
|
||||
memset(fs, '\0', sizeof(struct fork_sync));
|
||||
sem_init(&fs->sem, 1, 0);
|
||||
|
||||
pid = fork();
|
||||
if(flag){
|
||||
int pipefds[2];
|
||||
|
||||
if(pipe(pipefds) == -1){
|
||||
rc = -errno;
|
||||
sem_destroy(&fs->sem);
|
||||
goto fork_err;
|
||||
}
|
||||
pid = fork();
|
||||
if(pid == 0){
|
||||
close(pipefds[0]);
|
||||
pid = fork();
|
||||
if(pid != 0){
|
||||
write(pipefds[1], &pid, sizeof pid);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
else if(pid != -1){
|
||||
int npid;
|
||||
int st;
|
||||
|
||||
close(pipefds[1]);
|
||||
read(pipefds[0], &npid, sizeof npid);
|
||||
close(pipefds[0]);
|
||||
waitpid(pid, &st, 0);
|
||||
pid = npid;
|
||||
}
|
||||
else{
|
||||
rc = -errno;
|
||||
sem_destroy(&fs->sem);
|
||||
goto fork_err;
|
||||
}
|
||||
}
|
||||
else
|
||||
pid = fork();
|
||||
|
||||
switch (pid) {
|
||||
/* Error */
|
||||
|
||||
@@ -400,6 +400,7 @@ struct process {
|
||||
int fsgid;
|
||||
int execed;
|
||||
int nohost;
|
||||
int nowait;
|
||||
struct rlimit rlimit[MCK_RLIM_MAX];
|
||||
unsigned long saved_auxv[AUXV_LEN];
|
||||
char *saved_cmdline;
|
||||
|
||||
@@ -308,28 +308,6 @@ clone_thread(struct thread *org, unsigned long pc, unsigned long sp,
|
||||
struct process *proc = NULL;
|
||||
struct address_space *asp = NULL;
|
||||
|
||||
|
||||
if (termsig < 0 || _NSIG < termsig) {
|
||||
return (void *)-EINVAL;
|
||||
}
|
||||
|
||||
if((clone_flags & CLONE_SIGHAND) &&
|
||||
!(clone_flags & CLONE_VM))
|
||||
return (void *)-EINVAL;
|
||||
if((clone_flags & CLONE_THREAD) &&
|
||||
!(clone_flags & CLONE_SIGHAND))
|
||||
return (void *)-EINVAL;
|
||||
if((clone_flags & CLONE_FS) &&
|
||||
(clone_flags & CLONE_NEWNS))
|
||||
return (void *)-EINVAL;
|
||||
if((clone_flags & CLONE_NEWIPC) &&
|
||||
(clone_flags & CLONE_SYSVSEM))
|
||||
return (void *)-EINVAL;
|
||||
if((clone_flags & CLONE_NEWPID) &&
|
||||
(clone_flags & CLONE_THREAD))
|
||||
return (void *)-EINVAL;
|
||||
|
||||
|
||||
if ((thread = ihk_mc_alloc_pages(KERNEL_STACK_NR_PAGES,
|
||||
IHK_MC_AP_NOWAIT)) == NULL) {
|
||||
return NULL;
|
||||
|
||||
@@ -292,7 +292,7 @@ static int wait_zombie(struct thread *thread, struct process *child, int *status
|
||||
}
|
||||
|
||||
ppid = child->ppid_parent->pid;
|
||||
if(ppid == 1)
|
||||
if(ppid == 1 || child->nowait)
|
||||
return 0;
|
||||
request.number = __NR_wait4;
|
||||
request.args[0] = child->pid;
|
||||
@@ -379,6 +379,7 @@ do_wait(int pid, int *status, int options, void *rusage)
|
||||
struct mcs_rwlock_node lock;
|
||||
|
||||
dkprintf("wait4,thread->pid=%d,pid=%d\n", thread->proc->pid, pid);
|
||||
|
||||
rescan:
|
||||
pid = orgpid;
|
||||
|
||||
@@ -1823,6 +1824,7 @@ unsigned long do_fork(int clone_flags, unsigned long newsp,
|
||||
struct thread *new;
|
||||
struct syscall_request request1 IHK_DMA_ALIGN;
|
||||
int ptrace_event = 0;
|
||||
int termsig = clone_flags & 0x000000ff;
|
||||
|
||||
dkprintf("do_fork,flags=%08x,newsp=%lx,ptidptr=%lx,ctidptr=%lx,tls=%lx,curpc=%lx,cursp=%lx",
|
||||
clone_flags, newsp, parent_tidptr, child_tidptr, tlsblock_base, curpc, cursp);
|
||||
@@ -1836,6 +1838,31 @@ unsigned long do_fork(int clone_flags, unsigned long newsp,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (termsig < 0 || _NSIG < termsig) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if((clone_flags & CLONE_SIGHAND) &&
|
||||
!(clone_flags & CLONE_VM)){
|
||||
return -EINVAL;
|
||||
}
|
||||
if((clone_flags & CLONE_THREAD) &&
|
||||
!(clone_flags & CLONE_SIGHAND)){
|
||||
return -EINVAL;
|
||||
}
|
||||
if((clone_flags & CLONE_FS) &&
|
||||
(clone_flags & CLONE_NEWNS)){
|
||||
return -EINVAL;
|
||||
}
|
||||
if((clone_flags & CLONE_NEWIPC) &&
|
||||
(clone_flags & CLONE_SYSVSEM)){
|
||||
return -EINVAL;
|
||||
}
|
||||
if((clone_flags & CLONE_NEWPID) &&
|
||||
(clone_flags & CLONE_THREAD)){
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cpuid = obtain_clone_cpuid();
|
||||
if (cpuid == -1) {
|
||||
kprintf("do_fork,core not available\n");
|
||||
@@ -1859,6 +1886,11 @@ unsigned long do_fork(int clone_flags, unsigned long newsp,
|
||||
/* fork() a new process on the host */
|
||||
else {
|
||||
request1.number = __NR_fork;
|
||||
request1.args[0] = 0;
|
||||
if(clone_flags & CLONE_PARENT){
|
||||
if(cpu_local_var(current)->proc->ppid_parent->pid != 1)
|
||||
request1.args[0] = clone_flags;
|
||||
}
|
||||
new->proc->pid = do_syscall(&request1, ihk_mc_get_processor_id(), 0);
|
||||
if (new->proc->pid == -1) {
|
||||
kprintf("ERROR: forking host process\n");
|
||||
@@ -1937,7 +1969,29 @@ unsigned long do_fork(int clone_flags, unsigned long newsp,
|
||||
chain_thread(new);
|
||||
if (!(clone_flags & CLONE_VM)) {
|
||||
new->proc->status = PS_RUNNING;
|
||||
chain_process(new->proc);
|
||||
if(clone_flags & CLONE_PARENT){
|
||||
struct mcs_rwlock_node_irqsave lock;
|
||||
struct process *proc = cpu_local_var(current)->proc;
|
||||
struct process *parent;
|
||||
struct mcs_rwlock_node parent_lock;
|
||||
|
||||
mcs_rwlock_reader_lock(&proc->update_lock, &lock);
|
||||
parent = proc->ppid_parent;
|
||||
mcs_rwlock_reader_lock_noirq(&parent->update_lock, &parent_lock);
|
||||
if(parent->status == PS_EXITED || parent->status == PS_ZOMBIE){
|
||||
mcs_rwlock_reader_unlock_noirq(&parent->update_lock, &parent_lock);
|
||||
parent = cpu_local_var(resource_set)->pid1;
|
||||
mcs_rwlock_reader_lock_noirq(&parent->update_lock, &parent_lock);
|
||||
}
|
||||
new->proc->parent = parent;
|
||||
new->proc->ppid_parent = parent;
|
||||
new->proc->nowait = 1;
|
||||
chain_process(new->proc);
|
||||
mcs_rwlock_reader_unlock_noirq(&parent->update_lock, &parent_lock);
|
||||
mcs_rwlock_reader_unlock(&proc->update_lock, &lock);
|
||||
}
|
||||
else
|
||||
chain_process(new->proc);
|
||||
}
|
||||
|
||||
if (cpu_local_var(current)->proc->ptrace) {
|
||||
@@ -2536,7 +2590,6 @@ SYSCALL_DECLARE(rt_sigtimedwait)
|
||||
ets.tv_sec++;
|
||||
ets.tv_nsec -= 1000000000L;
|
||||
}
|
||||
kprintf("ets=%ld.%09ld\n", ets.tv_sec, ets.tv_nsec);
|
||||
}
|
||||
else {
|
||||
memset(&ats, '\0', sizeof ats);
|
||||
@@ -2550,7 +2603,6 @@ kprintf("ets=%ld.%09ld\n", ets.tv_sec, ets.tv_nsec);
|
||||
if(timeout){
|
||||
if (gettime_local_support)
|
||||
calculate_time_from_tsc(&ats);
|
||||
kprintf("ats=%ld.%09ld\n", ats.tv_sec, ats.tv_nsec);
|
||||
if(ats.tv_sec > ets.tv_sec ||
|
||||
(ats.tv_sec == ets.tv_sec &&
|
||||
ats.tv_nsec >= ets.tv_nsec)){
|
||||
|
||||
Reference in New Issue
Block a user