linux-um archives
 help / color / mirror / Atom feed
From: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
To: BlaisorBlade <blaisorblade_spam@yahoo.it>
Cc: Jeff Dike <jdike@addtoit.com>,
	user-mode-linux devel
	<user-mode-linux-devel@lists.sourceforge.net>
Subject: [uml-devel] [Patch 1/1] uml: fix uml-hang-on-2.6.9-host.patch
Date: Fri, 12 Nov 2004 15:46:05 +0100	[thread overview]
Message-ID: <4194CCAD.2020701@fujitsu-siemens.com> (raw)

From: Bodo Stroesser <bstroesser@fujitsu-siemens.com>

The patch needs to be corrected. The use of
os_kill_ptraced_process() is restricted to the tracer-thread!
No other process is allowed to do ptrace(PTRACE_KILL).
So I had "dead" processes hanging in my host system until UML
was shutdown. And I had panic()s, because processes were not
stopped.
Thus, I implemented request_kill_ptraced_process(), which lets
the tracer do the ptrace(PTRACE_KILL). Sorry, this method is
slow, but I didn't see an other solution.
Also, I modified some other places to use the new call instead
of os_kill_process(). But this didn't work on the first step.
kill_off_processes_tt() couldn't kill the remaining processes
on shutdown. This happens, because ptrace(PTRACE_KILL) doesn't
really send a SIGKILL to the process, but writes SIGKILL to the
exit_code. That does results in send_sig(SIGKILL) for processes
being stopped on a ptrace event only, but not even for all of
these events.
So I added an option to request_kill_ptraced_process() that
allows to force an additional os_kill_process() to be executed
before the os_kill_ptraced_process().
Summary: The behavior of 2.6.9 host is very uggly. You need to
do kill() and ptrace(PTRACE_KILL) to be shure, a process will
really exit. If the host is changed to be more consistent, we
should change all this again.

Signed-off-by: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
---

