Saturday, November 27, 2010

ACPI Power Button

Objective
In this topic I'll give some hints on '''configuring actions for acpi events

The beginning of the plot
On Monday (24 Nov 2008) my precious EBOX4300 seemed to be turned off, this resulted in this web page again being down...I'm starting to feel I'm not going to get even a poor of 50% of uptime!! :(

After a not so hard research I came up with the cause of the downtime: my housemaid. I noticed that the main power button in front of the machine, when pressed, causes a shut down on it.

With this insecure-for-my-uptime discovery I realized it was time to change this suicidal behaviour on my server.

Identifying ACPI events generated
It's as easy as monitoring the '''/var/log/acpid''' which is the file where the acpi daemon (acpid) writes interesting data. So when issuing this command

tail -f /var/log/acpid

And manually pressing the rear power button We will see something like this on the screen


[Tue Nov 25 21:32:42 2008] received event "button/power PWRF 00000080 0000000d"
[Tue Nov 25 21:32:42 2008] executing action "/etc/acpi/powerbtn.sh"
[Tue Nov 25 21:32:42 2008] BEGIN HANDLER MESSAGES
hola
[Tue Nov 25 21:32:42 2008] END HANDLER MESSAGES
[Tue Nov 25 21:32:42 2008] action exited with status 0
[Tue Nov 25 21:32:42 2008] completed event "button/power PWRF 00000080 0000000d"

 Changing the behaviour after an event
As we can see in the last section the '''/etc/acpi/powerbn.sh''' is invoked when pressing the power button.

What I did next was extending/varying the default behaviour like this:

  1. one press of the button: do nothing...ha ha ha ma housemaid now you cannot defeat me!
  2. two consecutive presses of the button: do a backup of the file system to a usb drive
  3. three consecutive presses of the button: do a reboot

The consecutive button press is measured by means of a 1 second interval and implemented by a "non-blocking sleep" and a file that acts as a flag as you can see in the following code.

{{{
#!/bin/sh
# /etc/acpi/powerbtn.sh
# Modified by eslimasec for an ebox4300 backup to a usb drive
# Based on a Herr Groucho script
# Initiates a shutdown when the power button has been
# pressed.
# begin variablas definitions: edit here
USB_DEV=/dev/sda1
MNT_DIR=/mnt/usbdrive
MNT_CMD=/bin/mount
UMNT_CMD=/bin/umount
INTERVAL=1
LOCKDIR=/var/lock
POWEROFF_LOCK=$LOCKDIR/poweroff
TODAY=`date +"%Y%m%d"`
BK_CMD="tar -czpf bk_wavy_$TODAY.tar.gz --exclude=/mnt/usbdrive  --exclude=/proc --exclude=/sys --exclude=/var/cache /"
MOUNT_CMD="$MNT_CMD $USB_DEV $MNT_DIR"
UMOUNT_CMD="$UMNT_CMD $USB_DEV"
# end variable definition: end editing
# begin functions declaration
do_backup()
{
        fdisk -l | grep -q /dev/sda1
        if  [ $? -eq 0 ]
        then
                $MOUNT_CMD
                cd $MNT_DIR
                echo "Backup starting"
                $BK_CMD
                cd /
                $UMOUNT_CMD
                echo "Backup ended, $USB_DEV unmounted"
        else
                echo "No usb drive located at $USB_DEV"
        fi
}
# end function declaration
# begin of main code
# If powersaved is running, let it process the acpi event
if pidof powersaved; then
        exit 0
fi
if [ ! -e $POWEROFF_LOCK ]
then
        echo "Presseed 1 time"
        echo "pressed_once" > $POWEROFF_LOCK
        {
                sleep 2
                rm -f $POWEROFF_LOCK
        } &
else
        case `cat $POWEROFF_LOCK` in
                pressed_once)
                        echo "Pressed 2 times"
                        echo "pressed_twice" > $POWEROFF_LOCK
                        {
                                sleep 1
                                #if the user pressed the button 3 times we are in poweroff mode  and we will skip doing the backup
                                if [ "`cat $POWEROFF_LOCK`" != "pressed_trice" ]
                                then
                                        do_backup
                                        rm -f $POWEROFF_LOCK
                                fi
                        } &
                        ;;
                pressed_twice)
                        echo "Pressed 3 times"
                        echo "pressed_trice" > $POWEROFF_LOCK
                        logger "Reboting system because of button press"
                        if ps -Af | grep -q '[k]desktop' && test -f /usr/bin/dcop
                        then
                                dcop --all-sessions --all-users ksmserver ksmserver logout 0 2 0 && exit 0
                                rm -f $POWEROFF_LOCK
                        else
                                /sbin/reboot
                                rm -f $POWEROFF_LOCK
                        fi
                        ;;
        esac
fi
}}}
I know trice does not exists...who cares!
== Links ==
  • http://www.mail-archive.com/lug-list@lugmen.org.ar/msg00586.html

No comments:

Post a Comment