Bug#679499: [buildd-tools-devel] Bug#679499: schroot: suspend fails from chroot

2012-12-10 Thread Toby Speight
0 In article 20121014231616.gn5...@codelibre.net,
0 Roger Leigh URL:mailto:rle...@codelibre.net (Roger) wrote:

Roger This is quite an interesting problem, and will need a bit more
Roger investigation before I find a solution.

I fully expected that!  :-)

I have however just tried a bit of experimentation, which does basically
what you suggest here:

Roger I'll try trapping SIGCONT/SIGSTOP, and then raise the same signal
Roger on ourselves.  However, this could open a horrible can of worms,
Roger e.g. if you send SIGCONT to bash while schroot is stopped.

I've tried that scenario, and the child bash does continue okay when
given SIGCONT, and resuming schroot gets me back correctly.  Weird
things happen if the child exits when schroot is not in the foreground,
though - it seems that the parent (of schroot) is told to stop.  In
other words, if we do something like:

/
| ~$ schroot -d / -c child -u root
| /# suspend; exit
| 
| [1]+  Stopped schroot/schroot -d / -c child -u root
| ~$ bg
| [1]+ schroot/schroot -d / -c child -u root 
\

I get

/
| ~$ exit
| exit
\

without asking for it.  Since all my other tests are successful and I
don't know what causes the above, I present my patch below, in the hope
that someone can identify what's needed.  Admittedly, typing suspend;
exit (or even suspend; exec command) seems a fairly oddball case.

If I use 'fg' rather than 'bg', it works; also if I start schroot
backgrounded, with a command such as 'schroot -- sleep 3 ' or
'schroot -- bash -c sleep 3 '.

If I use 'schroot -- bash -i -c sleep 3 ', I get some strange
behaviour.  It stops itself, and if I immediately type 'fg' I get the
unasked-for exit (which can be prevented if you get bash to give
There are stopped jobs.  message, by having another background
process).  A second 'fg' gets in, and the sleep runs.  If I first
just press enter, the parent notices schroot stop, but I still need
to 'fg' twice to get in.

Here's the patch I've been trying:

diff -u -x '*~' schroot-1.6.4/sbuild/sbuild-session.cc schroot-new/sbuild/sbuild-session.cc
--- schroot-1.6.4/sbuild/sbuild-session.cc	2012-10-27 23:39:05.0 +0100
+++ schroot-new/sbuild/sbuild-session.cc	2012-12-10 18:54:56.421884095 +
@@ -1431,7 +1431,7 @@
 	  child_killed = true;
 	}
 
-  if (waitpid(pid, status, 0) == -1)
+  if (waitpid(pid, status, WUNTRACED) == -1)
 	{
 	  if (errno == EINTR  (sighup_called || sigterm_called || sigint_called))
 	continue; // Kill child and wait again.
@@ -1450,6 +1450,16 @@
 	}
   // No need to handle the SIGINT case here; it is handled
   // correctly below
+  else if (WIFSTOPPED(status))
+{
+  siginfo_t info;
+  int stopsig = WSTOPSIG(status); // one of SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU
+  raise(stopsig);
+  // time passes ... when we come back, attempt to wake the child
+  // (which may now be a zombie, but that's fine):
+  kill(pid, SIGCONT);
+  continue;
+}
   else
 	break;
 }


Bug#679499: [buildd-tools-devel] Bug#679499: schroot: suspend fails from chroot

2012-10-14 Thread Roger Leigh
On Fri, Jun 29, 2012 at 09:00:31AM +0100, Toby Speight wrote:
 If I use plain 'chroot' to access a working system, with
 SHELL=/bin/bash, I can type 'suspend' into bash, and get back to my
 parent shell.
 
 If I use 'schroot' to do the same, then 'suspend' just hangs until I
 go to another terminal and 'kill -CONT' the bash process.
 
 I would like schroot to behave the same as plain chroot.  I appreciate
 it might not be trivial (chroot doesn't have to do anything special, as
 it simply exec()s the required command, whereas schroot would have to
 detect its child stopping and do the same to itself - I've no idea how
 to do that).

This is quite an interesting problem, and will need a bit more
investigation before I find a solution.

bash sets up its own process group on startup.  When you call
suspend, it signals the whole process group to stop.  But since
schroot isn't in the same group, it's not suspended.  Ideally,
you would only run a login shell with schroot, but we're not in
an ideal world ;)

schroot uses PAM, and basically treats commands being run in the
chroot as though they were run as a separate login, e.g. equivalent
to running ssh or sudo.  That said, it should be possible to do this.

schroot itself isn't doing anything special by starting any new
sessions with setsid or setpgid, and itself works perfectly well
with job control.  Try running any command other than a shell
(e.g. more or anything you like, or run schroot as part of a
pipeline e.g. schroot ls -l / | less) and you'll see that it
all works fine in that you can press C-Z and it all suspends
properly.

So to support suspending a shell within ourselves, I'm not sure what
is best to do here.  I'll try trapping SIGCONT/SIGSTOP, and then
raise the same signal on ourselves.  However, this could open a
horrible can of worms, e.g. if you send SIGCONT to bash while
schroot is stopped.  We won't be restarted ourselves then, and
bash might then immediately get SIGTTOU/IN etc.  I also don't want
to break schroot running correctly in the normal/pipeline cases
shown above.


Regards,
Roger

-- 
  .''`.  Roger Leigh
 : :' :  Debian GNU/Linux http://people.debian.org/~rleigh/
 `. `'   Printing on GNU/Linux?   http://gutenprint.sourceforge.net/
   `-GPG Public Key: 0x25BFB848   Please GPG sign your mail.


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org