#!/bin/bash #-t --tmpfs path to temporary save file #-r --root Parent directory to the new rootfs. Only applied to options which are to the right of this option. #-f --fake-root This is the location where the fake (or new) rootfs will be mounted. #-n --new-root See: -f --fake-root # This is a subdirectory of the -r|--root option when the -r --root option is applied to the left of this argument unset SANDBOX_ID unset rwbranch unset FAKEROOT unset SANDBOX_TMPF unset FAKEROOT_dir unset SANDBOX_IMG #SANDBOX_ROOT=/mnt/sb unset SANDBOX_ROOT # [ -z "$TMPFILE" ] && TMPFILE=$(mktemp -p /tmp) TMPFILE=$(mktemp -p /tmp) trap 'umountall' 1 function log(){ local logfile="${2}" local trace="$3" #[ -z "$logfile" ] && LOGFILE #[ -z "$trace" ] && trace=TRACE if [ ! -z "$LOGFILE" ]; then case "$1" in init) [ "$TRACE" = true ] && set -x [ ! -z "$LOGFILE" ] && rm "$LOGFILE" exec 6>&1 # Link file descriptor #6 with stdout. #exec &1> >(tee -a "$LOGFILE") #exec &2> >(tee -a "$LOGFILE") exec &> >(tee -a "$LOGFILE") ;; start) [ "$TRACE" = true ] && set -x #exec &1> >(tee -a "$LOGFILE") #exec &2> >(tee -a "$LOGFILE") exec &> >(tee -a "$LOGFILE") ;; stop) #https://stackoverflow.com/questions/21106465/restoring-stdout-and-stderr-to-default-value [ "$TRACE" = true ] && set +x exec 1>&6 #See https://tldp.org/LDP/abs/html/x17974.html #exec 6>&- # Restore stdout and close file descriptor #6. exec &2> /dev/stderr ;; esac fi } declare -A del_rulles_filter declare -A del_rulles_action declare -A umount_rules_filter declare -A umount_rules_action safe_del(){ unset safe_del_result POLICY="" #Default action if no rule is found if [ ! -z "$(cat /proc/mounts | grep -F "$(ls -1d $1 | sed 's:/$::')" - )" ] || [ ! -z "$(cat /proc/mounts | grep -F "$(ls -1d $1 | xargs realpath )" - )" ] ; then #It is not safe to delete a mounted directory safe_del_result=1 #This is in case one doesn't want to use the return status right away return 1 else for a_rule_key in "${!del_rulles_filter[@]}"; do rule_i="${a_rull_key[$a_rule_key]}" if [ ! -z "$(echo $1 | grep "$rule_i")" ]; then action="${del_rulles_action[$a_rule_key}" case $action in DELETE) safe_del_result=0 #This is in case one doesn't want to use the return status right away return 0 break #This is probably redundant ;; KEEP) safe_del_result=1 #This is in case one doesn't want to use the return status right away return 1 break #This is probably redundant ;; POLICY_KEEP) POLICY=KEEP ;; POLICY_DELETE) POLICY=DELETE ;; esac fi done if [ -z ${safe_del_result+x} ]; then #If we don't have a result yet set result based on policy case "$POLICY" in KEEP) safe_delete_result=1 return 1; ;; DELETE) safe_delete_result=0 return 0; ;; *) echo "No Delete policy set, so keeping file/dir $1" safe_delete_result=1 return 1 esac fi fi } safe_umount(){ unset safe_umount_result POLICY="" #Default action if no rule is found for a_rule_key in "${!umount_rules_filter[@]}"; do rule_i="${a_rull_key[$a_rule_key]}" if [ ! -z "$(echo $1 | grep "$rule_i")" ]; then action="${umount_rulles_action[$a_rule_key}" case $action in DELETE) safe_umount_result=0 #This is in case one doesn't want to use the return status right away return 0 break #This is probably redundant ;; UMOUNT) safe_umount_result=1 #This is in case one doesn't want to use the return status right away return 1 break #This is probably redundant ;; POLICY_KEEP) POLICY=KEEP ;; POLICY_UMOUNT) POLICY=UMOUNT ;; esac fi done if [ -z ${safe_umount_result+x} ]; then #If we don't have a result yet set result based on policy case "$POLICY" in KEEP) safe_umount_result=1 return 1; ;; UMOUNT) safe_umount_result=0 return 0; ;; *) echo "No Delete policy set, so keeping file/dir $1" safe_umount_result=1 return 1 esac fi } umountall() { { log start #R_FR=$(realpath -m "$FAKEROOT") #[ ${#R_FR} -lt 2 ] && exit safe_umount $FAKEROOT/$SANDBOX_TMPFS [ $safe_umount_result -eq 0 ] && umount -l $FAKEROOT/$SANDBOX_TMPFS if [ PUPMODE = 2 ]; then #Full Install safe_umount $FAKEROOT/$SANDBOX_TMPFS umount -l $FAKEROOT/tmp else safe_umount $FAKEROOT/$SANDBOX_TMPFS [ $safe_umount_result -eq 0 ] && umount -l $FAKEROOT/initrd/mnt/tmpfs fi for layer_name in "pup_ro2" "pup_ro3" "pup_ro4" "pup_ro5" "pup_z"; do layer="$(eval 'echo $'$layer_name)" if [ ! -z "$layer" ] ; then safe_umount "$FAKEROOT/initrd/$layer_name" [ $safe_umount_result -eq 0 ] && umount -l "$FAKEROOT/initrd/$layer_name" fi done for aFolder in /proc /sys /dev ""; do safe_umount $FAKEROOT"/$aFolder" [ $safe_umount_result -eq 0 ] && umount -l $FAKEROOT$aFolder done if [ -z "$RW_LAYER" ]; then safe_umount "$SANDBOX_TMPFS" [ $safe_umount_result -eq 0 ] && umount -l $SANDBOX_TMPFS safe_delete "$SANDBOX_TMPFS" [ $safe_delete_result -eq 0 ] && rmdir $SANDBOX_TMPFS fi safe_delete $FAKEROOT [ $safe_delete_result -eq 0 ] && rmdir $FAKEROOT } # 2> /dev/null } function choose_save(){ # location not specified - then ask log stop dialog --backtitle "rw image sandbox" --title "choose rw image" \ --extra-button --extra-label "Create" --ok-label "Locate" \ --yesno "You didn't specify the location of the rw image file. Do you want to locate existing file, or do you want to create a new one?" 0 0 chosen=$? log start case $chosen in 0) # ok - locate log stop dialog --backtitle "rw image sandbox" --title "Specify location of existing rw image" --fselect `pwd` 8 60 2> $TMPFILE savebranch=`cat $TMPFILE` log start rm $TMPFILE if [ -n "$savebranch" ]; then if [ -d "$savebranch" ]; then SANDBOX_IMG=$savebranch elif [ ! -f "$savebranch" ]; then echo "$savebranch doesn't exist - exiting." exit fi else echo "You didn't specify any file or you pressed cancel. Exiting." exit fi ;; 3) # create echo "create" log stop dialog --backtitle "save image sandbox" --title "Specify name and path of new the file" --fselect `pwd` 8 60 2> $TMPFILE savebranch=`cat $TMPFILE` log start rm $TMPFILE if [ -n "$savebranch" ]; then if [ -f "$savebranch" ]; then echo "$savebranch already exist - exiting." exit else # get the size log stop dialog --title "Create new save image" --inputbox "Specify size (in megabytes)" 0 40 100 2> $TMPFILE size=`cat $TMPFILE` log start rm $TMPFILE if [ -n "$size" ]; then if dd if=/dev/zero of="$savebranch" bs=1 count=0 seek="$size"M; then if ! mke2fs -F "$savebranch"; then echo "I fail to make an ext2 filesystem at $savebranch, exiting." exit fi else echo "I fail to create a ${size}M file at $savebranch,, exiting." exit fi else echo "You didn't specify the size or your press cancel. Exiting." exit fi fi else echo "You didn't specify any file or you pressed cancel. Exiting." exit fi ;; 1 | 255) # 1 is cancel, 255 is Escape ;& *) # invalid input - treat as cancel echo "Cancelled - exiting." exit ;; esac } function find_save(){ if [ ! -z "SANDBOX_IMG" ]; then FULL_SAVE_PATH=$SANDBOX_IMG else for prefix in '${DISTRO_FILE_PREFIX}save' '.*save'; do for dir in "$PDRV/${PSUBDIR}" "PDRV"; do ONE_SAVE="$(ls $dir -1 | grep -m "${prefix}save")" if [ -z "$ONE_SAVE" ]; then continue else SAVE_FILE="$ONE_SAVE" FULL_SAVE_PATH="$dir"/ONE_SAVE break fi done done echo "PSAVE"mount_items fi } function find_bk_folders(){ for a_PDRV in "$PDRV" sr0 sr1; do #Consider adding /mnt/home here for a_psubdir in "${PSUBDIR}" ""; do MT_PT_of_Folder="$(mount_fn2 "$PDRV" "${PSUBDIR}")" #https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L981 BKFOLDERS="$(find $MT_PT_of_Folder -maxdepth 1 -xdev -type d -name '20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]' | sed -e s%^${SAVE_MP}/%% | sort -r)" [ ! -z "#BKFOLDERS" ] && break done done } function mk_initrd_dir(){ mkdir -p "$FAKEROOT"/initrd if [ -z "$PUPMODE" ] ; then if [ -z "$PMEDIA" ]; then #if [ "$PUPMODE" = 5 ] ; then # #aufs layers: RW (top) RO1 RO2 PUPMODE # #First boot (or pfix=ram): tmpfs pup_xxx.sfs 5 PUPMODE=5 #MAYBE PUPMODE=2 would be better elif [ PMEDIA = 'atahd' ] || [ "$PMEDIA" = 'usbhd' ]; then find_save if [ -f "$FULL_SAVE_PATH" ] || [ -d "$FULL_SAVE_PATH" ]; then #aufs layers: RW (top) RO1 RO2 PUPMODE #Normal running puppy: pup_save.3fs pup_xxx.sfs 12 PUPMODE=12 else echo "Invalid SAVE_PATH=$SAVE_PATH does not exist" PUMPMODE=2 #TODO, prompt to either search for save file/folder or alternatively create it. fi elif [ PMEDIA = 'usbflash' ] || [ pmedia = 'ideflash' ]; then find_save #aufs layers: RW (top) RO1 RO2 PUPMODE #ditto, but flash drive: tmpfs pup_save.3fs pup_xxx.sfs 13 if [ -f "$SAVE_PATH" ] || [ -d "$SAVE_PATH" ]; then #aufs layers: RW (top) RO1 RO2 PUPMODE #ditto, but flash drive: tmpfs pup_save.3fs pup_xxx.sfs 13 PUPMODE=13 else echo "Invalid SAVE_PATH=$SAVE_PATH does not exist" PUPMODE=5 fi elif [ "$PMEDIA" = usbcd ] || [ "$PMEDIA" = idecd ] || [ "$PMEDIA" = satacd ] ; then find_bk_folders if [ ! -z "$BKFOLDERS" ]; then PUPMODE=77 #MULTI-Session CD else #First Boot find_save if [ -f "$FULL_SAVE_PATH" ] || [ -d "$FULL_SAVE_PATH" ]; then PUPMODE=13 else PUPMODE=5 fi fi #aufs layers: RW (top) RO1 RO2 PUPMODE #Multisession cd/dvd: tmpfs folders pup_xxx.sfs 77 else #[PUPMODE=2 -> full install PUPMODE=2 fi if [ "$PUPMODE" = 2 ]; then #Full install echo "Full install has no initrd" else mkdir -p "$FAKEROOT/initrd" cd $FAKEROOT/initrd if [ "$PUPMODE" = 12 ]; then # Usually [ PMEDIA = 'atahd' ] || [ "$PMEDIA" = usbhd ] ln -s mnt/dev_save/"${SAVE_PATH}" pup_rw elif [ "$PUPMODE" = 13 ] || [ "$PUPMODE" = 5 ] || [ "$PUPMODE" = 77 ]; then ln -s mnt/tmpfs/pup_rw pup_rw if [ "$PUPMODE" = 13 ]; then # Usually [ PMEDIA = 'usbflash' ] || [ pmedia = 'ideflash' ] ln -s "mnt/tmpfs/dev_save/${SAVE_PATH}" pup_ro1 elif [ "$PUPMODE" = 77 ]; then ln -s mnt/tmpfs/pup_ro1/"${SAVE_PATH}" pup_ro1 #Usually [ "$PMEDIA" = usbcd ] || [ "$PMEDIA" = idecd ] || [ "$PMEDIA" = satacd ] fi fi fi fi } function set_fakeroot(){ unset CLEANUP_SANDBOX_ROOT if [ ! -z ${FAKEROOT+x} ] || [ ! -z ${SANDBOX_ROOT+x} ]; then [ ! -z ${FAKEROOT+x} ] && [ -z "${fakeroot}" ] && FAKEROOT=fakeroot if [ ! -z ${SANDBOX_ROOT+x} ] && [ -z "${fakeroot}" ]; then SANDBOX_ROOT=/mnt/sb CLEANUP_SANDBOX_ROOT=yes fi [ ${#SANDBOX_ROOT} -gt 1 ] && FAKEROOT=$SANDBOX_ROOT/$FAKEROOT FAKEROOT_dir="${FAKEROOT%/*}" [ -z "${SANDBOX_ROOT}" ] && SANDBOX_ROOT=${FAKEROOT_dir} if grep -q $FAKEROOT /proc/mounts; then if [ ! "$SANDBOX_ROOT" = /mnt/sb ]; then log stop dialog --backtitle "rename root" --title "choose rw image" \ --extra-button --extra-label "Rename" --ok-label "Keep" \ --yesno "You didn't specify the location of the rw image file. Do you want to locate existing file, or do you want to create a new one?" 0 0 chosen=$? log start case "#chosen" in 1) RENAME_ROOT=yes; ;; 0) RENAME_ROOT=no; ;; esac else RENAME_ROOT=yes fi if [ "${RENAME_ROOT}" = yes ]; then FAKEROOT=$(mktemp -d -p ${FAKEROOT%/*}/ ${FAKEROOT##*/}.XXXXXXX) SANDBOX_ID=".${FAKEROOT##*.}" if [ -z "$SANDBOX_IMG" ]; then if grep -q $SANDBOX_IMG /proc/mounts; then SANDBOX_IMG=$FAKEROOT_dir/${SANDBOX_IMG##*/}${SANDBOX_ID} fi fi rmdir $FAKEROOT else log stop echo "Warning chose to remount over existing mount! $FAKEROOT" echo "ctrl-c to quote" read -p "Press enter to continue" log start fi fi else echo "Warning sandbox root not defined" #[ -z "$FAKEROOT" ] && FAKEROOT=/ fi if [ $CLEANUP_SANDBOX_ROOT = yes ]; then if [ ${#del_rules_filter} -eq 0 ]; then del_rules_filter+=( $SANDBOX_ROOT"/*" ) del_rules_filter+=( POLICY_DELETE ) fi if [ ${#umount_rules_filter} -eq 0 ]; then umount_rules_filter+=( $SANDBOX_ROOT"/*" ) umount_rules_filter+=( POLICY_UMOUNT ) fi fi } function set_sandbox_img(){ [ ! -z ${FAKEROOT+x} ] && FAKEROOT_dir="" [ -z ${FAKEROOT_dir+x} ] && set_fakeroot if [ ! -z ${SANDBOX_IMG+x} ] && [ -z "${SANDBOX_IMG}" ]; then SANDBOX_IMG=sandbox_img SANDBOX_IMG=${SANDBOX_IMG}${SANDBOX_ID} [ -z "$FAKEROOT_dir" ] && SANDBOX_IMG=$FAKEROOT_dir/$SANDBOX_IMG elif [ -z "${FAKEROOT_dir}" ] ; then SANDBOX_IMG=$FAKEROOT_dir/$SANDBOX_IMG fi } function set_sandbox_tmpfs(){ [ ! -z ${FAKEROOT+x} ] && FAKEROOT_dir="" [ -z ${FAKEROOT_dir+x} ] && set_fakeroot if [ ! -z ${SANDBOX_TMPFS+x} ] && [ -z "${SANDBOX_TMPFS}" ]; then SANDBOX_TMPF=sandbox_tmpfs SANDBOX_TMPF=${SANDBOX_TMPF}${SANDBOX_ID} [ -z "$FAKEROOT_dir" ] && SANDBOX_TMPF=$FAKEROOT_dir/$SANDBOX_TMPF elif [ -z "${FAKEROOT_dir}" ] ; then SANDBOX_TMPF=$FAKEROOT_dir/$SANDBOX_TMPF fi } declare -a options="$(getopt -o t::,r::,s:,d:,l: --long input-file:tmpfs::,root::,save:,pupmode::,pmedia:,pdrv:,psubdir:,distro-specs:,logfile:,trace: -- "$@")" eval set --"$options" while [ $# -gt 0 ]; do case "$1" in -t|--tmpfs) if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then SANDBOX_TMPFS="$2" set_sandbox_tmpfs shift 2 else SANDBOX_TMPF="" #Later we use [ -z ${SANDBOX_TMPF+x} ] to check that this is set set_sandbox_tmpfs shift 1 fi; ;; -r|--root) if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then SANDBOX_ROOT="$2" shift 2 else SANDBOX_ROOT="" #Later we use [ -z ${SANDBOX_ROOT+x} ] to check that this is set shift 1 fi; ;; -f|-n|--fake-root|--new-root) if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then FAKEROOT="$2" set_fakeroot shift 2 else FAKEROOT="" #Later we use [ -z ${FAKEROOT+x} ] to check that this is set set_fakeroot shift 1 fi; ;; -s|--save) #$SANDBOX_IMG #if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then if [ -d "$2" ]; then SANDBOX_IMG=$2 savebranch=$2 else [ -f "$2" ] #mnt_sb_immage #mount -o loop "$rwbranch" $SANDBOX_IMG; savebranch=$1 loop=$(losetup-FULL -a | grep "$savebranch" | sed "s/:.*$//") if [ ! -z "$loop" ]; then SANDBOX_IMG=$(/proc/mounts | grep $loop | cut -d " " -f2) else SANDBOX_IMG="" set_sandbox_img fi shift 2; fi; ;; --pupmode) if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then PUPMODE=$2 shift 2 else PUPMODE=2 shift fi ;; --pmedia) PMEDIA=$2; shift 2; ;; -d| --pdrv) PDRV=$2; shift 2; ;; --psubdir) PSUBDIR=$2; shift 2; ;; --distro-specs) DISTRO_SPECS=$2; . "$DISTRO_SPECS" shift 2 ;; -l|--logfile) LOGFILE=$2 [ -z "$TRACE" ] && TRACE=true shift 2 log init ;; -t|--trace) TRACE=$2 if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then TRACE="$2" shift 2 else TRACE=true shift 1 fi log init ;; --) shift 1 options2+=( "$@" ) break; ;; *) options2+=( "$1" ) shift 1; ;; esac done #SANDBOX_TMPFS=$SANDBOX_ROOT/sandbox # mounted rw location of #SANDBOX_TMPFS=$SANDBOX_ROOT/initrd/mnt/tmpfs/pup_rw #tmpfs used for sandbox #SANDBOX_ID= TMPFILE=$(mktemp -p /tmp) # use namespaces if available #[ -e /proc/1/ns/pid ] && [ -e /proc/1/ns/mnt ] && type unshare >/dev/null && USE_NS=1 # umount all if we are accidentally killed #trap 'umountall' 1 #s243a don't unmount on error # 0.1 must be root if [ $(id -u) -ne 0 ]; then echo "You must be root to use sandbox." exit fi ## 0.2 cannot launch sandbox within sandbox #if [ "$AUFS_ROOT_ID" != "" ] ; then # grep -q $SANDBOX_ROOT /sys/fs/aufs/$AUFS_ROOT_ID/br0 && # echo "Cannot launch sandbox within sandbox." && exit #fi # s243a we are remounting everything rather then creating a sandbox. # 0.3 help case "$1" in --help|-h) echo "Usage: ${0##*/}" echo "Starts an in-memory (throwaway) sandbox. Type 'exit' to leave." exit esac ## 0.4 if not running from terminal but in Xorg, then launch via terminal #! [ -t 0 ] && [ -n "$DISPLAY" ] && exec $XTERM -e "$0" "$@" #! [ -t 0 ] && exit ## 0.5 is this the first sandbox? If not, then create another name for mountpoints #if grep -q $FAKEROOT /proc/mounts; then # FAKEROOT=$(mktemp -d -p $SANDBOX_ROOT ${FAKEROOT##*/}.XXXXXXX) # SANDBOX_ID=".${FAKEROOT##*.}" # SANDBOX_TMPFS=$SANDBOX_ROOT/${SANDBOX_TMPFS##*/}${SANDBOX_ID} # rmdir $FAKEROOT #fi # 1. get aufs system-id for the root filesystem if [ -z "$AUFS_ROOT_ID" ] ; then AUFS_ROOT_ID=$( awk '{ if ($2 == "/" && $3 == "aufs") { match($4,/si=[0-9a-f]*/); print "si_" substr($4,RSTART+3,RLENGTH-3) } }' /proc/mounts ) fi # 2. get branches, then map branches to mount types or loop devices items=$( { echo ==mount==; cat /proc/mounts; echo ==losetup==; losetup-FULL -a; echo ==branches==; ls -v /sys/fs/aufs/$AUFS_ROOT_ID/br[0-9]* | xargs sed 's/=.*//'; } | \ awk ' /==mount==/ { mode=1 } /==losetup==/ { mode=2 } /==branches==/ { mode=3 } { if (mode == 1) { # get list of mount points, types, and devices - index is $3 (mount points) mountdev[$2]=$1 mounttypes[$2]=$3 } else if (mode == 2) { # get list of loop devices and files - index is $1 (loop devs) sub(/:/,"",$1) sub(/.*\//,"",$3); sub(/)/,"",$3) loopdev[$1]=$3 } else if (mode == 3) { # map mount types to loop files if mount devices is a loop for (m in mountdev) { if ( loopdev[mountdev[m]] != "" ) mounttypes[m]=loopdev[mountdev[m]] } # for (m in mountdev) print m " on " mountdev[m] " type " mounttypes[m] mode=4 } else if (mode==4) { # print the branches and its mappings if ($0 in mounttypes){ print $0, mounttypes[$0], "on" } else { MNT_PATH=$0 sub(/^.*[\/]/,"") print MNT_PATH, $0, "on" } } } ' ) # ' # 3. Ask user to choose the SFS log stop dialog --separate-output --backtitle "tmpfs sandbox" --title "sandbox config" \ --checklist "Choose which SFS you want to use" 0 0 0 $items 2> $TMPFILE chosen="$(cat $TMPFILE)" log start clear if [ -z "$chosen" ]; then echo "Cancelled or no SFS is chosen - exiting." exit 1 fi # 4. convert chosen SFS to robranches robranches="" for a in $(cat $TMPFILE) ; do robranches=$robranches:$a=ro done rm $TMPFILE # 5. get location of rw image if [ -z "$savebranch" ]; then choose_save loop=$(losetup-FULL -a | grep "$savebranch" | sed "s/:.*$//" ) if [ ! -z "$loop" ]; then SANDBOX_IMG=$(/proc/mounts | grep $loop | cut -d " " -f2) mount -o loop "$savebranch" $SANDBOX_IMG fi else loop=$(losetup-FULL -a | grep "$savebranch" | sed "s/:.*$//" ) if [ ! -z "$loop" ]; then SANDBOX_IMG=$(/proc/mounts | grep $loop | cut -d " " -f2) else mount -o loop "$savebranch" $SANDBOX_IMG fi fi if [ -z "$rwdir" ] ; then if [ -z "$PUPMODE" ]; rwdir=$SANDBOX_IMG else if [ $PUPMODE -ne 5 ] && [ $PUPMODE -ne 13 ] && [ $PUPMODE -ne 77 ]; then if [ -z ${SANDBOX_TMPF+x} ]; then SANDBOX_TMPF="" #Later we use [ -z ${SANDBOX_TMPF+x} ] to check that this is set fi fi fi fi # 4. make the mountpoints if not exist yet if [ ! -z "$SANDBOX_IMG" ]; then mkdir -p $SANDBOX_IMG mount -o loop "$savebranch" $SANDBOX_IMG || { echo "Failed to mount '$savebranch' at '$SANDBOX_IMG'" exit } fi if [ ! -z "$SANDBOX_ROOT" ]; then DEV_SAVE=$SANDBOX_ROOT/dev_save mkdir -p "$DEV_SAVE" if [ -z "$PDRV" ]; then if [[ "$SANDBOX_IMG" = *"/mnt/"* ]]; then PSUBDIR=${SANDBOX_IMG#/mnt/*/} PDRV=${SANDBOX_IMG%"/$PSUBDIR"} PDRV_real=$(cat /proc/mounts | grep $(realpath $PDRV) | cut -d " " -f1) PSUBDIR_i=${PSUBDIR} PDRV_i=${PDRV} PDRV_real_i=${PDRV_real} while (true); do if [[ PDRV_real_i = /dev/loop* ]]; then PDRV_real_i=$(losetup-FULL -a | grep "$(basename PDRV_real)") PDRV_real_i=${PDRV_real#*(} PDRV_real_i=${PDRV_real%)} PSUBDIR_i=${PDRV_real_i#/mnt/*/} PDRV_real=$PSUBDIR_i/$PDRV_real PDRV_real_i=${SANDBOX_IMG%"/$PSUBDIR_i"} PDRV_real_i=$(cat /proc/mounts | grep $(realpath $PDRV_real_i) | cut -d " " -f1) elif [[ PDRV_real_i = /dev/* ]]; then PDRV_real=$(blkid | grep $PDRV_real) break else echo "could not identify PDRV_real" break fi done fi fi fi if [ -z "$rwbranch" ] || [ -z ${SANDBOX_TMPF+x} ]; then if [ -z "$SANDBOX_TMPFS" ] ; then SANDBOX_TMPFS=$SANDBOX_ROOT/sandbox if grep -q $SANDBOX_TMPFS /proc/mounts; then #FAKEROOT=$(mktemp -d -p $SANDBOX_ROOT ${FAKEROOT##*/}.XXXXXXX) #SANDBOX_ID=".${FAKEROOT##*.}" SANDBOX_TMPFS=$SANDBOX_ROOT/${SANDBOX_ID/}${SANDBOX_ID} mkdir -p -f SANDBOX_TMPFS mount -t tmpfs none $SANDBOX_TMPFS; #We could exit if this fails but we don't need to becuase we can still write to SANDBOX_TMPFS even if it isn't tmpfs. rmdir $FAKEROOT fi fi fi if [ -z "$SANDBOX_TMPFS" ]; then SANDBOX_TMPFS=$SANDBOX_IMG else if [ $robranches ~= ** ]; then robranches=$SANDBOX_IMG=rr:$robranches fi fi mkdir -p $FAKEROOT mk_initrd_dir # 5. do the magic - mount the rw image first, and then the rest with aufs #if mount -o loop "$rwbranch" $SANDBOX_IMG; then if [ ${#FAKEROOT} -gt 1 ] && ! grep -q $FAKEROOT /proc/mounts; then # 5. record our new aufs-root-id so tools don't hack real filesystem SANDBOX_AUFS_ID=$(grep $FAKEROOT /proc/mounts | sed 's/.*si=/si_/; s/ .*//') #' sed -i -e '/AUFS_ROOT_ID/ d' $FAKEROOT/etc/BOOTSTATE 2> /dev/null echo AUFS_ROOT_ID=$SANDBOX_AUFS_ID >> $FAKEROOT/etc/BOOTSTATE echo "mount -t aufs -o \"br:$SANDBOX_TMPFS=rw$robranches\" aufs ${FAKEROOT}" echo "About to mount FAKEROOT at $FAKEROOT" read -p "Press enter to continue" mount -t aufs -o "br:$SANDBOX_TMPFS=rw$robranches" aufs ${FAKEROOT} # 7. sandbox is ready, now just need to mount other supports - pts, proc, sysfs, usb and tmp mkdir -p $FAKEROOT/dev $FAKEROOT/sys $FAKEROOT/proc $FAKEROOT/tmp mkdir -p "$DEV_SAVE/${PSUBDIR}" mount -o bind "$PDRV/${PSUBDIR}" "$DEV_SAVE/${PSUBDIR}" mount -o bind "$DEV_SAVE/${PSUBDIR}" "$FAKEROOT/initrd/mnt/dev_save" #Maybe optionally do this based on some input paramater: #Also pull these layers from an array for layer_name in "pup_ro2" "pup_ro3" "pup_ro4" "pup_ro5" "pup_z"; do layer="$(eval 'echo $'$layer_name)" if [ ! -z "$layer" ] ; then mount -o bind "$layer" "$FAKEROOT/initrd/$layer_name" fi done mkdir -p "$FAKEROOT/initrd/mnt/dev_save" mount -o bind "$DEV_SAVE/${PSUBDIR}" "$FAKEROOT/initrd/mnt/dev_save" mount -o rbind /dev $FAKEROOT/dev mount -t sysfs none $FAKEROOT/sys mount -t proc none $FAKEROOT/proc if [ PUPMODE = 2 ]; then #Full Install #Maybe don't base this on PUPMODE tmp_des=$FAKEROOT/tmp tmp_source=/tmp else mkdir -p $FAKEROOT/initrd/mnt/tmpfs tmp_des=$FAKEROOT/initrd/mnt/tmpfs tmp_source=/initrd/mnt/tmpfs cd $FAKEROOT rm tmp ln -s initrd/mnt/tmpfs tmp fi mount -o bind $tmp_source $tmp_des cd $FAKEROOT ln -s initrd/mnt/tmpfs tmp mkdir -p $FAKEROOT/$SANDBOX_TMPFS mount -o bind $SANDBOX_TMPFS $FAKEROOT/$SANDBOX_TMPFS # so we can access it within sandbox #mkdir -p $FAKEROOT/$SANDBOX_TMPFS mkdir -p $FAKEROOT/$SANDBOX_IMG mount -o bind $SANDBOX_IMG $FAKEROOT/$SANDBOX_IMG # so we can access it within sandbox cp /usr/share/sandbox/* $FAKEROOT/usr/bin 2> /dev/null # 8. optional copy, to enable running sandbox-ed xwin cp /usr/share/sandbox/* $FAKEROOT/usr/bin 2> /dev/null # 9. make sure we identify ourself as in sandbox - and we're good to go! echo -e '\nexport PS1="sandbox'${SANDBOX_ID}'# "' >> $FAKEROOT/etc/shinit #fatdog 600 sed -i -e '/^PS1/ s/^.*$/PS1="sandbox'${SANDBOX_ID}'# "/' $FAKEROOT/etc/profile # earlier fatdog if [ -d "$FULL_SAVE_PATH" ]; then #TODO verify that this works with a save file if [ $PUPMODE -eq 13 ] && [ $PUPMODE -eq 77 ]; then #TODO: when PUPMODE=77 (multisession cd) we need to copy folders. See: https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L1084 #and copy_folders() https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L482 #https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L1091 mount -o remount,prepend:"$FULL_SAVE_PATH"=rw,mod:"$SANDBOX_TMPFS"=ro,del:"$SANDBOX_TMPFS" "$FAKEROOT" #mount -o remount,add:1:"$FULL_SAVE_PATH"=ro+wh "$FAKEROOT" fi fi echo "Starting sandbox now." log stop if [ $USE_NS ]; then unshare -f -p --mount-proc=$FAKEROOT/proc chroot $FAKEROOT else chroot $FAKEROOT fi log start # 8. done - clean up everything umountall echo "Leaving sandbox." elif [ "${FAKEROOT:-/}" = "/" ]; then #[ -z "$FAKEROOT" ] && $FAKEROOT="/" echo "mount -t aufs -o \"remount,br:$SANDBOX_TMPFS=rw$robranches\" aufs ${FAKEROOT:-/}" echo "Warning! about to remount rootfs at $FAKEROOT" read -p "Press enter to continue" trap - 1 #Clear traps trap mount -t aufs -o "br:$SANDBOX_TMPFS=rw$robranches" aufs ${FAKEROOT:-/}; mkdir -p /dev /sys /proc /tmp #These probably already exist [[ "`mountpoint /dev`" != *"is a mountpoint"* ]] && mount -t devtmpfs devtmpfs /dev mkdir -p /initrd/mnt/tmpfs [[ "`mountpoint /initrd/mnt/tmpfs`" != *"is a mountpoint"* ]] && mount -t tmpfs none /initrd/mnt/tmpfs mkdir -p /initrd/mnt/tmpfs/tmp if [[ "`mountpoint /tmp`" != *"is a mountpoint"* ]]; then if [[ "`mountpoint /initrd/mnt/tmpfs`" != *"is a mountpoint"* ]]; mount -o bind /initrd/mnt/tmpfs/tmp /tmp else mount -t tmpfs none /tmp fi fi else echo "not implemented for FAKEROOT=${FAKEROOT:-/}}" exit fi #else # echo "Unable to mount aufs br:$SANDBOX_IMG=rw$robranches" # umount -l $SANDBOX_IMG #fi #else # echo "unable to mount rw image: $rwbranch" #fi