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

Reply via email to