summaryrefslogtreecommitdiffstats
path: root/remote
diff options
context:
space:
mode:
authorJonathan Bauer2014-03-11 17:05:46 +0100
committerJonathan Bauer2014-03-11 17:05:46 +0100
commit32e6868dba383d092e15b28e29c12d760482b811 (patch)
tree277a633f2441391d456d08dec651701e81591a9c /remote
parent[binutil.inc] fix special case: (diff)
downloadtm-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.inc111
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}"
}