Skip to content

Instantly share code, notes, and snippets.

@logarytm
Last active August 11, 2018 19:52
Show Gist options
  • Save logarytm/26d11d9476757fe43a82959f5bc341b5 to your computer and use it in GitHub Desktop.
Save logarytm/26d11d9476757fe43a82959f5bc341b5 to your computer and use it in GitHub Desktop.
sanity preserving chroot(1)
#!/bin/sh
# sane_chroot: sanity-preserving chroot(1)
set -e
finish() {
prefix="$(realpath "$prefix")"
if [ "x$(unlock)" != "x0" ]; then
return 0
else
echo "Shutting down..."
fi
found=1
while [ "x$found" = "x1" ]; do
found=0
for pid in $(ls -1 /proc); do
link=$(readlink /proc/$pid/root || true)
if [ "x$link" != "x" ]; then
if [ "x${link:0:${#prefix}}" == "x$prefix" ]; then
kill -9 $pid && echo "Killed process $pid" || true
found=1
fi
fi
done
done
umount -v -l "$prefix"/tmp/.X11-unix || true
umount -v -l "$prefix"/dev || true
umount -v -l "$prefix"/proc || true
umount -v -l "$prefix"/sys || true
rm -v "$lockfile"
}
lock() {
local count
count="$(cat "$lockfile" 2>/dev/null || echo 0)"
echo $(expr "$count" + 1) > "$lockfile"
}
unlock() {
local count
count="$(cat "$lockfile")"
echo $(expr "$count" - 1) | tee "$lockfile"
}
prefix="$1"
lockfile="$1/.chroot_lock"
shift
if [ "x" = "x$prefix" ] || ! [ -d "$prefix" ]; then
printf "error: invalid chroot directory\n" >&2
exit 1
fi
if [ $# = 0 ]; then
printf "error: at least two arguments required" >&2
fi
trap finish EXIT
lock
mkdir -p "$prefix/tmp/.X11-unix"
ln -sfv /tmp/.X11-unix "$prefix"/tmp/.X11-unix || echo "warning: X11 will not be available" >&2
mount -v -t devtmpfs devtmpfs "$prefix"/dev || true
mount -v --rbind /dev/pts "$prefix"/dev/pts || true
mount -v -t proc proc "$prefix"/proc || true
mount -v -t sysfs sysfs "$prefix"/sys || true
chroot "$prefix" "$@" || exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment