Date: Sat, 14 Oct 2006 11:49:25 GMT From: Roman Divacky <rdivacky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 107883 for review Message-ID: <200610141149.k9EBnPPp085203@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=107883 Change 107883 by rdivacky@rdivacky_witten on 2006/10/14 11:49:09 I got the semantics of pdeath_signal wrong. Implement it this time correctly. o introduce pdeath_signal in emuldata o introduce eventhandler for proc_reparent o implement proc_reparent event handler that psignals children in a case of parents death Affected files ... .. //depot/projects/linuxolator/src/sys/amd64/linux32/linux32_sysvec.c#2 edit .. //depot/projects/linuxolator/src/sys/compat/linux/linux_emul.c#5 edit .. //depot/projects/linuxolator/src/sys/compat/linux/linux_emul.h#2 edit .. //depot/projects/linuxolator/src/sys/compat/linux/linux_misc.c#12 edit .. //depot/projects/linuxolator/src/sys/i386/linux/linux_sysvec.c#2 edit .. //depot/projects/linuxolator/src/sys/kern/kern_exit.c#3 edit .. //depot/projects/linuxolator/src/sys/sys/eventhandler.h#2 edit Differences ... ==== //depot/projects/linuxolator/src/sys/amd64/linux32/linux32_sysvec.c#2 (text+ko) ==== @@ -129,6 +129,7 @@ static eventhandler_tag linux_exit_tag; static eventhandler_tag linux_schedtail_tag; static eventhandler_tag linux_exec_tag; +static eventhandler_tag linux_reparent_tag; /* * Linux syscalls return negative errno's, we do positive and map them @@ -1087,6 +1088,8 @@ NULL, 1000); linux_exec_tag = EVENTHANDLER_REGISTER(process_exec, linux_proc_exec, NULL, 1000); + linux_reparent_tag = EVENTHANDLER_REGISTER(reparent, linux_reparent, + NULL, 1000); if (bootverbose) printf("Linux ELF exec handler installed\n"); } else @@ -1114,6 +1117,7 @@ EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag); EVENTHANDLER_DEREGISTER(schedtail, linux_schedtail_tag); EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag); + EVENTHANDLER_DEREGISTER(reparent, linux_reparent_tag); if (bootverbose) printf("Linux ELF exec handler removed\n"); } else ==== //depot/projects/linuxolator/src/sys/compat/linux/linux_emul.c#5 (text+ko) ==== @@ -84,6 +84,7 @@ /* non-exec call */ em = malloc(sizeof *em, M_LINUX, M_WAITOK | M_ZERO); em->pid = child; + em->pdeath_signal = 0; if (flags & CLONE_VM) { /* handled later in the code */ } else { @@ -251,7 +252,7 @@ int error = 0; int *child_set_tid; - if (p->p_sysent != &elf_linux_sysvec) + if (__predict_true(p->p_sysent != &elf_linux_sysvec)) return; retry: @@ -299,3 +300,17 @@ EMUL_UNLOCK(&emul_lock); return 0; } + +/* p is locked */ +void +linux_reparent(void *arg __unused, struct proc *p) +{ + struct linux_emuldata *em; + + if (__predict_true(p->p_sysent != &elf_linux_sysvec)) + return; + + em = em_find(p, EMUL_UNLOCKED); + psignal(p, em->pdeath_signal); + EMUL_UNLOCK(&emul_lock); +} ==== //depot/projects/linuxolator/src/sys/compat/linux/linux_emul.h#2 (text+ko) ==== @@ -50,6 +50,8 @@ struct linux_emuldata_shared *shared; + int pdeath_signal; /* parent death signal */ + LIST_ENTRY(linux_emuldata) threads; /* list of linux threads */ }; @@ -71,6 +73,7 @@ void linux_proc_exit(void *, struct proc *); void linux_schedtail(void *, struct proc *); void linux_proc_exec(void *, struct proc *, struct image_params *); +void linux_reparent(void *, struct proc *); extern struct sx emul_shared_lock; extern struct sx emul_lock; ==== //depot/projects/linuxolator/src/sys/compat/linux/linux_misc.c#12 (text+ko) ==== @@ -1554,6 +1554,7 @@ int error = 0; struct proc *p = td->td_proc; char comm[LINUX_MAX_COMM_LEN]; + struct linux_emuldata *em; #ifdef DEBUG if (ldebug(prctl)) @@ -1565,12 +1566,16 @@ case LINUX_PR_SET_PDEATHSIG: if (!LINUX_SIG_VALID(args->arg2)) return (EINVAL); - PROC_LOCK(p); - p->p_sigparent = args->arg2; - PROC_UNLOCK(p); + em = em_find(p, EMUL_UNLOCKED); + KASSERT(em != NULL, ("prctl: emuldata not found.\n")); + em->pdeath_signal = args->arg2; + EMUL_UNLOCK(&emul_lock); break; case LINUX_PR_GET_PDEATHSIG: - error = copyout(&p->p_sigparent, (void *) args->arg2, sizeof(p->p_sigparent)); + em = em_find(p, EMUL_UNLOCKED); + KASSERT(em != NULL, ("prctl: emuldata not found.\n")); + error = copyout(&em->pdeath_signal, (void *) args->arg2, sizeof(em->pdeath_signal)); + EMUL_UNLOCK(&emul_lock); break; case LINUX_PR_SET_NAME: comm[LINUX_MAX_COMM_LEN-1] = 0; ==== //depot/projects/linuxolator/src/sys/i386/linux/linux_sysvec.c#2 (text+ko) ==== @@ -113,6 +113,7 @@ static eventhandler_tag linux_exit_tag; static eventhandler_tag linux_schedtail_tag; static eventhandler_tag linux_exec_tag; +static eventhandler_tag linux_reparent_tag; /* * Linux syscalls return negative errno's, we do positive and map them @@ -927,6 +928,8 @@ NULL, 1000); linux_exec_tag = EVENTHANDLER_REGISTER(process_exec, linux_proc_exec, NULL, 1000); + linux_reparent_tag = EVENTHANDLER_REGISTER(reparent, linux_reparent, + NULL, 1000); if (bootverbose) printf("Linux ELF exec handler installed\n"); } else @@ -954,6 +957,7 @@ EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag); EVENTHANDLER_DEREGISTER(schedtail, linux_schedtail_tag); EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag); + EVENTHANDLER_DEREGISTER(reparent, linux_reparent_tag); if (bootverbose) printf("Linux ELF exec handler removed\n"); } else ==== //depot/projects/linuxolator/src/sys/kern/kern_exit.c#3 (text+ko) ==== @@ -900,4 +900,5 @@ LIST_REMOVE(child, p_sibling); LIST_INSERT_HEAD(&parent->p_children, child, p_sibling); child->p_pptr = parent; + EVENTHANDLER_INVOKE(reparent, child); } ==== //depot/projects/linuxolator/src/sys/sys/eventhandler.h#2 (text+ko) ==== @@ -178,4 +178,7 @@ typedef void(*schedtail_fn)(void *, struct proc *); EVENTHANDLER_DECLARE(schedtail, schedtail_fn); + +typedef void(*reparent_fn)(void *, struct proc *); +EVENTHANDLER_DECLARE(reparent, reparent_fn); #endif /* SYS_EVENTHANDLER_H */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200610141149.k9EBnPPp085203>