diff options
author | Jonathan Bauer | 2014-03-11 17:05:46 +0100 |
---|---|---|
committer | Jonathan Bauer | 2014-03-11 17:05:46 +0100 |
commit | 32e6868dba383d092e15b28e29c12d760482b811 (patch) | |
tree | 277a633f2441391d456d08dec651701e81591a9c /remote | |
parent | [binutil.inc] fix special case: (diff) | |
download | tm-scripts-32e6868dba383d092e15b28e29c12d760482b811.tar.gz tm-scripts-32e6868dba383d092e15b28e29c12d760482b811.tar.xz tm-scripts-32e6868dba383d092e15b28e29c12d760482b811.zip |
[chroot.inc] major improvements
-do not remove directories on startup/exit, instead check for existing
mounts.
-after remounting / to read-only, check if it worked.
Diffstat (limited to 'remote')
-rw-r--r-- | remote/includes/chroot.inc | 111 |
1 files changed, 86 insertions, 25 deletions
diff --git a/remote/includes/chroot.inc b/remote/includes/chroot.inc index 3485ce63..f0940bba 100644 --- a/remote/includes/chroot.inc +++ b/remote/includes/chroot.inc @@ -11,7 +11,7 @@ # General information about OpenSLX can be found at http://openslx.org/ # ----------------------------------------------------------------------------- # -# Common functions for chrooting +# Common functions for chrooting # # ----------------------------------------------------------------------------- @@ -23,8 +23,20 @@ CHROOT_BINDMOUNTS="/dev /proc /sys /run" # Helper function to setup the directory structure chroot_prepare_dirs() { - # first the dir structure - [ -d "${CHROOT_TEMPDIR}" ] && rm -rf "${CHROOT_TEMPDIR}" + # first check if CHROOT_TEMPDIR exists + if [ -d "${CHROOT_TEMPDIR}" ]; then + # try to umount and rmdir CHROOT_MOUNTDIR + umount "${CHROOT_MOUNTDIR}" 2>/dev/null + rmdir "${CHROOT_MOUNTDIR}" || perror "Could not remove '${CHROOT_MOUNTDIR}', meaning it has stuff in it. Aborting..." + + # try to umount and rmdir CHROOT_BINDDIR + umount "${CHROOT_BINDDIR}" 2>/dev/null + rmdir "${CHROOT_BINDDIR}" || perror "Could not remove '${CHROOT_BINDDIR}', meaning it has stuff in it. Aborting..." + + # try to rmdir CHROOT_TEMPDIR + rmdir "${CHROOT_TEMPDIR}" || perror "Could not remove '${CHROOT_TEMPDIR}', meaning it has stuff in it. Aborting..." + fi + mkdir -p "${CHROOT_TEMPDIR}" || perror "Could not create base directory for mount directories $CHROOT_TEMPDIR." for DIR in "${CHROOT_BINDDIR}" "${CHROOT_MOUNTDIR}"; do mkdir -p "${DIR}" || perror "Could not create directory for mount directory $DIR." @@ -36,31 +48,25 @@ chroot_prepare_dirs() { # - make an overlay from CHROOT_LOWERDIR CHROOT_UPPERDIR # - bind mount additional pseudo-fs (as given in CHROOT_BINDMOUNTS) chroot_prepare_mounts() { - # now the mounts + + # first mount / on CHROOT_BINDDIR and remount read-only mount -o bind "${CHROOT_LOWERDIR}" "${CHROOT_BINDDIR}" || perror "Could not bind-mount '$CHROOT_LOWERDIR' to '$CHROOT_BINDDIR'." mount -o remount,ro "${CHROOT_BINDDIR}" || perror "Could not remount '$CHROOT_BINDDIR' read-only." + + # check that it really is read-only + [ "x$(mount | grep -E "^/ on ${CHROOT_BINDDIR}" | grep -v '\(.*ro.*\)')" != "x" ] && perror "'${CHROOT_BINDDIR}' is not read-only! Aborting..." + + # safe, go on to make the overlay mount -t overlayfs overlayfs -o lowerdir="${CHROOT_BINDDIR}",upperdir="${CHROOT_UPPERDIR}" "${CHROOT_MOUNTDIR}" \ || perror "Could not mount (overlayfs) $CHROOT_LOWERDIR, $CHROOT_UPPERDIR to $CHROOT_BINDDIR." + + # mount pseudo-filesystems for DIR in $CHROOT_BINDMOUNTS; do mount -o bind "${DIR}" "${CHROOT_MOUNTDIR}/${DIR}" \ || perror "Could not bind mount '$DIR' into '$CHROOT_MOUNTDIR/$DIR'." done } -# Helper to cleanup the temporary mounts -chroot_cleanup_mounts() { - for DIR in $CHROOT_BINDMOUNTS; do - umount -l "${CHROOT_MOUNTDIR}/${DIR}" || pwarning "Could not unmount '$CHROOT_MOUNTDIR/$DIR'!" - done - umount -l "${CHROOT_MOUNTDIR}" || pwarning "Could not unmount '$CHROOT_MOUNTDIR'!" - umount -l "${CHROOT_BINDDIR}" || pwarning "Could not unmount '$CHROOT_BINDDIR'!" -} - -# Helper to clean the temporary directories -chroot_cleanup_dirs() { - rm -rf "${CHROOT_TEMPDIR}" || perror "Could not clean/delete temp directory '$CHROOT_TEMPDIR'." -} - # Helper to generate the mighty autoexec.bat chroot_gen_autoexec() { # create the script to be automatically executed. @@ -72,8 +78,7 @@ chroot_gen_autoexec() { # dump the piped input to it cat >> "${CHROOT_MOUNTDIR}/autoexec.bat" - # finish with an exit - echo "exit 0" >> "${CHROOT_MOUNTDIR}/autoexec.bat" + # make it executable chmod +x "${CHROOT_MOUNTDIR}/autoexec.bat" } @@ -87,9 +92,13 @@ chroot_handle_whiteouts() { echo "/./${WHITEOUT#$CHROOT_UPPERDIR}" >> "$WHITEOUT_LIST" rm -f -- "$WHITEOUT" || perror "Could not delete whiteout $WHITEOUT!" done - pinfo "Whitelist dumped to '${CHROOT_UPPERDIR}/overlay.whiteout.list'" + pinfo "Whiteout list dumped to '${CHROOT_UPPERDIR}/overlay.whiteout.list'" } +############################################################################### +# +# MAIN FUNCTION +# # Main function to be called from the outside # Usage: # chroot_run <build_dir> < <code_to_exec_in_chroot> @@ -124,13 +133,65 @@ chroot_run() { if [ "$RET" -eq 0 ]; then pinfo "chroot executed '${CHROOT_MOUNTDIR}/autoexec.bat' succeeded." else - perror "Failed to chroot to '$CHROOT_MOUNTDIR' with error code: $RET" + perror "Failed to run '$CHROOT_MOUNTDIR/autoexec.bat' inside the chroot to '$CHROOT_MOUNTDIR' with error code: $RET" fi # handle whiteouts chroot_handle_whiteouts || perror "'chroot_handle_whiteouts' failed with error code: $?" - # finally cleanup all the stuff we did previously - chroot_cleanup_mounts || perror "'chroot_cleanup_mounts' failed with $?." - chroot_cleanup_dirs || perror "'chroot_cleanup_dir' failed with $?." + # finally cleanup all the mounting stuff we did previously + chroot_cleanup_mounts || perror "'chroot_cleanup' failed with $?." +} + +############################################################################### +# +# CLEANUP FUNCTIONS +# +# Helper to check if the given path is mounted +chroot_check_mount_point() { + [ "$#" -eq 1 ] || perror "'chroot_check_mount_point' called with $# arguements, only 1 accepted." + local MOUNT="$1" + if [ "x$(mount | grep "$(readlink -f $MOUNT)")" != "x" ]; then + # still mounted + pdebug "'$MOUNT' is mounted!" + return 1 + else + pdebug "'$MOUNT' is not mounted." + return 0 + fi +} + +# Helper to umount the given path +chroot_umount() { + [ "$#" -eq 1 ] || perror "'chroot_umount' called with $# arguments, only 1 accepted." + local MOUNT="$1" + + # check if MOUNT is mounted + if ! chroot_check_mount_point "${MOUNT}"; then + # still mounted + if umount -l "${MOUNT}"; then + pdebug "Successfully umounted '${MOUNT}'." + else + pwarning "Could not umount '${MOUNT}'! Trying again..." + # now it gets ugly + for i in `seq 1 5`; do + umount -l "${MOUNT}" && return 0 + done + perror "Could not umount '${MOUNT}' after 5 tries! This shouldn't happen. Check your scripts." + fi + else + pdebug "'${MOUNT}' is not mounted." + fi + + # better be safe than sorry + chroot_check_mount_point "$MOUNT" || perror "'$MOUNT' is still mounted, exiting before something bad happens..." +} + +# Helper to cleanup the temporary mounts +chroot_cleanup_mounts() { + for DIR in $CHROOT_BINDMOUNTS; do + chroot_umount "${CHROOT_MOUNTDIR}/${DIR}" + done + chroot_umount "${CHROOT_MOUNTDIR}" + chroot_umount "${CHROOT_BINDDIR}" } |