diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index fd03064d..be77c96d 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -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 */ diff --git a/kernel/include/process.h b/kernel/include/process.h index 533e26b5..44d0d83b 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -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; diff --git a/kernel/process.c b/kernel/process.c index 4e113a2a..2889c528 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -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; diff --git a/kernel/syscall.c b/kernel/syscall.c index d218de90..9201d544 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -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)){