--- a/include/asm-um/processor-generic.h	2004-11-11 20:08:28.382687160 +0100
+++ b/include/asm-um/processor-generic.h	2004-11-11 20:09:09.167486928 +0100
@@ -54,7 +54,8 @@ struct thread_struct {
  		union {
  			struct {
  				int pid;
-			} fork, exec;
+				int mode;
+			} fork, exec, kill;
  			struct {
  				int (*proc)(void *);
  				void *arg;
--- a/arch/um/kernel/tt/include/mode-tt.h	2004-11-11 20:05:55.383946504 +0100
+++ b/arch/um/kernel/tt/include/mode-tt.h	2004-11-11 20:06:44.263515680 +0100
@@ -8,7 +8,7 @@

  #include "sysdep/ptrace.h"

-enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
+enum { OP_NONE, OP_EXEC, OP_FORK, OP_KILL, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };

  extern int tracing_pid;

--- a/arch/um/kernel/tt/exec_user.c	2004-11-11 19:43:38.511182056 +0100
+++ b/arch/um/kernel/tt/exec_user.c	2004-11-11 19:50:41.288910072 +0100
@@ -16,6 +16,7 @@
  #include "kern_util.h"
  #include "user.h"
  #include "ptrace_user.h"
+#include "os.h"

  void do_exec(int old_pid, int new_pid)
  {
@@ -36,7 +37,7 @@ void do_exec(int old_pid, int new_pid)
  		tracer_panic("do_exec failed to get registers - errno = %d",
  			     errno);

-	kill(old_pid, SIGKILL);
+	os_kill_ptraced_process(old_pid, 0);

  	if (ptrace(PTRACE_SETOPTIONS, new_pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
  		tracer_panic("do_exec: PTRACE_SETOPTIONS failed, errno = %d", errno);
--- a/arch/um/kernel/tt/process_kern.c	2004-11-11 20:03:15.852199016 +0100
+++ b/arch/um/kernel/tt/process_kern.c	2004-11-11 21:03:59.624261464 +0100
@@ -82,7 +82,7 @@ void *switch_to_tt(void *prev, void *nex
  	prev_sched = current->thread.prev_sched;
  	if((prev_sched->state == TASK_ZOMBIE) ||
  	   (prev_sched->state == TASK_DEAD))
-		os_kill_ptraced_process(prev_sched->thread.mode.tt.extern_pid, 1);
+		request_kill_ptraced_process( prev_sched->thread.mode.tt.extern_pid, 1);

  	/* This works around a nasty race with 'jail'.  If we are switching
  	 * between two threads of a threaded app and the incoming process
@@ -119,7 +119,7 @@ void release_thread_tt(struct task_struc
  	int pid = task->thread.mode.tt.extern_pid;

  	if(os_getpid() != pid)
-		os_kill_process(pid, 0);
+		request_kill_ptraced_process(pid, 0);
  }

  void exit_thread_tt(void)
@@ -330,10 +330,10 @@ void kill_off_processes_tt(void)
  	me = os_getpid();
          for_each_process(p){
  		if(p->thread.mode.tt.extern_pid != me)
-			os_kill_process(p->thread.mode.tt.extern_pid, 0);
+			request_kill_ptraced_process(p->thread.mode.tt.extern_pid, 2);
  	}
  	if(init_task.thread.mode.tt.extern_pid != me)
-		os_kill_process(init_task.thread.mode.tt.extern_pid, 0);
+		request_kill_ptraced_process(init_task.thread.mode.tt.extern_pid, 2);
  }

  void initial_thread_cb_tt(void (*proc)(void *), void *arg)
@@ -352,6 +352,20 @@ void initial_thread_cb_tt(void (*proc)(v
  	}
  }

+void request_kill_ptraced_process(int pid, int mode)
+{
+	/* The tracer has to do the kill, since killing must be
+	 * done with ptrace(PTRACE_KILL, pid), which is possible
+	 * from the father only! */
+	current->thread.request.op = OP_KILL;
+	current->thread.request.u.exec.pid = pid;
+	current->thread.request.u.exec.mode = mode;
+	os_usr1_process(os_getpid());
+	change_sig(SIGUSR1, 1);
+
+	change_sig(SIGUSR1, 0);
+}
+
  int do_proc_op(void *t, int proc_id)
  {
  	struct task_struct *task;
@@ -374,6 +388,12 @@ int do_proc_op(void *t, int proc_id)
  	case OP_FORK:
  		attach_process(thread->request.u.fork.pid);
  		break;
+	case OP_KILL:
+		if ( thread->request.u.kill.mode > 1 )
+			os_kill_process(thread->request.u.kill.pid, 0);
+		os_kill_ptraced_process(thread->request.u.kill.pid,
+		                        thread->request.u.kill.mode);
+		break;
  	case OP_CB:
  		(*thread->request.u.cb.proc)(thread->request.u.cb.arg);
  		break;
--- a/arch/um/kernel/tt/include/mode-tt.h	2004-11-12 12:14:24.239057776 +0100
+++ b/arch/um/kernel/tt/include/mode-tt.h	2004-11-12 12:15:17.496961344 +0100
@@ -20,6 +20,7 @@ extern void reboot_tt(void);
  extern void halt_tt(void);
  extern int is_tracer_winch(int pid, int fd, void *data);
  extern void kill_off_processes_tt(void);
+extern void request_kill_ptraced_process(int pid, int mode);

  #endif

--- a/arch/um/kernel/reboot.c	2004-11-12 12:18:29.356794216 +0100
+++ b/arch/um/kernel/reboot.c	2004-11-12 12:19:20.996943720 +0100
@@ -22,7 +22,7 @@ static void kill_idlers(int me)
  	for(i = 0; i < sizeof(idle_threads)/sizeof(idle_threads[0]); i++){
  		p = idle_threads[i];
  		if((p != NULL) && (p->thread.mode.tt.extern_pid != me))
-			os_kill_process(p->thread.mode.tt.extern_pid, 0);
+			request_kill_ptraced_process(p->thread.mode.tt.extern_pid, 2);
  	}
  #endif
  }


-------------------------------------------------------
This SF.Net email is sponsored by:
Sybase ASE Linux Express Edition - download now for FREE
LinuxWorld Reader's Choice Award Winner for best database on Linux.
http://ads.osdn.com/?ad_id=5588&alloc_id=12065&op=click
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

             reply	other threads:[~2004-11-12 14:46 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-11-12 14:46 Bodo Stroesser [this message]
2004-11-18  0:37 ` [uml-devel] [Patch 1/1] uml: fix uml-hang-on-2.6.9-host.patch Blaisorblade

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4194CCAD.2020701@fujitsu-siemens.com \
    --to=bstroesser@fujitsu-siemens.com \
    --cc=blaisorblade_spam@yahoo.it \
    --cc=jdike@addtoit.com \
    --cc=user-mode-linux-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox