| Index: build/install-chroot.sh
|
| diff --git a/build/install-chroot.sh b/build/install-chroot.sh
|
| index 155fc798b267237fad721a423b15a9e83c1b7f7e..f9e165ecac6c1d1dd51c47216511684c99e0cd4e 100755
|
| --- a/build/install-chroot.sh
|
| +++ b/build/install-chroot.sh
|
| @@ -497,26 +497,62 @@ while [ "$#" -ne 0 ]; do
|
| esac
|
| done
|
|
|
| +# Start a new chroot session and keep track of the session id. We inject this
|
| +# id into all processes that run inside the chroot. Unless they go out of their
|
| +# way to clear their environment, we can then later identify our child and
|
| +# grand-child processes by scanning their environment.
|
| session="$(schroot -c "${chroot}" -b)"
|
| +export CHROOT_SESSION_ID="${session}"
|
|
|
| if [ $# -eq 0 ]; then
|
| + # Run an interactive shell session
|
| schroot -c "${session}" -r -p
|
| else
|
| + # Run a command inside of the chroot environment
|
| p="$1"; shift
|
| schroot -c "${session}" -r -p "$p" -- "$@"
|
| fi
|
| rc=$?
|
|
|
| +# Compute the inode of the root directory inside of the chroot environment.
|
| i=$(schroot -c "${session}" -r -p ls -- -id /proc/self/root/. |
|
| awk '{ print $1 }') 2>/dev/null
|
| +other_pids=
|
| while [ -n "$i" ]; do
|
| - pids=$(ls -id1 /proc/*/root/. 2>/dev/null |
|
| + # Identify processes by the inode number of their root directory. Then
|
| + # remove all processes that we know belong to other sessions. We use
|
| + # "sort | uniq -u" to do what amounts to a "set substraction operation".
|
| + pids=$({ ls -id1 /proc/*/root/. 2>/dev/null |
|
| sed -e 's,^[^0-9]*'$i'.*/\([1-9][0-9]*\)/.*$,\1,
|
| t
|
| - d') >/dev/null 2>&1
|
| - [ -z "$pids" ] && break
|
| - kill -9 $pids
|
| + d';
|
| + echo "${other_pids}";
|
| + echo "${other_pids}"; } | sort | uniq -u) >/dev/null 2>&1
|
| + # Kill all processes that are still left running in the session. This is
|
| + # typically an assortment of daemon processes that were started
|
| + # automatically. They result in us being unable to tear down the session
|
| + # cleanly.
|
| + [ -z "${pids}" ] && break
|
| + for j in $pids; do
|
| + # Unfortunately, the way that schroot sets up sessions has the
|
| + # side-effect of being unable to tell one session apart from another.
|
| + # This can result in us attempting to kill processes in other sessions.
|
| + # We make a best-effort to avoid doing so.
|
| + k="$( ( xargs -0 -n1 </proc/$j/environ ) 2>/dev/null |
|
| + sed 's/^CHROOT_SESSION_ID=/x/;t1;d;:1;q')"
|
| + if [ -n "${k}" -a "${k#x}" != "${session}" ]; then
|
| + other_pids="${other_pids}
|
| +${j}"
|
| + continue
|
| + fi
|
| + kill -9 $pids
|
| + done
|
| done
|
| +# End the chroot session. This should clean up all temporary files. But if we
|
| +# earlier failed to terminate all (daemon) processes inside of the session,
|
| +# deleting the session could fail. When that happens, the user has to manually
|
| +# clean up the stale files by invoking us with "--clean" after having killed
|
| +# all running processes.
|
| schroot -c "${session}" -e
|
| exit $rc
|
| EOF
|
|
|