From owner-p4-projects@FreeBSD.ORG Sat Oct 14 11:49:26 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B20E616A47E; Sat, 14 Oct 2006 11:49:26 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 8649216A47B for ; Sat, 14 Oct 2006 11:49:26 +0000 (UTC) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 39D5F43D80 for ; Sat, 14 Oct 2006 11:49:26 +0000 (GMT) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k9EBnQUw085211 for ; Sat, 14 Oct 2006 11:49:26 GMT (envelope-from rdivacky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k9EBnPPp085203 for perforce@freebsd.org; Sat, 14 Oct 2006 11:49:25 GMT (envelope-from rdivacky@FreeBSD.org) Date: Sat, 14 Oct 2006 11:49:25 GMT Message-Id: <200610141149.k9EBnPPp085203@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to rdivacky@FreeBSD.org using -f From: Roman Divacky To: Perforce Change Reviews Cc: Subject: PERFORCE change 107883 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 14 Oct 2006 11:49:26 -0000 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 */