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 *fsc;
|
||||||
struct fork_sync_container *fp;
|
struct fork_sync_container *fp;
|
||||||
struct fork_sync_container *fb;
|
struct fork_sync_container *fb;
|
||||||
|
int flag = w.sr.args[0];
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
pid_t pid;
|
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));
|
memset(fs, '\0', sizeof(struct fork_sync));
|
||||||
sem_init(&fs->sem, 1, 0);
|
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) {
|
switch (pid) {
|
||||||
/* Error */
|
/* Error */
|
||||||
|
|||||||
@@ -400,6 +400,7 @@ struct process {
|
|||||||
int fsgid;
|
int fsgid;
|
||||||
int execed;
|
int execed;
|
||||||
int nohost;
|
int nohost;
|
||||||
|
int nowait;
|
||||||
struct rlimit rlimit[MCK_RLIM_MAX];
|
struct rlimit rlimit[MCK_RLIM_MAX];
|
||||||
unsigned long saved_auxv[AUXV_LEN];
|
unsigned long saved_auxv[AUXV_LEN];
|
||||||
char *saved_cmdline;
|
char *saved_cmdline;
|
||||||
|
|||||||
@@ -308,28 +308,6 @@ clone_thread(struct thread *org, unsigned long pc, unsigned long sp,
|
|||||||
struct process *proc = NULL;
|
struct process *proc = NULL;
|
||||||
struct address_space *asp = 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,
|
if ((thread = ihk_mc_alloc_pages(KERNEL_STACK_NR_PAGES,
|
||||||
IHK_MC_AP_NOWAIT)) == NULL) {
|
IHK_MC_AP_NOWAIT)) == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ static int wait_zombie(struct thread *thread, struct process *child, int *status
|
|||||||
}
|
}
|
||||||
|
|
||||||
ppid = child->ppid_parent->pid;
|
ppid = child->ppid_parent->pid;
|
||||||
if(ppid == 1)
|
if(ppid == 1 || child->nowait)
|
||||||
return 0;
|
return 0;
|
||||||
request.number = __NR_wait4;
|
request.number = __NR_wait4;
|
||||||
request.args[0] = child->pid;
|
request.args[0] = child->pid;
|
||||||
@@ -379,6 +379,7 @@ do_wait(int pid, int *status, int options, void *rusage)
|
|||||||
struct mcs_rwlock_node lock;
|
struct mcs_rwlock_node lock;
|
||||||
|
|
||||||
dkprintf("wait4,thread->pid=%d,pid=%d\n", thread->proc->pid, pid);
|
dkprintf("wait4,thread->pid=%d,pid=%d\n", thread->proc->pid, pid);
|
||||||
|
|
||||||
rescan:
|
rescan:
|
||||||
pid = orgpid;
|
pid = orgpid;
|
||||||
|
|
||||||
@@ -1823,6 +1824,7 @@ unsigned long do_fork(int clone_flags, unsigned long newsp,
|
|||||||
struct thread *new;
|
struct thread *new;
|
||||||
struct syscall_request request1 IHK_DMA_ALIGN;
|
struct syscall_request request1 IHK_DMA_ALIGN;
|
||||||
int ptrace_event = 0;
|
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",
|
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);
|
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;
|
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();
|
cpuid = obtain_clone_cpuid();
|
||||||
if (cpuid == -1) {
|
if (cpuid == -1) {
|
||||||
kprintf("do_fork,core not available\n");
|
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 */
|
/* fork() a new process on the host */
|
||||||
else {
|
else {
|
||||||
request1.number = __NR_fork;
|
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);
|
new->proc->pid = do_syscall(&request1, ihk_mc_get_processor_id(), 0);
|
||||||
if (new->proc->pid == -1) {
|
if (new->proc->pid == -1) {
|
||||||
kprintf("ERROR: forking host process\n");
|
kprintf("ERROR: forking host process\n");
|
||||||
@@ -1937,7 +1969,29 @@ unsigned long do_fork(int clone_flags, unsigned long newsp,
|
|||||||
chain_thread(new);
|
chain_thread(new);
|
||||||
if (!(clone_flags & CLONE_VM)) {
|
if (!(clone_flags & CLONE_VM)) {
|
||||||
new->proc->status = PS_RUNNING;
|
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) {
|
if (cpu_local_var(current)->proc->ptrace) {
|
||||||
@@ -2536,7 +2590,6 @@ SYSCALL_DECLARE(rt_sigtimedwait)
|
|||||||
ets.tv_sec++;
|
ets.tv_sec++;
|
||||||
ets.tv_nsec -= 1000000000L;
|
ets.tv_nsec -= 1000000000L;
|
||||||
}
|
}
|
||||||
kprintf("ets=%ld.%09ld\n", ets.tv_sec, ets.tv_nsec);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
memset(&ats, '\0', sizeof ats);
|
memset(&ats, '\0', sizeof ats);
|
||||||
@@ -2550,7 +2603,6 @@ kprintf("ets=%ld.%09ld\n", ets.tv_sec, ets.tv_nsec);
|
|||||||
if(timeout){
|
if(timeout){
|
||||||
if (gettime_local_support)
|
if (gettime_local_support)
|
||||||
calculate_time_from_tsc(&ats);
|
calculate_time_from_tsc(&ats);
|
||||||
kprintf("ats=%ld.%09ld\n", ats.tv_sec, ats.tv_nsec);
|
|
||||||
if(ats.tv_sec > ets.tv_sec ||
|
if(ats.tv_sec > ets.tv_sec ||
|
||||||
(ats.tv_sec == ets.tv_sec &&
|
(ats.tv_sec == ets.tv_sec &&
|
||||||
ats.tv_nsec >= ets.tv_nsec)){
|
ats.tv_nsec >= ets.tv_nsec)){
|
||||||
|
|||||||
Reference in New Issue
Block a user