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