PERFORCE change 102640 for review

Roman Divacky rdivacky at FreeBSD.org
Fri Jul 28 10:30:29 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=102640

Change 102640 by rdivacky at 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;


More information about the p4-projects mailing list