#!/usr/bin/bash
#
# Deactivate module from the root directory structure on the fly
# This may fail for many cases, most likely when your module is 'busy'
# - for example if you have files open from the module yet.

if [ "$1" = "-k" ]; then
   CALLED_BY_KDE_HELPER=1
   shift
fi

if [ -e /usr/bin/kdeactivate -a "$DISPLAY" -a ! "$CALLED_BY_KDE_HELPER" ]; then
   exec /usr/bin/kdeactivate "$@" 2>/dev/null
fi

PATH=.:$(dirname $0):/usr/lib:$PATH
. liblinuxlive || exit 5

allow_only_root
MODULE="$(basename "$1")"

IMAGES=/mnt/live/memory/images
IPREV=empty

if [ "$MODULE" = "" -o ! -e "$IMAGES/$MODULE" ]; then
   echo
   echo "Deactivate module from the root filesystem while running Linux Live"
   echo "Usage: $0 module.[lzm|xzm|rwm|rom|enc]"
   exit 1
fi

# if the module contains /var/lock/deactivatelock, deny deactivation
if [ -e "$IMAGES/$MODULE/var/lock/deactivatelock" ]; then
   echo "Can't deactivate the given module, I am sorry."
   exit 2
fi

[ -e "$IMAGES/$MODULE/usr/share/applications" ] && UPDATE_MENUS=yes

try_remount()
{
if [ $(cmdline_parameter unionfs) ];then
   mount -t unionfs -o remount,del=$IMAGES/$MODULE unionfs / 2>/dev/null
else
   mount -t aufs -o remount,verbose,del:$IMAGES/$MODULE aufs / 2>/dev/null
fi
}

# Try to simply remove the dir first. If succeeds, finish
rmdir "$IMAGES/$MODULE" 2>/dev/null && exit 0
# OK the previous trick didn't work. So we have a real module here.

# First, try to stop all daemons which may be started by this module
find_n_run_scripts $IMAGES/$MODULE stop deactivate

# detach it from aufs union. This may take a long time, remounting the
# root directory is an expensive operation.
try_remount

# if remount fails, try to free all inotify watchers and remount again
while [ $? -ne 0 -a "$IPREV" != "$INODE" ]; do
   IPREV="$INODE"
   INODE=$(dmesg | fgrep "test_inode_busy" | tail -n 1 | cut -d : -f 4 | cut -b 8-)
   if [ "$INODE" != "" ]; then
      find / -noleaf -xdev -inum "$INODE"
      find / -noleaf -xdev -inum "$INODE" | xargs touch
      try_remount
   fi
done

if [ $? -ne 0 ]; then
   echo "The module can't be removed, because it's busy (used)." >&2
   exit 3
fi

# if we are here, the module has been successfuly removed from aufs union
# so now we have to umount the lzm file and then free the loop device
LOOP=$(cat /proc/mounts | grep "$IMAGES/$MODULE " | cut -d " " -f 1)
umount -n "$IMAGES/$MODULE" 2>/dev/null
if [ $? -ne 0 ]; then
   exit 4
fi
losetup -d "$LOOP" 2>/dev/null # sometimes it's freed by umount automatically
rmdir "$IMAGES/$MODULE" # if not empty or busy, a message will be shown

# update menus
if [ "$UPDATE_MENUS" = "yes" ] ;then
   ps -A | grep -q gam_server || killall -1 lxpanel mate-panel 2>/dev/null
   touch /usr/share/applications
fi
