Use separate pid namespace for worker processes

As described in 2be79c6 ("run the chroot in a new PID namespace"), child
processes can hang around and keep various files open. This may prevent
filesystems from being unmounted (as they are still in-use).

When adding unshare mode, I did not quite understand this distinction
(and I wasn't testing with e.g. gnupg) so I didn't catch this. Fix this
by always using unshare to create a second pid namespace for "worker"
processes. This ensures that all children are dead when we start
unmounting things. As the top-level unshare is no longer always
necessary, convert the unshare variable to a binary value.

Fixes: ee9db7d ("Add unshare mode to pacstrap")
Closes: #21
This commit is contained in:
Sean Anderson 2022-07-28 10:02:31 -04:00
parent 8a56133926
commit 58ff428757
3 changed files with 18 additions and 10 deletions

View File

@ -5,7 +5,7 @@ shopt -s extglob
m4_include(common)
setup=chroot_setup
unshare="$root_unshare"
unshare=0
usage() {
cat <<EOF
@ -82,7 +82,7 @@ while getopts ':hNu:' flag; do
;;
N)
setup=unshare_setup
unshare="$user_unshare"
unshare=1
;;
u)
userspec=$OPTARG
@ -116,8 +116,12 @@ arch-chroot() {
chroot_args=()
[[ $userspec ]] && chroot_args+=(--userspec "$userspec")
SHELL=/bin/bash chroot "${chroot_args[@]}" -- "$chrootdir" "${args[@]}"
SHELL=/bin/bash $pid_unshare chroot "${chroot_args[@]}" -- "$chrootdir" "${args[@]}"
}
args=("$@")
$unshare bash -c "$(declare_all); arch-chroot"
if (( unshare )); then
$mount_unshare bash -c "$(declare_all); arch-chroot"
else
arch-chroot
fi

4
common
View File

@ -152,8 +152,8 @@ unshare_teardown() {
unset CHROOT_ACTIVE_FILES
}
root_unshare="unshare --fork --pid"
user_unshare="$root_unshare --mount --map-auto --map-root-user --setuid 0 --setgid 0"
pid_unshare="unshare --fork --pid"
mount_unshare="$pid_unshare --mount --map-auto --map-root-user --setuid 0 --setgid 0"
# This outputs code for declaring all variables to stdout. For example, if
# FOO=BAR, then running

View File

@ -17,7 +17,7 @@ copykeyring=1
copymirrorlist=1
pacmode=-Sy
setup=chroot_setup
unshare="$root_unshare"
unshare=0
usage() {
cat <<EOF
@ -67,7 +67,7 @@ while getopts ':C:cdGiMNU' flag; do
;;
N)
setup=unshare_setup
unshare="$user_unshare"
unshare=1
;;
U)
pacmode=-U
@ -120,7 +120,7 @@ pacstrap() {
fi
msg 'Installing packages to %s' "$newroot"
if ! pacman -r "$newroot" $pacmode "${pacman_args[@]}"; then
if ! $pid_unshare pacman -r "$newroot" $pacmode "${pacman_args[@]}"; then
die 'Failed to install packages to new root'
fi
@ -130,6 +130,10 @@ pacstrap() {
fi
}
$unshare bash -c "$(declare_all); pacstrap"
if (( unshare )); then
$mount_unshare bash -c "$(declare_all); pacstrap"
else
pacstrap
fi
# vim: et ts=2 sw=2 ft=sh: