20 June 2010

Updated Hamachi keep-alive script

Last Updated on June 25, 2010.

I modified the hamachi wrapper script with two functionalities:
  • do NOT restart hamachi if there is nobody to ping
  • DO restart hamachi if there are unreachable hosts
  • DO restart hamachi if its CPU usage goes over 50% - this partly solves the 100% CPU usage problem of hamachi
  • if you modify the script name, the script should keep working - it even works if there is a space in the filename


scriptname="`basename \"$0\"`"

function command_pids {
for p in `ps xo pid,command | grep "$1"`; do
    IFS=' ' hampid=( $p )
    if [ ".`basename ${hampid[1]}`" == ".hamachi" ]; then RES="${RES} $pid"; fi
echo $RES;

function hamachi_force_terminate {
    hamachi stop >/dev/null
    sleep 1
    for ham_pid in $( command_pids hamachi ); do
        kill -9 $ham_pid

if [ `echo $( command_pids hamachi ) | wc -w` -eq 0 ]; then
    #echo "count not detect running hamachi"
    hamachi_pcpu=`ps ho pcpu $( command_pids hamachi )`
    if [ `echo $( command_pids hamachi ) | wc -w` -gt 1 ]; then
        echo "multiple running hamachi instances - terminating"
        if [ `echo "$hamachi_pcpu > 50" | bc` -eq 1 ]; then 
            echo "high CPU usage hamachi instances - terminating"

if [ `ip r | grep default -c` -lt 1 ]; then
    # No internet gateway, exiting!
    exit 1

hamachi_online=`hamachi list | egrep '\* [0-9]' | awk '{print $2}'`
count_unreachable=`hamachi list | egrep 'x [0-9]' | wc -l`

for IP in $hamachi_online; do
    ping -c 2 $IP >/dev/null
    if [ $? -ne 0 ]; then
        echo "ping $IP failed!"
        hamachi list | grep $IP
    fi # if first ping fails then ping is not OK!

if [ $hamachi_running -ne 1 -o $count_unreachable -gt 0 -o $ping_ok -eq 0 ]; then
    echo "restarting hamachi: running $hamachi_running unreachable $count_unreachable ping $ping_ok"
    if [ `pgrep tuncfg | wc -l` -eq 0 ]; then sudo /sbin/tuncfg; fi
    hamachi start
    echo -n "Logging in... " ;
    while [ `hamachi login | grep -c failed` -eq 1 -a $CNT -lt 100 ]; do 
        echo -n "$CNT "; 
        let CNT=$CNT+1; 
        sleep 2; 
    sleep 2;
    hamachi get-nicks
    #echo "hamachi is online"


Lordblacksuca said...

Hi, i have used this script, it work well but when hamachi goes offline, it restart it, and then the script freeze when "loggin in..." and never show the list of connected people

Saša Tomić said...

Can you give me some additional information?

What Linux version are you using?
At what line is the script failing (if you can find the line)?
Do you get any output from the script?

Lordblacksuca said...

Well, I am running ubuntu 9.04 server

I modified your script, becouse an error on line 36 "Command not found - [: -eq: unary operator expected"

so, I erase this
30 hamachi_pcpu=`ps ho pcpu $( command_pids hamachi )`
31 if [ `echo $( command_pids hamachi ) | wc -w` -gt 1 ]; then
32 echo "multiple running hamachi instances - terminating"
33 hamachi_force_terminate
34 hamachi_running=0
35 else
36 if [ `echo "$hamachi_pcpu > 50" | bc` -eq 1 ]; then
37 echo "high CPU usage hamachi instances - terminating"
38 hamachi_force_terminate
39 hamachi_running=0
40 fi
41 fi

The script freeze on loggin when I execute it manually. when cron execute it, in the terminal I have a "connect(): Conection Refused" Mesage.

Saša Tomić said...

OK, to solve the cron problem, you should allow running tuncfg without password.

Run in the terminal:

sudo visudo

then append the following line:

%admin ALL=NOPASSWD: /sbin/tuncfg

enter it _exactly_ like this, including the percent sign (%)

I'll now try running the script in Ubuntu 9.04 in virtualbox to try and reproduce the problem.

Saša Tomić said...

also, when you make a crontab entry, do it with your username.
So, in your terminal run:

$ crontab -e

and then add line

*/5 * * * * $HOME/bin/hamachi_watchdog.sh

or something like that

Saša Tomić said...

I found some hamachi race condition on Ubuntu 9.04
Adding a 2 second delay ("sleep 2") after "hamachi login" seems to have solved it

Try the new script now...

Lordblacksuca said...

will try it and comment the result here.

Lordblacksuca said...

it works very nice now! I just add the line in visudo and add the sleep 2; after login.

Thanks so much.

Saša Tomić said...

Great! I'm very happy to hear that!