[2024-feb-29] Sad news: Eric Layton aka Nocturnal Slacker aka vtel57 passed away on Feb 26th, shortly after hospitalization. He was one of our Wiki's most prominent admins. He will be missed.

Welcome to the Slackware Documentation Project

This is an old revision of the document!


Hibernation with LVM, LUKS and a Swapfile

With this How To you can use a swapfile instead a swap partition as described here: http://slackware.osuosl.org/slackware-14.0/README_CRYPT.TXT

First create a swapfile: (you can choose another name and / or size if you want)

dd if=/dev/zero of=/swapfile bs=1M count=4096
mkswap /swapfile 

Activate the Swap:

swapon /swapfile

Check if the Swapfile is recognized by the system:

cat /proc/swaps 
Filename                                Type            Size    Used    Priority
/swapfile                               file            4194300 0       -1

Add to the fstab

/swapfile        none             swap        defaults         0   0

For suspend/resume you need to append 2 kernel Parameter in /etc/lilo.conf resume and resume_offset.

resume is the partition where the swapfile is located (e.g /dev/sda, /dev/cryptslack/root) resume_offset is the beginning of the swapfile on the resume partition, you can get the offset with

sudo /sbin/filefrag -v /swapfile | head -n -3 | tail -n 1 | awk ' {print $3 }'

your lilo entry should look like this:

# Append any additional kernel parameters:
 append="vt.default_utf8=1 resume=/dev/cryptslack/root resume_offset=1134591"

You need to patch the initrd to recognize the resume_offset parameter

init-swapfile.patch
--- init.orig   2012-12-01 14:03:39.344538490 +0100                                                                                                            
+++ init        2012-12-01 14:01:12.526373970 +0100                                                                                                            
@@ -69,6 +69,7 @@                                                                                                                                              
 LUKSDEV=$(cat /luksdev)                                                                                                                                       
 LUKSKEY=$(cat /lukskey)                                                                                                                                       
 RESUMEDEV=$(cat /resumedev)                                                                                                                                   
+RESOFFSET=$(cat /resoffset)                                                                                                                                   
 WAIT=$(cat /wait-for-root)                                                                                                                                    
 KEYMAP=$(cat /keymap)                                                                                                                                         
 INIT=/sbin/init                                                                                                                                               
@@ -269,18 +270,35 @@
     umount -l /mountkey
     rmdir /mountkey 2>/dev/null
   fi
-  
-  # Resume state from swap
-  if [ "$RESUMEDEV" != "" ]; then
-    if ls -l $RESUMEDEV | grep -q "^l" ; then
-      #RESUMEDEV=$(ls -l $RESUMEDEV | awk '{ print $NF }')
-      RESUMEDEV=$(readlink -f $RESUMEDEV)
-    fi
-    echo "Trying to resume from $RESUMEDEV"
-    RESMAJMIN=$(ls -l $RESUMEDEV | tr , : | awk '{ print $5$6 }')
-    echo $RESMAJMIN > /sys/power/resume
-  fi
-
+ 
+if [ "$RESUMEDEV" != "" ]; then
+       # be lvm aware
+        RESUMEDEV=$(readlink -f ${RESUMEDEV} | awk -F '/' '{ print $3 }')
+       if [ -r "/sys/class/block/${RESUMEDEV}/dev" ] ; then
+       # try sysfs 
+               read RESMAJMIN < "/sys/class/block/${RESUMEDEV}/dev"
+       elif [ -r "/proc/partitions" ] ; then
+       # otherwise run through /proc/partitions
+               while read m n b d jnk ; do
+                       if [ "$d" = "${RESUMEDEV}" ] ; then
+                               RESMAJMIN="$m:$n"
+                               break
+                       fi
+               done < "/proc/partitions"
+               fi
+       if [ -z "${RESMAJMIN}" ] ; then
+               # Device does not exist (not found in /proc/partitions)
+               exit 99
+       fi
+
+       if [ -n "${RESOFFSET}" ]; then
+                echo "Try resume from ${RESMAJMIN}:${RESOFFSET}"
+               echo "${RESMAJMIN}:${RESOFFSET}" > /sys/power/resume
+       else
+               echo "${RESMAJMIN}" > /sys/power/resume
+       fi
+fi
+ 
mkdir patched_initrd
cd patched_initrd
cp -r /boot/initrd-tree .
echo "1134591" > resoffset
patch < init-swapfile.patch

after successfull patching ,pack the initrd to /boot/initrd-swapfile.gz

find . -print0 | cpio -ov -0 --format=newc | gzip -9 > /boot/initrd-swapfile.gz
i recommend you to test this initrd first with another bootentry
image = /boot/vmlinuz
initrd = /boot/initrd-swapfile.gz
root = /dev/cryptslack/root
label = "Linux Swapfile"
read-only

then you need to run lilo to save the changes

lilo

after a reboot you can suspend to your swapfile as with your swap partition

you need the reboot, suspend also uses resume_offset to find the swapfile

Sources

 howtos:slackware_admin:swapfile_hibernation ()