Pages

January 27, 2015

RHEL 6: Using linux cgroups as universal start/stop script

Have you ever had to deal with programs, which dont have correct start/stop scripts written and they are spawning many processes?

Maybe this universal start/stop script will help you. First enable cgroups support in OS, this is example for RHEL 6:

chkconfig cgconfig on 
chkconfig cgred on

and reboot.

Now comes script.

What you have to specify is STARTFILE - name of program, which doesnt have correct start/stop script and does spawn many other programs as children. Next specify unique name for CGROUP, under which we will track PIDs of spawned children. It can be any name. (#exec line I use for debugging, is not really needed).

In start part, I send pid of current (this) script running to prepared cgroup, which does tracking of pids for us. Then I run script STARTFILE as user "username".

In stop part script first send kill to all pids in CGROUP, after 1 second checks if there are any pids still running and if yes, after 10 seconds it sends kill -9. You can increase this delay, or even make a loop to periodicaly check for pids existence, its up to you.


# cat /etc/init.d/impex-onl
#!/bin/bash
#exec >> /tmp/testing 2>&1

STARTFILE=/opt/cdaenvs/suprod/work/impex-onl/bin/impex-start.sh
CGROUP=impexonl

#### dont edit after this line ##### 
PIDFILE=/cgroup/cpu/$CGROUP/tasks

existing_pids () {
 ( ps --no-header -e -o pid | tr -d ' ' ; cat $PIDFILE ) | sort | uniq -d
}

cgcreate -g cpu:$CGROUP

start() {
 echo "echo $$ > $PIDFILE"
 echo $$ > $PIDFILE
 echo "starting $STARTFILE" >> /dev/stderr
 su -l -c "$STARTFILE" username
}

stop() {
 existing_pids | while read i; do
  kill $i
 done
 sleep 1

 lines=`existing_pids|wc -l`
 if test "$lines" -gt 0; then
  sleep 10;
  existing_pids | while read i; do
   kill -9 $i
  done
 fi
}

# See how we were called.
case "$1" in
  start)
	start
	;;
  stop)
	stop
	;;
  status)
	echo -n "Pids of running $CGROUP processes: " >> /dev/stderr
	existing_pids | xargs echo >> /dev/stderr
	lines=`existing_pids|wc -l`
	if test "$lines" -gt 0; then
	 exit 0
	else
         exit 3
	fi
	;;
  restart|reload|force-reload)
	stop
	start
	;;
  *)
	echo $"Usage: $0 {start|stop|status|restart|reload|force-reload}"
	exit 1
esac

exit 0

No comments:

Post a Comment