Wednesday 14 September 2016

Make programs startup on boot on Linux

For all of you who have servers out there, you know a reboot is sometimes unavoidable, and in most modern systems it is as simple and painless as sudo reboot now  or on some other systems sudo shutdown -R now  (I think?!?), anyway, sometimes these machines reboot on their own, maybe a software update went through, or some program thought it funny to send the reboot command, in any case it does happen. And then you get that lovely call from the clients "it's not working" and you can't figure out why the webpage isn't showing but you can ssh into the box fine and the firewall is allowing all the right traffic.  (if ofcourse it is running). So you use the top  command to see if you have some form of malware, and lo and behold you see uptime is 1 hour, the system rebooted and your web server isn't running, you start the web server and there we go problem solved. Which brings us into the reason for this post how to make it run on startup...

Now because I am pretty stupid myself I couldn't just read one tutorial, no, I read them all! and I am going to try and show you the simplest and easiest way of doing it, but first let's discuss runlevels, a deceptively simple concept, that I couldn't wrap my head around. runlevels are basically a state the machine is in, such as state 0. halt. which basically means the system is about to shutdown now. There are usually 7 run levels numbered from 0 - 6 (programmers are iffy about where we start counting), as I already mentioned 0 which means the system is going to shutdown, there is 6. Reboot, which is pretty obvious, it is the state of the machine right before a reboot, it is said to be in runlevel 6. I am going to use Centos as the linux OS here but the ideas apply almost universally. Centos inherits the following runlevels from RHEL:

  • 0 — Halt
  • 1 — Single-user text mode
  • 2 — Not used (user-definable)
  • 3 — Full multi-user text mode
  • 4 — Not used (user-definable)
  • 5 — Full multi-user graphical mode (with an X-based login screen)
  • 6 — Reboot

Now I don't think I am going to go indepth of what each one means but here are the basics, when the systems boots into single user no-network, no GUI mode (usually for diagnostics), it runs in level 1 obviously until the shutdown or reboot command is called where it is briefly in either runlevel 0 or 6 before it goes down. runlevels 2 and 4 are not used (these can actually be customised). The machine is said to run in level 3 when it is booted in multi user mode with networking but no GUI, meaning it only has terminals. This is sometime used in Server environments as GUI is computationally expensive and really unnecessary. But for most people when they startup their Centos machine it starts in level 5 which has all the bells and whistles including X server which gives you a pretty GUI to look at.  Now the important thing to know here is that the init process calls services and scripts to start according to runlevels. for example init will call all the services neccessary in runlevel 3 to have multiple users log on. but it won't actually call any GUI services. These it will only call in level 5. Init does its runlevel magic as soon as the system goes into a runlevel. From there it allows the user to start and stop whatever they want. How is this helpfull? well you can tell the system that you want your script to start at whichever runlevel you want, making it really simple to have a custom program run when the machine is booted or hell even as soon as the shutdown command is sent. To do this there are basically two major steps: create the init.d script and add this script to the right runlevels. now for this post I am going to make Tomcat start on boot. (the following assumes you are root or atleast have sudo privileges)

Create init.d script
This is a basic startup shell script that shows the machine how to start your program and where to find it. for tomcat I have the following script.



#!/bin/bash
# chkconfig: 2345 80 20
# Description: Tomcat Server basic start/shutdown script
# /etc/init.d/tomcat -- startup script for the Tomcat servlet engine

TOMCAT_HOME=/opt/tomcat/bin
START_TOMCAT=/opt/tomcat/bin/startup.sh
STOP_TOMCAT=/opt/tomcat/bin/shutdown.sh


start() {
echo -n "Starting tomcat: "
cd $TOMCAT_HOME
${START_TOMCAT}
echo "done."
}

stop() {
echo -n "Shutting down tomcat: "
cd $TOMCAT_HOME
${STOP_TOMCAT}
echo "done."
}

case "$1" in

start)
start
;;

stop)
stop
;;

restart)
stop
sleep 10
start
;;

*)
echo "Usage: $0 {start|stop|restart}"

esac
exit 0

Edit the highlighted part to point to your tomcat installation (or the start and stop scripts of your program)  and then save this as /etc/init.d/tomcat. Then we have one more command to make this script accessible to anyone.
chmod 755 /etc/init.d/tomcat

Now that we have this script we have one more command to run to add it to the correct runlevels
chkconfig --add tomcat 

 To check that the runlevels are correct run 
 chkconfig  --list tomcat
It will produce something like this:
tomcat 0:off 1:off 2:on 3:on 4:on 5:on 6:off
Where it shows at which runlevels this script is on or off
 
To test this script you can try
service tomcat start
or
service tomcat stop
or
service tomcat restart 

To have a little bit more control over which runlevels your script runs in, is simple:
chkconfig --level 345 tomcat on
 
This switches tomcat on for levels 3,4 and 5.
And there you go creating a custom init script and making it run on boot.
 
I hope this helps you guys gain a little more control over your machines, if you have any questions, you are welcome to leave a comment or drop me an email.
Happy Hacking
MiniMite