Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 14 Oct 2006 11:49:25 GMT
From:      Roman Divacky <rdivacky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 107883 for review
Message-ID:  <200610141149.k9EBnPPp085203@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200610141149.k9EBnPPp085203>