#!/bin/bash set -x arch=aarch64 rootpath=/home/jejb/containers ctrl=/run/build-container if [ ! -v userns ]; then export userns=0 fi if [ $(id -u) -ne 0 ]; then unshare --user sleep 180 & userpid=$!; sudo $0 --userid $(id -u) --groupid $(id -g) --userpid $userpid "$@" exit 0; fi while true; do case $1 in --arch) arch=$2; shift; shift ;; --rootpath) rootpath=$2; shift; shift ;; --mountshift) userns=1; shift ;; --userid) uid=$2; shift; shift ;; --groupid) gid=$2; shift; shift ;; --userpid) userpid=/proc/$2; shift; shift ;; *) break;; esac done ctroot=$rootpath/$arch root=$ctrl/root-$arch usernspath=$ctrl/userns if [ "$1" == "in-ct" ]; then if [ $userns -eq 1 ]; then /home/jejb/git/bindfs/src/bindfs --map=0/10000:1/10001:2/10002:3/10003:4/10004:5/10005:6/10006:7/10007:8/10008:@0/@10000:@1/@10001 $ctroot $root else mount --bind $ctroot $root fi mkdir $root$ctrl mount -t proc none $root/proc mount -t sysfs none $root/sys for f in /home /var/tmp; do mount --bind $f ${root}${f} mount --make-rprivate ${root}${f} done #mount --bind /usr/bin/qemu-$arch $root/qemu-$arch cd $root mkdir old-root pivot_root . old-root elif [ "$1" == "in-ct-user" ]; then mount --make-rprivate /old-root umount -l /old-root rmdir /old-root else if [ -e $ctrl/$arch ]; then echo "Error: $ctrl/$arch exists, is container running?" exit 1; fi if [ ! -d $ctrl ]; then mkdir $ctrl || exit 1 fi if grep -q "$ctrl tmpfs" /proc/self/mounts; then : else mount -t tmpfs none $ctrl || exit 1 fi if [ ! -e $usernspath ]; then touch $usernspath # userns are annoying. the maps must be written all at once and # shell echo won't, so we trick awk into doing it echo 1| awk "{print \"0 100000 1000\n${uid} ${uid} 1\n65534 65534 2\"}" > $userpid/uid_map if [ $gid -le 1000 ]; then gidn=$[$gid + 1] gide=$[10000-$gidn] echo 1| awk "{print \"0 100000 ${gid}\n${gid} ${gid} 1\n${gidn} 100${gidn} ${gide}\n65533 65533 3\"}" > $userpid/gid_map else echo 1| awk "{print \"0 100000 1000\n${gid} ${gid} 1\n65533 65533 3\"}" > $userpid/gid_map fi mount --bind $userpid/ns/user $usernspath fi mkdir $root touch $ctrl/$arch # create the mount ns with owning user ns nsenter --user=$usernspath unshare --mount sleep 10 & # timing problem here: need to allow nsenter time to begin executing sleep 1 # can only mount on private propagation mount points mount --make-rprivate $ctrl mount --bind /proc/$!/ns/mnt $ctrl/$arch # enter the mount ns with true root, not the user ns nsenter --mount=$ctrl/$arch $0 --arch $arch --rootpath $rootpath in-ct nsenter --mount=$ctrl/$arch --user=$ctrl/userns $0 --arch $arch --rootpath $rootpath in-ct-user rmdir $root fi