How can I automate my Linux computer to power off (and on preferably) under certain circumstances?

1

0

OK, So a little background;

I've been using Windows Home Server as a Backup Appliance, Media Server and Share Server at home for some time. I decided it was costing me allot of juice so very early on added the "Lights Out" add-on to ensure it was only running as and when needed.

I'm now looking to switch to a Linux based server and I'm looking for a similar tool/set of tools for advanced power management.

Now the question;

Anyone got any all-in-one suggestions (i.e with client parts for both Windows and Linux and a server part for the Linux server), or can anyone simply verify that I'll need to set-up all the individual bits for this myself separately?

(A tool similar to "SmartPower" but for linux would be a great start)

Ashimema

Posted 2010-12-31T15:13:11.853

Reputation: 145

Answers

2

Unfortunately you did not specify your specific requirements, so it's hard to know, what exactly you need.

However with shell scripts almost anything is possible. I have a shell script that shutdowns the computer, once specific clients (space separated list in the CLIENTS variable) are no longer online and certain processes (space separated list in the PROCESSES variable) are not running for the last 3 checks:

 #!/bin/sh

LOGFILE=/var/log/autoshutdown.log
CLIENTS="hanzo twix"
PROCESSES="screen"
CHECK_THRESHOLD=3
CHECK_COUNT_FILE=/tmp/autoshutdown_count

FALSE=1
TRUE=0

function log() {
    typeset message="$1"
    echo "$(date +'%Y-%m-%d %H:%M:%S')  $message" >> $LOGFILE
}

function clientsOnline() {
    typeset flag_online=$FALSE
    for client in $CLIENTS
    do
        if ping -c 1 $client 1>/dev/null 2>/dev/null
        then
            #log "Client $client is online."
            flag_online=$TRUE
        else
            #log "Client $client is offline."
            true                                                                                                         
        fi
    done                                                                                                                 

    return $flag_online                                                                                                  
}                                                                                                                        

function processRunning() {
    typeset process_flag=$FALSE                                                                                          
    for process in $PROCESSES                                                                                            
    do                                                                                                                   
        if ps -e | grep -qs $process                                                                                     
        then                                                                                                             
            #log "Process $process is running."                                                                          
            process_flag=$TRUE
        else                                                                                                             
            #log "Process $process is not running."
            true                                                                                                         
        fi                                                                                                               
    done                                                                                                                 

    return $process_flag
}

function resetShutdownCounter() {
    echo "0" > $CHECK_COUNT_FILE                                                                                         
}                                                                                                                        

function getShutdownCount() {
    if [ -r $CHECK_COUNT_FILE ]
    then
        cat $CHECK_COUNT_FILE | head -n 1
    else
        echo 0
    fi
}

function incrementShutdownCounter() {
    echo $(expr $(getShutdownCount) + 1) > $CHECK_COUNT_FILE
}

if [ $(id -u) -ne 0 ]
then
    echo "This script must be run as root user." >&2
    exit 1
fi

#log "### Starting ###"

if clientsOnline
then
    #log "At least one client is online. Reseting shutdown count."
    resetShutdownCounter
elif processRunning
then
    #log "At least one of the registered processes is running. Reseting shutdown count."
    resetShutdownCounter
else
    incrementShutdownCounter
    log "No registered client online. Shutdown counter incremented. Current value: $(getShutdownCount)"

    if [ $(getShutdownCount) -ge $CHECK_THRESHOLD ]
    then
        log "Shutdown count threshold reached. Shutting down system in 10 seconds."
        rm -f $CHECK_COUNT_FILE
        /sbin/shutdown -h 1
    fi
fi

All you have to do is to run this script from your crontab every 5 minutes. Then it would shutdown your computer in case the shutdown conditions are fulfilled for 15 minutes in a row.

Yaba

Posted 2010-12-31T15:13:11.853

Reputation: 325

Cheers Yaba, Very useful example script; general enough for me to simply modify as needed. Thanks – Ashimema – 2011-01-19T21:51:12.213

Only just got round to playing with this...

In your script where do the "clients" actually come from? It's probably a basic Linux question, but where's the link between the friendly "Client" name you use here and the client machines physical address (IP)? – Ashimema – 2011-02-09T16:04:44.223

@Ashimema... that's a simple host name resolution through DNS or /etc/hosts. You could also enter an IP address instead of the host name. Basically the command 'ping -c 1 $client' must succeed in case the client is online. – Yaba – 2011-02-09T21:56:56.287

1

Actually, that's quite simple.

To power off your Linux machine you only have to execute a '/sbin/telinit 6' (as root!) from the command line or a script. This shuts down all processes in an orderly fashion and powers off through the BIOS. Note that this not work all motherboards, but in 99% of the cases it does.

There are many ways to automate this... I don't know of any automated packages, but it's not difficult to create one it yourself. I'm assuming you are using a server and a desktop/laptop to work on. If, for example you want your Linux system to power down automatically after you shut down your Windows desktop, you could write a script that pings your Windows machine every 5 minutes. If that fails 3 times in a row, shut down the machine. Another possibility is a webpage, only accessible from you local lan that initiates a (delayed) shutdown; you just make sure that page gets called on Windows shutdown. Etcetera...

JvO

Posted 2010-12-31T15:13:11.853

Reputation: 883

Thanks JvO, that's a pretty useful answer.

You've helped me clarify that a pre-packaged tool doesn't appear to exist yet, and come up with an excellent idea for where I could start to create a script to accomplish it (using the pinging of machines that need monitoring on the network) It's obvious now I think about it. Cheers – Ashimema – 2010-12-31T16:09:42.077

0

As for shutting down at a specific time, you can do it pretty easily by putting an entry in /etc/crontab

30 2 * * * root /sbin/shutdown -h 0

That will shutdown the system at 2:30am every day.

Some BIOSes let you setup the system to power on at a specific time, that's another option besides wake-on lan.

deltaray

Posted 2010-12-31T15:13:11.853

Reputation: 1 665

Cheers deltaray, I've used crontab before for similar, but was hoping to find a tool to do a number of monitoring events similar to the one mentioned for whs. Lights out monitors a "calendar" much like crontab would in this instant, but it also monitors whether client computers are turned on or not and using therefore using the server, whether there's an active backup taking place or due to start, whether the server is undergoing any self maintenance (I'm looking at using greyhole storage pooling, so in Linux this would be the drive balancing regimes) – Ashimema – 2010-12-31T16:14:06.457

0

Another mechanism (to add to others' responses) is gnome-power-cmd.sh if you are using Gnome:

gnome-power-cmd.sh {suspend | shutdown | hibernate | reboot}

It appears to use DBUS. I don't know how useful that will be if you plan on running a server w/out Gnome though.

Not Sure

Posted 2010-12-31T15:13:11.853

Reputation: 111

Looks like this isn't generally found in newer distro's? – Ashimema – 2011-02-09T17:40:03.097

@Ashimema: you're right, sorry. I haven't upgraded my distro for ~ 2 years now. You may have already seen this, but I found a way to do this with dbus-send directly. In fact, my gnome-power-cmd.sh looks like a wrapper (with a few differences) around the solution presented in that link.

– Not Sure – 2011-02-20T00:12:50.240