PERFORCE change 107883 for review
Roman Divacky
rdivacky at FreeBSD.org
Sat Oct 14 04:49:26 PDT 2006
http://perforce.freebsd.org/chv.cgi?CH=107883
Change 107883 by rdivacky at 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 */
More information about the p4-projects
mailing list