Michael, might i ask you to try the attached version? It does the following:
- it reads the resume device that was set up from /sys/power/resume, the format is "major:minor" in decimal into $RDEV. - then it reads the swap partitions from /proc/swaps, one line at a time - it checks the major/minor of those partitions if they match $RDEV - if there was no match => bail out - otherwise => prepare suspend. The only thing i can imagine why this would fail is that /sys/power/resume is not set up when the partition is compiled in (or of course a new bug i might have put in ;-) If it fails for you, please tell me the contents of your /sys/power/resume directly after boot and if they match the compiled-in resume partition. Thanks and have a nice weekend ;-) -- Stefan Seyfried \ "I didn't want to write for pay. I QA / R&D Team Mobile Devices \ wanted to be paid for what I write." SUSE LINUX Products GmbH, Nürnberg \ -- Leonard Cohen
#!/bin/bash ########################################################################### # # # Powersave Daemon # # # # Copyright (C) 2004,2005 SUSE Linux Products GmbH # # # # This program is free software; you can redistribute it and/or modify it # # under the terms of the GNU General Public License as published by the # # Free Software Foundation; either version 2 of the License, or (at you # # option) any later version. # # # # This program is distributed in the hope that it will be useful, but # # WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # # General Public License for more details. # # # # You should have received a copy of the GNU General Public License along # # with this program; if not, write to the Free Software Foundation, Inc., # # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # # ########################################################################### # # first get helper functions (e.g. DEBUG, load_scheme, ...) "${0%/*}/helper_functions" "${PUB_SCRIPT_DIR}/sleep_helper_functions" "${PUB_SCRIPT_DIR}/sleep_helper_messages" set_variables "suspend2disk" prepare_logs "suspend2disk" declare -i PERCENT export PERCENT=0 # ugly global variable, but the easiest way to go. export STEP=5 ##EV_ID="$4" # event id, needed for SCRIPT_RETURN, set in helper_functions progress "" ############################################################################# # if the system is configured for 855resolution, we _must_ switch away from # X before suspend if [ -e /etc/sysconfig/videobios ]; then . /etc/sysconfig/videobios if [ "$VIDEOBIOS_PATCH" = "yes" ]; then SWITCH_VT=yes echo "VIDEOBIOS_PATCH is enabled" >> $LSMOD_LOG fi fi ############################################################################# # try to find a kernel image that matches the actually running kernel. # We need this, if more than one kernel is installed. This works reasonably # well with grub, if all kernels are named "vmlinuz-`uname -r`" and are # located in /boot. If they are not, good luck ;-) declare -a KERNELS MENU_ENTRIES declare -i DEFAULT_BOOT eval `get_kernels` # works only with grub, but we have no other # choice anyway for now. NEXT_BOOT="" RUNNING=`uname -r` ARCH=`uname -m` let PERCENT+=$STEP if [ "${BOOT_LOADER:-GRUB}" == "GRUB" ]; then progress "${_M01}" declare -i I=0 DEBUG "running kernel: $RUNNING" DIAG while [ -n "${KERNELS[$I]}" ]; do BOOTING="${KERNELS[$I]}" if IMAGE=`readlink /boot/$BOOTING` && [ -e "/boot/${IMAGE##*/}" ]; then DEBUG "Found kernel symlink $BOOTING => $IMAGE" INFO BOOTING=$IMAGE fi case $ARCH in ppc*) BOOTING="${BOOTING#vmlinux-}" ;; *) BOOTING="${BOOTING#vmlinuz-}" ;; esac if [ "$RUNNING" == "$BOOTING" ]; then NEXT_BOOT=${MENU_ENTRIES[$I]} DEBUG "running kernel corresponds to grub menu entry $NEXT_BOOT" DIAG DEBUG "kernel filename: '${KERNELS[$I]}'" DIAG echo "running kernel is grub menu entry $NEXT_BOOT (${KERNELS[$I]})" >> $LSMOD_LOG break fi let I++ done # if we have not found a kernel, issue a warning. # if we have found a kernel, we'll do "grub-once" later, after # prepare_suspend finished. if [ -z "$NEXT_BOOT" ]; then DEBUG "no kernelfile matching the running kernel found" WARN echo "no kernelfile matching the running kernel found" >> $LSMOD_LOG fi fi let PERCENT+=$STEP progress "${_M01}" ############################################################################# # if we did not find a kernel (or BOOT_LOADER is not GRUB) check, # if the running kernel is still the one that will (probably) be booted for # resume (default entry in menu.lst or if there is none the kernel file # /boot/vmlinuz points to.) # This will only work, if you use "original" SUSE kernels. # you can always override with the config variable set to "yes" if [ -z "$NEXT_BOOT" \ -a "$SUSPEND2DISK_IGNORE_KERNEL_MISMATCH" != "yes" ]; then # which kernel is booted with the default entry? BOOTING="${KERNELS[$DEFAULT_BOOT]}" # if there is no default entry (no menu.lst? Using LILO?) we fall back to # the default of /boot/vmlinuz. [ -z "$BOOTING" ] && BOOTING="vmlinuz" if IMAGE=`readlink /boot/$BOOTING` && [ -e "/boot/${IMAGE##*/}" ]; then BOOTING=$IMAGE fi BOOTING="${BOOTING#vmlinuz-}" DEBUG "running kernel: '$RUNNING', (probably) booting kernel: '$BOOTING'" DIAG if [ "$BOOTING" != "$RUNNING" ]; then notify 'The kernel version "'$BOOTING'" in /boot does not match the running kernel version "'$RUNNING'". Resuming with this kernel will not work. If you know what you are doing, you can override this in /etc/sysconfig/powersave/sleep with the variable SUSPEND2DISK_IGNORE_KERNEL_MISMATCH=yes.' ERROR CONTINUE "$EV_ID" progress_finish $SCRIPT_RETURN $EV_ID 1 "kernel version mismatch, cannot suspend to disk." EXIT 1 fi fi let PERCENT+=$STEP progress "${_M02}" ################################################################ # this is a hack. We can swapon a dedicated partition before # suspend. This partition will only be used by the suspend image # after resume we swapoff it again. if [ -n "$SUSPEND2DISK_RESUME_DEVICE" ]; then DEBUG "activating suspend partition '$SUSPEND2DISK_RESUME_DEVICE'" DIAG echo "You have set SUSPEND2DISK_RESUME_DEVICE. This is for experts." >> $LSMOD_LOG echo "activating suspend partition '$SUSPEND2DISK_RESUME_DEVICE'" >> $LSMOD_LOG echo "swapon: $SUSPEND2DISK_RESUME_DEVICE" >> $STATE swapon "$SUSPEND2DISK_RESUME_DEVICE" RET=$? if [ $RET -ne 0 ]; then DEBUG "swapon $SUSPEND2DISK_RESUME_DEVICE failed. Error: $RET" WARN echo "could not activate $SUSPEND2DISK_RESUME_DEVICE. Suspend might fail." >> $LSMOD_LOG fi fi ################################################################ # we need a swap partition, and it has to be given to the kernel # with the resume= parameter # Note: the suspend code can deal with multiple swap partitions, # but only the one given by resume= will be used. if [ "$SUSPEND2DISK_IGNORE_RESUME_PARAMETER" != yes ]; then read RDEV < /sys/power/resume # no resume device set? Error. if [ "$RDEV" = "0:0" ]; then DEBUG "resume partition is not set up." ERROR echo "resume partition is not set up." >> $LSMOD_LOG notify "The resume partition is not set up. Probably you need to add a 'resume=...' option to your kernel command line and reboot. Suspend to disk and resume is not possible without a resume partition, please consult the documentation. You can skip this check by setting SUSPEND2DISK_IGNORE_RESUME_PARAMETER to 'yes' in the sleep configuration file." \ ERROR CONTINUE "$EV_ID" progress_finish $SCRIPT_RETURN $EV_ID 1 "no resume parameter" EXIT 1 fi # # is the resume= parameter correct? while read SDEV STYPE DUMMY; do [ "$STYPE" != "partition" ] && continue X=$(stat -c '$((0x%t)):$((0x%T))' $SDEV) # stat major:minor in HEX [ $? -ne 0 ] && continue SNUM=$(eval echo $X) # this converts "$((0x3)):$((0xf))" to "3:15" [ "$SNUM" = "$RDEV" ] && break SDEV="" # not necessary, but for clarity :-) done < /proc/swaps if [ -z "$SDEV" ] ; then DEBUG "swap partition '$RDEV' not available" ERROR DEBUG "Contents of /proc/swaps:" DIAG while read LINE; do DEBUG "$LINE" DIAG done < /proc/swaps echo "swap partition '$RDEV' not available. Boom." >> $LSMOD_LOG echo "Content of /proc/swaps:" >> $LSMOD_LOG cat /proc/swaps >> $LSMOD_LOG notify "Swap partition '$RDEV' is not available, cannot suspend to disk." \ ERROR CONTINUE "$EV_ID" progress_finish $SCRIPT_RETURN $EV_ID 1 "resume partition not available." EXIT 1 fi else echo "SUSPEND2DISK_IGNORE_RESUME_PARAMETER=yes" >> $LSMOD_LOG fi # end of swap partition sanity check ################################################################ let PERCENT+=$STEP progress "" prepare_sleep "suspend2disk" let PERCENT+=$STEP progress "" # set the bootloader to the running kernel if [ -n "$NEXT_BOOT" ]; then progress "${_M09}" echo "preparing boot-loader: selecting entry $NEXT_BOOT, kernel /boot/$BOOTING" >> $LSMOD_LOG T1=`date +"%s%N"` sync; sync; sync # this is needed to speed up grub-once on reiserfs T2=`date +"%s%N"` let PERCENT+=$STEP progress "${_M10}" grub-once $NEXT_BOOT > /dev/null 2>&1 T3=`date +"%s%N"` S=$(((T2-T1)/100000000)); S="$((S/10)).${S:0-1}" G=$(((T3-T2)/100000000)); G="$((G/10)).${G:0-1}" echo " time needed for sync: $S seconds, time needed for grub: $G seconds." >> $LSMOD_LOG else let PERCENT=+$STEP fi progress "" # SET THE SHUTDOWN METHOD ###################################### # "platform" -> "real" S4, default. # "shutdown" -> S5 # "firmware" -> S4bios, not really supported. # "reboot" -> just reboot, only useful for debugging # we do a sanity check after setting this since there are still # kernels out there getting this wrong. echo -n "${SUSPEND2DISK_SHUTDOWN_MODE:-platform}" > /sys/power/disk RET=$? if [ $RET -ne 0 ]; then DEBUG "could not set shutdown mode. errno: '$RET'" WARN DEBUG "a software-suspend enabled kernel is needed for suspend to disk" WARN fi # Set the image size ########################################### # this is only valid for kernels from 2.6.16rc1 upwards IMAGE=${SUSPEND2DISK_IMAGE_SIZE:-500} SYSFS_IMGSZ="/sys/power/image_size" if [ -r $SYSFS_IMGSZ ]; then while read DEV TYPE SIZE USED PRI; do [ $DEV != $RPART ] && continue # RPART comes from above FREE=$[($SIZE-$USED)/1024] # get free space on RPART in MB if [ $FREE -lt $IMAGE ]; then IMAGE=$[$FREE-10] fi break # we found the partition, no need to look further done < /proc/swaps DEBUG "calculated image_size: $IMAGE" DIAG if [ $IMAGE -lt 0 ]; then IMAGE=0 fi # SUSPEND2DISK_IMAGE_SIZE is in MB, but the kernel now expects bytes echo [$IMAGE*1024*1024] > $SYSFS_IMGSZ else DEBUG "no $SYSFS_IMGSZ found." DIAG fi switch_to_vt progress_finish $SCRIPT_RETURN $EV_ID 0 "prepare_sleep finished successfully for $1" EXIT 0
_______________________________________________ powersave-devel mailing list powersave-devel@forge.novell.com http://forge.novell.com/mailman/listinfo/powersave-devel