Date: Fri, 28 Jul 2006 10:30:27 GMT From: Roman Divacky <rdivacky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 102640 for review Message-ID: <200607281030.k6SAUR06016140@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=102640 Change 102640 by rdivacky@rdivacky_witten on 2006/07/28 10:30:25 Add linux_getppid() and change linux_getpid() to work with group_pid. Affected files ... .. //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_misc.c#4 edit .. //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux.h#13 edit .. //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_machdep.c#24 edit Differences ... ==== //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_misc.c#4 (text+ko) ==== @@ -93,6 +93,9 @@ #define BSD_TO_LINUX_SIGNAL(sig) \ (((sig) <= LINUX_SIGTBLSZ) ? bsd_to_linux_signal[_SIG_IDX(sig)] : sig) +struct linux_emuldata *em_find(pid_t pid, int locked); +extern struct rwlock emul_lock; + static unsigned int linux_to_bsd_resource[LINUX_RLIM_NLIMITS] = { RLIMIT_CPU, RLIMIT_FSIZE, RLIMIT_DATA, RLIMIT_STACK, RLIMIT_CORE, RLIMIT_RSS, RLIMIT_NPROC, RLIMIT_NOFILE, @@ -1327,11 +1330,77 @@ * linux_getuid() - MP SAFE */ +/* XXX: getppid must be changed too */ + int linux_getpid(struct thread *td, struct linux_getpid_args *args) { + struct linux_emuldata *em; + + em = em_find(td->td_proc->p_pid, EMUL_UNLOCKED); + + if (em == NULL) { +#ifdef DEBUG + printf(LMSG("emuldata not found.\n")); +#endif + EMUL_RUNLOCK(&emul_lock); + return (0); + } + + td->td_retval[0] = em->shared->group_pid; + EMUL_RUNLOCK(&emul_lock); + return (0); +} + +int +linux_getppid(struct thread *td, struct linux_getppid_args *args) +{ + struct linux_emuldata *em; + struct proc *p, *pp; - td->td_retval[0] = td->td_proc->p_pid; + em = em_find(td->td_proc->p_pid, EMUL_UNLOCKED); + + if (em == NULL) { +#ifdef DEBUG + printf(LMSG("emuldata not found.\n")); +#endif + EMUL_RUNLOCK(&emul_lock); + return (0); + } + + /* find the group leader */ + p = pfind(em->shared->group_pid); + + if (p == NULL) { +#ifdef DEBUG + printf(LMSG("parent process not found.\n")); +#endif + return (0); + } + + pp = p->p_pptr; /* switch to parent */ + PROC_LOCK(pp); + PROC_UNLOCK(p); + + em = em_find(pp->p_pid, EMUL_UNLOCKED); + + if (em == NULL) { +#ifdef DEBUG + printf(LMSG("emuldata not found.\n")); +#endif + EMUL_RUNLOCK(&emul_lock); + return (0); + } + + /* if its also linux process */ + if (pp->p_sysent == &elf_linux_sysvec) + td->td_retval[0] = em->shared->group_pid; + else + td->td_retval[0] = pp->p_pid; + + EMUL_RUNLOCK(&emul_lock); + PROC_UNLOCK(pp); + return (0); } ==== //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux.h#13 (text+ko) ==== @@ -780,6 +780,11 @@ #define GET_PRESENT(desc) (((desc)->b >> ENTRY_B_SEG_NOT_PRESENT) & 1) #define GET_USEABLE(desc) (((desc)->b >> ENTRY_B_USEABLE) & 1) +struct linux_emuldata_shared { + int refs; + pid_t group_pid; +}; + /* modeled after similar structure in NetBSD * this will be extended as we need more functionality */ @@ -789,6 +794,8 @@ int *child_set_tid; /* in clone(): Child's TID to set on clone */ int *child_clear_tid; /* in clone(): Child's TID to clear on exit */ + struct linux_emuldata_shared *shared; + SLIST_ENTRY(linux_emuldata) emuldatas; }; ==== //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_machdep.c#24 (text+ko) ==== @@ -68,11 +68,11 @@ struct linux_emuldata *emuldata_headp; /* where we store the emulation data */ struct rwlock emul_lock; -static int linux_proc_init(struct thread *, pid_t); +static int linux_proc_init(struct thread *, pid_t, int); void linux_proc_exit(void *, struct proc *); void linux_schedtail(void *, struct proc *); void linux_proc_exec(void *, struct proc *, struct image_params *); -static struct linux_emuldata *em_find(pid_t pid, int locked); +struct linux_emuldata *em_find(pid_t pid, int locked); struct l_descriptor { l_uint entry_number; @@ -138,7 +138,7 @@ if (error == 0) error = kern_execve(td, &eargs, NULL); if (error == 0) - error = linux_proc_init(td, 0); + error = linux_proc_init(td, 0, 0); return (error); } @@ -290,7 +290,7 @@ } /* this returns locked reference to the emuldata entry (if found) */ -static struct linux_emuldata * +struct linux_emuldata * em_find(pid_t pid, int locked) { struct linux_emuldata *em; @@ -323,7 +323,7 @@ if (td->td_retval[1] == 1) td->td_retval[0] = 0; - error = linux_proc_init(td, td->td_retval[0]); + error = linux_proc_init(td, td->td_retval[0], 0); if (error) return (error); @@ -345,7 +345,7 @@ /* Are we the child? */ if (td->td_retval[1] == 1) td->td_retval[0] = 0; - error = linux_proc_init(td, td->td_retval[0]); + error = linux_proc_init(td, td->td_retval[0], 0); if (error) return (error); return (0); @@ -419,7 +419,7 @@ return (error); /* create the emuldata */ - error = linux_proc_init(td, p2->p_pid); + error = linux_proc_init(td, p2->p_pid, args->flags); /* reference it - no need to check this */ em = em_find(p2->p_pid, EMUL_UNLOCKED); KASSERT(em != NULL, "no emuldata after proc_init()!\n"); @@ -1130,9 +1130,9 @@ } static int -linux_proc_init(struct thread *td, pid_t child) +linux_proc_init(struct thread *td, pid_t child, int flags) { - struct linux_emuldata *em; + struct linux_emuldata *em, *p_em; /* XXX: locking? */ if (child != 0) { @@ -1156,7 +1156,31 @@ em->child_clear_tid = NULL; em->child_set_tid = NULL; + em->shared = NULL; + + if (flags & CLONE_VM) { + printf("CLONE_VM!!!!!\n"); + /* lookup the parent */ + p_em = em_find(td->td_proc->p_pptr->p_pid, EMUL_LOCKED); + if (p_em == NULL) { +#ifdef DEBUG + printf(LMSG("parent emuldata not found for CLONE_VM.\n")); +#endif + } else { + em->shared = p_em->shared; + em->shared->refs++; +#ifdef DEBUG +#endif + } + } else { + struct linux_emuldata_shared *s; + MALLOC(s, struct linux_emuldata_shared *, sizeof *s, M_LINUX, M_WAITOK | M_ZERO); + em->shared = s; + s->refs = 1; + s->group_pid = td->td_proc->p_pid; + } + if (child != 0) EMUL_WUNLOCK(&emul_lock); else @@ -1209,6 +1233,10 @@ printf(LMSG("futex stuff in proc_exit failed.\n")); } + em->shared->refs--; + if (em->shared->refs == 0); + FREE(em->shared, M_LINUX); + EMUL_RUNLOCK(&emul_lock); /* XXX: there is a race but I think we can ommit that * because its not very possible that the same process @@ -1231,7 +1259,7 @@ { if (__predict_false(imgp->sysent == &elf_linux_sysvec && p->p_sysent == &elf32_freebsd_sysvec)) - linux_proc_init(FIRST_THREAD_IN_PROC(p), p->p_pid); + linux_proc_init(FIRST_THREAD_IN_PROC(p), p->p_pid, 0); if (__predict_false(imgp->sysent == &elf32_freebsd_sysvec && p->p_sysent == &elf_linux_sysvec)) { struct linux_emuldata *em;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607281030.k6SAUR06016140>