add powermanagement and disk utils

This commit is contained in:
Ertuğrul Erata
2015-07-31 10:59:10 +03:00
parent ada4e1ce08
commit 5ddcdd77d9
70 changed files with 3472 additions and 61 deletions
@@ -0,0 +1,202 @@
#!/bin/bash
#
# Stefan Seyfried, SUSE Linux Products GmbH 2006, GPL v2
# mostly taken from the powersave project.
GRUBONCE="/usr/sbin/grubonce"
GRUBDEFAULT="/boot/grub/default"
GRUBDEFSAVE="/run/suspend.grubonce.default"
#####################################################################
# gets a list of available kernels from /boot/grub/menu.lst
# kernels are in the array $KERNELS, output to stdout to be eval-ed.
getkernels()
{
# DEBUG "Running getkernels()" INFO
local MENU_LST="/boot/grub/menu.lst"
local I DUMMY MNT ROOTDEV
declare -i I=0 J=-1
# we need the root partition later to decide if this is the kernel to select
while read ROOTDEV MNT DUMMY; do
[ "$ROOTDEV" = "rootfs" ] && continue # not what we are searching for
if [ "$MNT" = "/" ]; then
break
fi
done < /proc/mounts
# build an array KERNELS with all the kernels in /boot/grub/menu.lst
# the array MENU_ENTRIES contains the corresponding menu entry numbers
# DEFAULT_BOOT contains the default entry.
while read LINE; do
case $LINE in
title*)
let J++ # increase for every menu entry, even for non-linux
# DEBUG "Found grub menu entry #${J}: '${LINE}'" INFO
;;
default*)
DUMMY=($LINE) # "default 0 #maybe a comment"
echo "DEFAULT_BOOT=${DUMMY[1]}" # ^^[0]^^ 1 ^^[2]^ 3 ^^[4]^^
# DEBUG "Default boot entry is '${DUMMY[1]}'" INFO
;;
kernel*noresume*)
# we probably found the "failsafe" kernel that won't resume...
echo " Skipping grub entry #${J}, because it has the noresume option" >&2
;;
kernel*root=*)
local ROOT
ROOT=${LINE#*root=}
DUMMY=($ROOT)
ROOT=${DUMMY[0]}
if [ "$(echo $ROOT | grep LABEL)" ]; then
LABEL=`echo $ROOT | cut -d"=" -f2`
ROOT=`readlink -f /dev/disk/by-label/$LABEL`
elif [ "$(echo $ROOT | grep UUID)" ]; then
UUID=`echo $ROOT | cut -d"=" -f2`
ROOT=`readlink -f /dev/disk/by-uuid/$UUID`
fi
if [ "$(stat -Lc '%t:%T' $ROOT)" != "$(stat -Lc '%t:%T' $ROOTDEV)" ]; then
echo " Skipping grub entry #${J}, because its root= parameter ($ROOT)" >&2
echo " does not match the current root device ($ROOTDEV)." >&2
continue
fi
DUMMY=($LINE) # kernel (hd0,1)/boot/latestkernel-ABC root=/dev/hda2
echo "KERNELS[$I]='${DUMMY[1]##*/}'" # latestkernel-ABC
echo "MENU_ENTRIES[$I]=$J"
# DEBUG "Found kernel entry #${I}: '${DUMMY[1]##*/}'" INFO
let I++
;;
kernel*)
# a kernel without "root="? We better skip that one...
echo " Skipping grub entry #${J}, because it has no root= option" >&2
;;
*) ;;
esac
done < $MENU_LST
}
#############################################################
# runs grubonce from the grub package to select which kernel
# to boot on next startup
grub-once()
{
if [ -x "$GRUBONCE" ]; then
rm -f "$GRUBDEFSAVE"
if [ -e "$GRUBDEFAULT" ]; then
echo " saving original $GRUBDEFAULT"
cp "$GRUBDEFAULT" "$GRUBDEFSAVE"
fi
echo " running '$GRUBONCE $1'"
$GRUBONCE $1
else
echo "WARNING: $GRUBONCE not found, not preparing bootloader"
fi
}
#############################################################
# restore grub default after (eventually failed) resume
grub-once-restore()
{
echo "INFO: running grub-once-restore"
rm -f "$GRUBDEFAULT"
if [ -e "$GRUBDEFSAVE" ]; then
echo " restoring original $GRUBDEFAULT"
mv "$GRUBDEFSAVE" "$GRUBDEFAULT"
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 "kernel-`uname -r`" and are
# located in /boot. If they are not, good luck ;-)
find-kernel-entry()
{
NEXT_BOOT=-1
ARCH=`uname -m`
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#*kernel-}" ;;
esac
if [ "$RUNNING" == "$BOOTING" ]; then
NEXT_BOOT=${MENU_ENTRIES[$I]}
echo " running kernel is grub menu entry $NEXT_BOOT (${KERNELS[$I]})"
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 [ $NEXT_BOOT -eq -1 ]; then
echo "WARNING: no kernelfile matching the running kernel found"
fi
}
#############################################################################
# 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/latestkernel points to.)
# This will only work, if you use "original" SUSE kernels.
# you can always override with the config variable set to "yes"
prepare-grub()
{
echo "INFO: running prepare-grub"
eval `getkernels`
RUNNING=`uname -r`
find-kernel-entry
RET=0
if [ $NEXT_BOOT -eq -1 ]; then
# which kernel is booted with the default entry?
BOOTING="${KERNELS[$DEFAULT_BOOT]}"
# if there is no default entry (no menu.lst?) we fall back to
# the default of /boot/latestkernel.
[ -z "$BOOTING" ] && BOOTING="latestkernel"
if IMAGE=`readlink /boot/$BOOTING` && [ -e "/boot/${IMAGE##*/}" ]; then
BOOTING=$IMAGE
fi
BOOTING="${BOOTING#*kernel-}"
echo "running kernel: '$RUNNING', probably booting kernel: '$BOOTING'"
if [ "$BOOTING" != "$RUNNING" ]; then
echo "ERROR: kernel version mismatch, cannot suspend to disk"
echo "running: $RUNNING booting: $BOOTING" >> $INHIBIT
RET=1
fi
else
# set the bootloader to the running kernel
echo " preparing boot-loader: selecting entry $NEXT_BOOT, kernel /boot/$BOOTING"
T1=`date +"%s%N"`
sync; sync; sync # this is needed to speed up grub-once on reiserfs
T2=`date +"%s%N"`
echo " grub-once: `grub-once $NEXT_BOOT`"
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."
fi
return $RET
}
###### main()
case $1 in
hibernate)
prepare-grub
;;
thaw)
grub-once-restore
;;
esac
@@ -0,0 +1,106 @@
#!/bin/sh
#
# Written by Gabriel Burt <gburt@novell.com>
# Copyright 2008 Novell, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# Use rtcwake to wake the computer from sleep or hibernate
# as configured in /etc/pm/config.d/rtcwake.config
. "${PM_FUNCTIONS}"
rtcwake_cmd="/usr/sbin/rtcwake";
command_exists $rtcwake_cmd || exit $NA
rtcwake_config_file="/etc/pm/config.d/rtcwake.conf"
function start_of_day {
echo `date -d "$1" "+%D"`
}
function since_epoch {
echo `date -d "$1" "+%s"`
}
function day_of_week {
echo `date -d "$1" "+%u"`
}
function isAlarmDow {
is=0
for dow in $RTCWAKE_DAYS; do
if test "x$dow" = "x$1"; then
is=1;
break;
fi
done
echo $is
}
function set_alarm
{
# If USER_RTCWAKE_ALLOWED is yes and the user passed in a num_seconds_to_sleep variable, then
# we will respect it (and ignore the system config)
# Do require that the number of seconds is at least 30 though.
if test "x$USER_RTCWAKE_ALLOWED" != "xno" && test "x$NUM_SECONDS_TO_SLEEP" != "x" && test $(($NUM_SECONDS_TO_SLEEP > 30)) == 1; then
echo "Have NUM_SECONDS_TO_SLEEP: $NUM_SECONDS_TO_SLEEP";
# Actually set/configure the rtcwake
sh -c "$rtcwake_cmd -m on -s $NUM_SECONDS_TO_SLEEP &"
elif test "x$1" = "xyes"; then
echo "alarm enabled, configuring rtcwake...";
echo "RTCWAKE time: $RTCWAKE_TIME";
echo "RTCWAKE days: $RTCWAKE_DAYS";
next_alarm=0
now=$(since_epoch now);
# The next alarm has to be at most 7 days from now
for days_from_now in 0 1 2 3 4 5 6 7; do
# Get the date N days from now
alarm_day=$(start_of_day "$days_from_now day");
# Check that this day is an alarm-enabled day of the week
alarm_dow=$(day_of_week $alarm_day);
is_alarm_dow=$(isAlarmDow $alarm_dow);
if test "x$is_alarm_dow" = "x1"; then
# Get the actual alarm time on that day
alarm_time=$(since_epoch "$alarm_day $RTCWAKE_TIME");
# Ensure the alarm time is more than 15 minutes from now
# - otherwise we set the alarm for the next slot
# 900 seconds = 15 minutes * 60 seconds/minute
is_enough_in_future=$(($alarm_time - $now > 900));
if test "x$is_enough_in_future" = "x1"; then
next_alarm=$alarm_time
break;
fi
fi
done
if test "x$next_alarm" != "x0"; then
# Recalculate now to be as accurate as possible
now=$(since_epoch now);
seconds_from_now=$(($next_alarm - $now));
echo "Will set alarm for $seconds_from_now seconds from now, at $alarm_day $RTCWAKE_TIME ($next_alarm)"
# Actually set/configure the rtcwake
sh -c "$rtcwake_cmd -m on -s $seconds_from_now &"
else
echo "No acceptable time found to set the rtcwake alarm. Review your configuration in $rtcwake_config_file"
exit $NA
fi
else
echo "rtcwake alarm not enabled in $rtcwake_config_file, doing nothing...";
exit $NA
fi
}
case "$1" in
suspend) set_alarm $SUSPEND_RTCWAKE_ENABLED ;;
hibernate) set_alarm $HIBERNATE_RTCWAKE_ENABLED ;;
*) exit $NA ;;
esac
@@ -0,0 +1,162 @@
#!/bin/bash
#
# Stefan Seyfried, SUSE Linux Products GmbH, 2006
# mostly taken from the powersave project
. "${PM_FUNCTIONS}"
# sanity check the environment if resume will be possible after hibernate
checkhibernate()
{
echo "INFO: checking for suspend-to-disk prerequisites..."
if [ -z "$IMAGE_SIZE" ]; then
IMAGE_SIZE="`awk '/^MemTotal:/ { print int($2*1024*.45) }' /proc/meminfo`"
fi
# Default to partition style hibernation
SWAP_TYPE=partition
read CMDLINE < /proc/cmdline
for CMD in $CMDLINE; do
case $CMD in
resume=*)
RESUME=${CMD#*=}
;;
resume_offset=*)
# Swap type is file as resume_offset is given
SWAP_TYPE=file
;;
esac
done
if [ -z "$RESUME" ]; then
# No resume= given in /proc/cmdline, failing.
echo "ERROR: no resume parameter on kernel commandline, can not suspend"
echo "no resume parameter on kernel commandline" >> $INHIBIT
return 1
fi
if [ "$SWAP_TYPE" = file ] && [ "$SLEEP_MODULE" = "uswsusp" ]; then
# File-style hibernating is not supported by uswsusp
echo "ERROR: You must use the kernel hibernate method or tuxonice when suspending to swapfile, not uswsusp"
echo "suspend to swapfile with uswsusp method not kernel" >> $INHIBIT
return 1
fi
# the resume device can be a symlink, e.g. with LVM/EVMS or with
# /dev/disk/by-id/foo
RESUME=$(readlink -f $RESUME)
OK=
while read DEV TYPE SIZE USED PRI; do
if [ "$TYPE" = "file" ] && [ "$SWAP_TYPE" = "file" ] && [ "$RESUME" = "$(df "$DEV" | tail -n +2 | cut -d ' ' -f 1)" ]; then
OK=1
break
fi
[ "$TYPE" != "partition" ] && continue
[ "$DEV" != "$RESUME" ] && continue
FREE=$[($SIZE-$USED)*1024] # get free space on DEV
if [ $FREE -lt $IMAGE_SIZE ]; then
IMAGE_SIZE=$[$FREE-10*1024*1024]
fi
OK=1
break # we found the partition, no need to look further
done < /proc/swaps
if [ -z "$OK" ]; then
if [ "$SWAP_TYPE" = "file" ]; then
MSG_TYPE="swap file"
else
MSG_TYPE="resume partition"
fi
echo "ERROR: $MSG_TYPE '$RESUME' not active, can not suspend"
echo "$MSG_TYPE '$RESUME' not active" >> $INHIBIT
return 1
fi
if [ "$SLEEP_MODULE" = "kernel" ]; then
echo " using kernel suspend method"
read DEV < /sys/power/resume
if [ "$DEV" = "0:0" ]; then
echo "ERROR: no resume partition set up in /sys/power/resume"
# maybe "resume=..." was given, but initrd did not set up
# /sys/power/resume correctly.
echo "resume device not correctly setup in /sys/power/resume" >> \
$INHIBIT
return 1
fi
X=$(stat -Lc '$((0x%t)):$((0x%T))' $RESUME)
RDEV=$(eval echo $X)
if [ "$DEV" != "$RDEV" ]; then
echo "ERROR: /sys/power/resume ($DEV) disagrees with resume= parameter ($RDEV)"
echo " can not suspend."
echo "/sys/power/resume disagrees with resume= parameter" >> \
$INHIBIT
return 1
fi
if [ -n "$IMAGE_SIZE" -a -w /sys/power/image_size ]; then
echo " setting image size to $IMAGE_SIZE"
echo "$IMAGE_SIZE" > /sys/power/image_size 2>/dev/null
fi
fi
if [ "$SLEEP_MODULE" = "uswsusp" ]; then
echo " using userspace suspend method, temp. config file $S2DISK_CONF"
if [ "$S2DISK_CONF" != "/etc/suspend.conf" ]; then
rm -f $S2DISK_CONF
# Generate S2DISK_CONF
echo " setting resume device to $RESUME"
echo "resume device = $RESUME" >> $S2DISK_CONF
if [ -n "$IMAGE_SIZE" ]; then
echo " setting image size to $IMAGE_SIZE"
echo "image size = $IMAGE_SIZE" >> $S2DISK_CONF
fi
# add the parameters from /etc/suspend.conf to /var/lib/s2disk.conf
if [ -e /etc/suspend.conf ]; then
echo "# parameters taken from /etc/suspend.conf:" >> $S2DISK_CONF
sed '/^[[:space:]]*\(#\|$\)/d;' /etc/suspend.conf >> $S2DISK_CONF
echo " adding these parameters from /etc/suspend.conf:"
sed '/^[[:space:]]*\(#\|$\)/d;s/^/ /;' /etc/suspend.conf
fi
else
# don't overwrite the user's config file, but warn about the issue
echo "WARNING: S2DISK_CONF is set to /etc/suspend.conf"
echo " Disabling automatic generation of config file."
echo " This is most likely a configuration error and will cause problems"
echo " unless you configure /etc/suspend.conf completely on your own!"
fi
fi
return 0
}
# this only makes sense on hibernate or on suspend-hybrid
case $1 in
hibernate)
;;
suspend)
if [ "$2" != suspend_hybrid ]; then
exit 0
fi
;;
*)
exit $NA
;;
esac
[ -e /etc/pm/config.d/$1 ] && . /etc/pm/config.d/$1
if [ -z "$SLEEP_MODULE" ]; then
# Decide the SLEEP_MODULE if not given
if [ -x /usr/sbin/s2disk -a -c /dev/snapshot ]; then
SLEEP_MODULE="uswsusp"
else
SLEEP_MODULE="kernel"
fi
fi
if ! checkhibernate; then
echo "WARNING: $INHIBIT will be created to prevent suspending!"
touch $INHIBIT
exit 1
fi
exit 0
@@ -0,0 +1,21 @@
#!/bin/bash
. "${PM_FUNCTIONS}"
command_exists /sbin/pccardctl || exit $NA
case "$1" in
hibernate|suspend)
echo "ejecting PCMCIA cards..."
/sbin/pccardctl eject
;;
thaw|resume)
echo "inserting PCMCIA cards..."
/sbin/pccardctl insert
;;
*) exit $NA
;;
esac
exit 0
@@ -0,0 +1,15 @@
#!/bin/bash
# The ndiswrapper hook - relead the ndiswrapper module
. "${PM_FUNCTIONS}"
command_exists /usr/sbin/ndiswrapper || return $NA
case "$1" in
resume|thaw)
modprobe -r ndiswrapper
modprobe ndiswrapper
;;
*) exit $NA
;;
esac