Commit b0d03750 authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds

[PATCH] uml: unregister signal handlers at reboot

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

In most cases reboot failed on my system.  After "Restarting system.", UML
exited without further messages.  I found an SIGIO being processed by
sig_handler() resp.  sig_handler_common_skas().  Don't know, why this exits,
maybe the context is no longer valid at this time.  So, I changed the sequence
in the reboot part of main() to stop the timers and disable the fds before
unblocking the signals.  Since this wasn't enough, I also added
set_handler(SIGXXX, SIG_IGN) calls to disable_timer() and
deactivate_all_fds().  Now reboot works fine in SKAS and it still works in TT.
Signed-off-by: default avatarBodo Stroesser <bstroesser@fujitsu-siemens.com>
Signed-off-by: default avatarJeff Dike <jdike@addtoit.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent a9417c6c
...@@ -377,6 +377,8 @@ int deactivate_all_fds(void) ...@@ -377,6 +377,8 @@ int deactivate_all_fds(void)
if(err) if(err)
return(err); return(err);
} }
/* If there is a signal already queued, after unblocking ignore it */
set_handler(SIGIO, SIG_IGN, 0, -1);
return(0); return(0);
} }
......
...@@ -155,18 +155,20 @@ int main(int argc, char **argv, char **envp) ...@@ -155,18 +155,20 @@ int main(int argc, char **argv, char **envp)
int err; int err;
printf("\n"); printf("\n");
/* stop timers and set SIG*ALRM to be ignored */
/* Let any pending signals fire, then disable them. This
* ensures that they won't be delivered after the exec, when
* they are definitely not expected.
*/
unblock_signals();
disable_timer(); disable_timer();
/* disable SIGIO for the fds and set SIGIO to be ignored */
err = deactivate_all_fds(); err = deactivate_all_fds();
if(err) if(err)
printf("deactivate_all_fds failed, errno = %d\n", printf("deactivate_all_fds failed, errno = %d\n",
-err); -err);
/* Let any pending signals fire now. This ensures
* that they won't be delivered after the exec, when
* they are definitely not expected.
*/
unblock_signals();
execvp(new_argv[0], new_argv); execvp(new_argv[0], new_argv);
perror("Failed to exec kernel"); perror("Failed to exec kernel");
ret = 1; ret = 1;
......
...@@ -60,6 +60,9 @@ void disable_timer(void) ...@@ -60,6 +60,9 @@ void disable_timer(void)
(setitimer(ITIMER_REAL, &disable, NULL) < 0)) (setitimer(ITIMER_REAL, &disable, NULL) < 0))
printk("disnable_timer - setitimer failed, errno = %d\n", printk("disnable_timer - setitimer failed, errno = %d\n",
errno); errno);
/* If there are signals already queued, after unblocking ignore them */
set_handler(SIGALRM, SIG_IGN, 0, -1);
set_handler(SIGVTALRM, SIG_IGN, 0, -1);
} }
void switch_timers(int to_real) void switch_timers(int to_real)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment