severity 608054 serious
tags 608054 + patch fixed-upstream pending
thanks

On Wed, Dec 29, 2010 at 05:22:58PM +0100, Julien Cristau wrote:
> On Wed, Dec 29, 2010 at 16:08:48 +0000, Roger Leigh wrote:
> 
> > On Sun, Dec 26, 2010 at 07:14:54PM +0100, Julien Cristau wrote:
> > I assume this is due to the 15killprocs setup script?  If you
> > add an "exit 0" to the top of this script, does it still occur?
> > 
> exit 0 at the top of 15killprocs fixes it.
> 
> > To better understand what's going on here, I really need some more
> > information about why this is happening, i.e. which commands you
> > run in each terminal and when.
> > 
> xterm 1:                xterm 2:
> schroot
>                         schroot
>                         ^d
> ^d
> 
> schroot in xterm 2 stays suspended until I exit the chroot from xterm 1,
> or, if I don't do that quickly enough, xterm 1 gets:
> [1]+  Stopped                 schroot
> $ fg
> schroot
> E: Child terminated by signal 'Killed'
> $
> 
> > Note that if you're running commands in the /same session/ on both
> > then ending the session will naturally kill all running processes
> > in that session; this is intended and expected.  If you're running
> > commands in /separate sessions/ and ending one kills the other,
> > then this is most certainly a major bug.
> > 
> They're separate sessions, sorry.

I believe this is now fixed; I've attached a new copy of the 15killprocs
setup script, and this is also on the schroot-1.4 (unstable/squeeze) and
master branches in git.  If you could test it to confirm it's behaving
correctly, that would be great.

This was due to 3762a30f committed in early December.  This was intended
to speed up session ending on large and heavily-loaded systems by
replacing a readlink(1) invocation for each process on the system with
"test -ef" to compare the device/inode directly.  While this is much
faster, there's a downside: the device/inode doesn't /uniquely/
identify a chroot, at least when not using cloned chroots (which are
unique).  If you're using the directory chroot type, each session
bind mounts the same directory, so ending a session causes processes
in all sessions based on the same chroot to killed.

The solution I've chosen is to retain the "test -ef" check for
efficiency, but then to additionally do the readlink(1) check if the
test is positive.  This should fix the problem properly, and still
retain the performance improvement for most system workloads.

Anders, I've just CCd you to be sure you're aware of this issue with
your patch in case it's going to cause you problems on any systems
you've deployed it on.


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.
#!/bin/sh
# Copyright © 2007       Kees Cook <k...@outflux.net>
# Copyright © 2007-2009  Roger Leigh <rle...@debian.org>
#
# schroot is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# schroot is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see
# <http://www.gnu.org/licenses/>.
#
#####################################################################

set -e

. "$SETUP_DATA_DIR/common-data"
. "$SETUP_DATA_DIR/common-functions"

if [ -f "$CHROOT_SCRIPT_CONFIG" ]; then
    . "$CHROOT_SCRIPT_CONFIG"
elif [ "$STATUS" = "ok" ]; then
    fatal "script-config file '$CHROOT_SCRIPT_CONFIG' does not exist"
fi

# Kill all processes that were run from within the chroot environment
# $1: mount base location
do_kill_all()
{
    if [ -z "$1" ]; then
        fatal "No path for finding stray processes: not reaping processes in 
chroot"
    fi

    info "Killing processes run inside $1"
    ls /proc | egrep '^[[:digit:]]+$' |
    while read pid; do
        # Check if process root are the same device/inode as chroot
        # root (for efficiency)
        if [ /proc/"$pid"/root -ef "$1" ]; then
            # Check if process and chroot root are the same (may be
            # different even if device/inode match).
            root=$(readlink /proc/"$pid"/root || true)
            if [ "$root" = "$1" ]; then
                exe=$(readlink /proc/"$pid"/exe || true)
                info "Killing left-over pid $pid (${exe##$1})"
                info "  Sending SIGTERM to pid $pid"

                /bin/kill -TERM "$pid" 2>/dev/null

                count=0
                max=5
                while [ -d /proc/"$pid" ]; do
                    count=$(( $count + 1 ))
                    info "  Waiting for pid $pid to shut down... ($count/$max)"
                    sleep 1
                # Wait for $max seconds for process to die before -9'ing it
                    if [ "$count" -eq "$max" ]; then
                        info "  Sending SIGKILL to pid $pid"
                        /bin/kill -KILL "$pid" 2>/dev/null
                        sleep 1
                        break
                    fi
                done
            fi
        fi
    done
}

if [ $STAGE = "setup-recover" ] || [ $STAGE = "setup-stop" ]; then
    do_kill_all "$CHROOT_MOUNT_LOCATION"
fi

Attachment: signature.asc
Description: Digital signature

Reply via email to