#!/bin/sh -e
#
# kernel-patch-suspend2 mkinitrd script
#
# changes the initrd boot script to allow for suspend2 resuming on systems with
# modular kernels.
#
# This script is heavily based on the original version found at
#   http://softwaresuspend.berlios.de/wiki/DebianInitrd
#
# (c) 2005 martin f. krafft <madduck@debian.org>
# distributed under the same terms as the original version.
#

# This is a kludge until mkinitrd has per-version script support (#298120):
case $0 in
  *-${VERSION//./_}) :;;
  *) exit 0;;
esac

if ! egrep -q '^CONFIG_(SOFTWARE_)?SUSPEND2=[ym]$' /boot/config-$VERSION; then
  echo I: while processing $0: >&2
  echo I: kernel version $VERSION seems to be not suspend2-enabled. >&2
  echo I: skipping execution of ${0##*/} for this run. >&2
  echo 'I: (you may ignore this message!)' >&2
  exit 0
fi

if [ -f $INITRDDIR/linuxrc.suspend2 ]; then
  echo I: suspend2 already registered with the initial ramdisk. >&2
  echo I: probably you have multiple suspend2-enabled kernel >&2
  echo I: images installed. Good for you. >&2
  echo 'I: (you may ignore this message!)' >&2
  exit 0
fi

# module support is deprecated
MODULES="suspend_core suspend_block_io suspend_text suspend_swap lzf suspend_lzf"
pushd $MODULEDIR > /dev/null 2>&1
for i in $MODULES ; do
  find -name "$i.ko"
done | cpio -p --make-directories --quiet $INITRDDIR/lib/modules/$VERSION/ 
popd > /dev/null 2>&1

if [ -r /proc/suspend2/filewriter_target ] && \
   [ -w $(</proc/suspend2/filewriter_target) ]; then

  resume2=$(</proc/suspend2/resume2)

else

  # Figure out swap device from the first device listed in /proc/swaps
  swap_device=`awk 'BEGIN{getline;getline;print$1}' < /proc/swaps`
  swap_type=`awk 'BEGIN{getline;getline;print$2}' < /proc/swaps`

  case "$swap_type" in
    partition)
      if [ ! -b "$swap_device" ]; then
	echo E: $swap_device is not a block device. >&2
	exit 1
      fi
      resume2=$(perl -e "@a=stat '$swap_device';printf 'swap:%04x', \$a[6]")
      ;;

    file)
      echo E: unable to use swap files at this time. Sorry. >&2
      exit 1
      # swap file support is currently broken
	#swapfile_dev=`perl -e "@a=stat '$swap_device';printf '%04x', \\$a[0]"`
	#swapfile_loc=`sed -ne 's/.*:\(0x[0-9a-fA-F@]\+\).$/\1/;p;q' < /proc/suspend2/header_locations`
	# We can't actually determine the locations at this point in time, because
	# we aren't guaranteed a suspend2 kernel :(
      ;;
    *)  
      echo W: unable to determine swap device. You will need to set resume2= >&2
      echo W: on your kernel command-line manually. >&2
      ;;
  esac

fi

echo I: using $resume2 on the kernel command line for suspend2. >&2

# create new linuxrc multiplexer
if [ -f $INITRDDIR/linuxrc -a ! -f $INITRDDIR/real-linuxrc ]; then
  mv $INITRDDIR/linuxrc $INITRDDIR/real-linuxrc
  cat <<EOT > $INITRDDIR/linuxrc
#!/bin/sh -e

export PATH=/sbin:/bin

for linuxrc in ./linuxrc.*; do
  . \$linuxrc || true
done

. ./real-linuxrc || true
EOT
  chmod 755 $INITRDDIR/real-linuxrc $INITRDDIR/linuxrc
fi
# end linuxrc multiplexer

# create suspend2 linuxrc
cat <<EOT > $INITRDDIR/linuxrc.suspend2
#!/bin/sh -e

export PATH=/sbin:/bin

mount -t proc proc /proc

if [ ! -d /proc ]; then
  echo E: /proc is not available. >&2
  echo E: this calls for suicide, but I will try to continue... >&2
  exit 0
fi

# we need this in case the keyboard is available as a module, and we want to
# warn about existing suspend partitions during a normal boot.
modprobe i8042 2>/dev/null || true

# load all normal modules
. /loadmodules

# now load suspend2 modules (deprecated)
modprobe suspend_core 2>/dev/null || true
modprobe suspend_block_io 2>/dev/null || true
modprobe suspend_text 2>/dev/null || true
modprobe lzf 2>/dev/null || true
modprobe suspend_lzf 2>/dev/null || true
modprobe suspend_swap 2>/dev/null || true

if [ ! -d /proc/suspend2 ]; then
  echo W: software suspend2 is not available, yet I was asked to set it up. >&2
  echo W: something fishy is going on... >&2
  echo W: trying to skip suspend2 initialisation. >&2
  exit 0
fi

if [ -w /proc/suspend2/resume2 ]; then
  echo $resume2 > /proc/suspend2/resume2
fi

if [ -w /proc/suspend2/do_resume ]; then
  /bin/echo > /proc/suspend2/do_resume || true
fi

umount /proc 2>/dev/null || true
EOT
chmod 755 $INITRDDIR/linuxrc.suspend2
# end suspend2 linuxrc

echo I: suspend2 support successfully installed into the >&2
echo "I: initial ramdisk (initrd) of kernel version $VERSION." >&2

exit 0
