Iff /tmp is available inside the chroot then use /tmp/grml-chroot
for storing information about active grml-chroot sessions.
This patch is based on work by Marc Haber and addresses the following issue
reported by him in http://bts.grml.org/grml/issue659:
| grml-chroot does not properly handle the situation when the user decides to
| chroot into the same chroot multiple times (for example, in different windows).
| When the first chroot terminates, the unconditional umount leaves the other
| chroots without mounted /proc, /dev etc.
Sadly this isn't bullet proof though.
Quoting Gebi from the according discussion on IRC (with his permission):
02:48 < gebi> you know that /tmp was to bind mounted too if you want to use X?
02:49 < gebi> not a good idea to use a bind mounted /tmp inside of the chroot for saving state which ultimatly goes back to the
base image
02:50 < gebi> mrud: but you e.g HAVE to mount --bind /tmp chroot/tmp to use X in chroot
02:51 < gebi> so it would be no fun to use chroot/tmp as state dir for grml-chroot, because on unmounting your files would not be
there anymore
02:51 < gebi> because hidden by the mount --bind
Thanks to Ulrich Dangel and Michael Gebetsroither for
code review and improvement suggestions.
DEST_=""
MOUNTED_="" # all mounted destinations
DEST_=""
MOUNTED_="" # all mounted destinations
+function bailout
+{
+ umount_all
+ die "Bailout"
+}
+trap bailout 1 2 3 3 6 9 14 15
+function isMounted
+{
+ local dir="$1"
+ if cut -d\ -f 2 /proc/mounts | grep -q "$dir"; then
+ return 0
+ else
+ return 1
+ fi
+}
+
function printUsage
{
cat <<EOT
function printUsage
{
cat <<EOT
- if [[ $options_ == "--bind" ]]; then
+ if ! isMounted "${DEST_}/$dest_"; then
+ if [[ $options_ == "--bind" ]]; then
all_options_="--bind $type_"
all_options_="--bind $type_"
all_options_="-t $type_ none"
all_options_="-t $type_ none"
+ fi
+ mount $all_options_ "${DEST_}/$dest_" && storeMounts "$dest_"
- mount $all_options_ "${DEST_}/$dest_" && storeMounts "$dest_"
- for i in $MOUNTED_; do
- umount "${DEST_}/$i"
+ for i in /proc /sys /dev; do
+ umount "${DEST_}/${i}"
+
+ rm -f "$DEST_"/etc/debian_chroot
mountit "sysfs" "sys"
mountit "/dev" "dev" "--bind"
mountit "sysfs" "sys"
mountit "/dev" "dev" "--bind"
-WROTE_DEBIAN_CHROOT=""
-if [ ! -f "$DEST_"/etc/debian_chroot ]; then
- WROTE_DEBIAN_CHROOT="yes"
+# do not write to /var/run of chroot if it's not present
+if [ -d "$DEST_/tmp" ] ; then
+ STATEDIR="tmp/grml-chroot"
+ mkdir -p "$DEST_/$STATEDIR"
+ touch "$DEST_/$STATEDIR/$$"
+fi
+
+if [ ! -e "$DEST_"/etc/debian_chroot ]; then
echo "Writing /etc/debian_chroot ..."
cat "$DEST_"/etc/hostname > "$DEST_"/etc/debian_chroot
fi
echo "Writing /etc/debian_chroot ..."
cat "$DEST_"/etc/hostname > "$DEST_"/etc/debian_chroot
fi
chroot "$DEST_" "$@"
RC=$?
fi
chroot "$DEST_" "$@"
RC=$?
fi
-if [ ! -z "$WROTE_DEBIAN_CHROOT" ]; then
- rm "$DEST_"/etc/debian_chroot
+if [ -z "$STATEDIR" ] ; then
+ umount_all
+else
+ rm "$DEST_/$STATEDIR/$$"
+
+ if rmdir "$DEST_/$STATEDIR" 2>/dev/null; then
+ umount_all
+ fi