Thursday, June 4, 2015

Linux Runlevels and using it for Automated Startup or Shutdown



This example is based on the version Linux 5.

A runlevel defines the state of the machine after boot. In Simple we can say as the mode in which you want the system to be restated, it is just like in windows while the system is booting up we will have option like start with safe mode, Networking and so on.

Different runlevels are typically assigned to the single-user mode,
multiuser mode without network services started, multiuser mode with network services started, system shutdown, and system reboot system states.

The different run level action can be viewed from as below.

# cat /etc/inittab


#####################################################################
# Default runlevel. The runlevels used by RHS are:
#   0 - halt (Do NOT set initdefault to this)
#   1 - Single user mode
#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
#   3 - Full multiuser mode
#   4 - unused
#   5 - X11
#   6 - reboot (Do NOT set initdefault to this)
#####################################################################


As you can see for 0 and 6 it is mentioned as do not set, this is because we dont want our system to shutdown (runlevel 0) or
reboot (runlevel 6) immediately once our system boots.

To know the default run level in which your system is configured type as below.

[root@standalone2 rc0.d]# runlevel
N 5

We get the output as 5 which means by default the system is configured to start at run level 5.

you can also see that there are directories like rc0.d, rc1.d, rc2.d, rc3.d, rc4.d, rc5.d, rc6.d under the /etc folders, these directories contains the files/scripts which to be called during the runlevel. Normally the files under this will start with S which is for start and K which is for to kill the process/service.

Using these run levels you can configure your script to start/stop services during shutdown/start/reboot of the system.


Now here my system is running in runlevel 5, now i need to schedule a script to do some action based on runlevels.

Parameter will be passed as start with S and parameter stop will be passed with K automatically by the system.


Now we need to configure the script like as below.

Runlevel 0  - stop
Runlevel 1  - stop
Runlevel 2  - stop
Runlevel 3  - stop
Runlevel 4  - stop
Runlevel 5  - start
Runlevel 6  - stop


Below is the sample script. Named as testme

#################################################################
#!/bin/bash
#
#
case $1 in
"start")
        echo `date` >> /home/oracle/startup.log
        echo 'startup' >> /home/oracle/startup.log
        ;;
"stop")
        echo `date` >> /home/oracle/shutdown.log
        echo 'shutdown' >> /home/oracle/shutdown.log
        ;;
esac
#################################################################

Copy the sciprt inside the /etc/init.d directory.

We will give a sequence number as 40 for this script.

Now we need to create a symbolic link file under the appropirate run level directories.


[root@standalone2 init.d]# cd /etc/rc0.d/
[root@standalone2 rc0.d]# ln -s /etc/init.d/testme K40testme
[root@standalone2 rc0.d]# ls -lrt K40testme
lrwxrwxrwx 1 root root 18 Jun  4 04:10 K40testme -> /etc/init.d/testme

Create the same in all the directories except rc5.d.

K40testme ( Refers K for kill which will pass the parameter as stop , 40 is the sequence or order in which the script
has to be executed, testme is the mainfile)

[root@standalone2 rc1.d]# cd ../rc2.d/
[root@standalone2 rc2.d]# ln -s /etc/init.d/testme K40testme
[root@standalone2 rc2.d]# cd ../rc3.d/
[root@standalone2 rc3.d]# ln -s /etc/init.d/testme K40testme
[root@standalone2 rc3.d]# cd ../rc4.d/
[root@standalone2 rc4.d]# ln -s /etc/init.d/testme K40testme
[root@standalone2 rc4.d]# cd ../rc6.d/
[root@standalone2 rc6.d]# ln -s /etc/init.d/testme K40testme

and in rc5.d create as below.

[root@standalone2 rc5.d]# ln -s /etc/init.d/testme S40testme
[root@standalone2 rc5.d]# ls -lrt S40*
lrwxrwxrwx 1 root root 18 Jun  4 04:13 S40testme -> /etc/init.d/testme



As you can see the testme script is showing as off for all the run levels except 5.

Lets test the script now.

Now am running runing runlevel 6 (init 6) which will reboot the system, also as per
our script it should first call the stop and while booting it will call the runlevel 5 so
our script should start.

[root@standalone2 rc5.d]# init 6

== Once the server is up we could see that the script has been executed successfully.

[oracle@standalone2 ~]$ cd /home/oracle
[oracle@standalone2 ~]$ ls -lrt startup.log
-rw-r--r-- 1 root root 144 Jun  4 05:23 startup.log

---------------------------------------------------------------------

Instead of manually creating links we can use chkconfig to automate the process.



Here we will use script to bring up an oracle database online when system starts.

Oracle database comes with default script dbstart and dbshut will can be used for this purpose.

to use this, create a script as below.


#!/bin/bash
#
# chkconfig: 35 99 10
# description: Auto start/stop of database
#
# Set ORA_HOME to the Oracle Home where the lsnrctl and dbstart
# commands can be found
ORA_HOME=/u01/app/oracle/product/11.2.0.3/dbhome_1
# Set ORA_OWNER to the owner of the Oracle software
ORA_OWNER=oracle
LCKFILE=/var/lock/subsys/ora_db_start
case "$1" in
    'start')
           # Start the listener:
  touch $LCKFILE
           su - $ORA_OWNER -c "$ORA_HOME/bin/lsnrctl start"
           # Start the databases:
           su - $ORA_OWNER -c $ORA_HOME/bin/dbstart
    ;;
    'stop')
           # Stop the listener:
  rm -f $LCKFILE
           su - $ORA_OWNER -c "$ORA_HOME/bin/lsnrctl stop"
           # Stop the databases:
           su - $ORA_OWNER -c $ORA_HOME/bin/dbshut
    ;;
esac



Save the filename as ora_db_start in /etc/init.d


Now we need to set the run levels of this.

You can either manually create links under the rc folders or can use chkconfig which will automatically creates
the links files.

# chkconfig --add ora_db_start


-- you can see that the script ora_db_start it contains chkconfig: 35 99 10 where 35 is the 3 and 5 runlevels which
should be on and other run levels should be off, 99 is the Start sequence and 10 is the kill sequence.


===============

You can also create a user defined script if required, as per below.


Create a script as oracle_db under /etc/init.d/ with below contents.

#!/bin/bash
#
# chkconfig: 35 99 10
# description: Starts and stops the Oracle listener and database
#
# Define variables for use in this script
export ORACLE_HOME=/u01/app/oracle/product/11.2.0.3/dbhome_1
ORA_OWNER=oracle
case "$1" in
    'start')
           touch /var/lock/subsys/oracle_db
           # Start the databases:
           su - oracle -c $ORACLE_HOME/bin/db_startup.sh
    ;;
    'stop')
           rm -f /var/lock/subsys/oracle_db
           # Stop the databases:
           su - oracle -c $ORACLE_HOME/bin/db_shutdown.sh
        ;;
esac



Create the below scripts as oracle user under the $ORACLE_HOME/bin directory.


db_startup.sh

#!/bin/bash
export ORACLE_HOME=/u01/app/oracle/product/11.2.0.3/dbhome_1
export ORACLE_SID=testdb
export PATH=$ORACLE_HOME/bin:$PATH
sqlplus -s "/ as sysdba" <> /u01/app/oracle/product/11.2.0.3/dbhome_1/db_startup.log
startup;
exit;
EOF


db_shutdown.sh

#!/bin/bash
export ORACLE_HOME=/u01/app/oracle/product/11.2.0.3/dbhome_1
export ORACLE_SID=testdb
export PATH=$ORACLE_HOME/bin:$PATH
sqlplus -s "/ as sysdba" <> /u01/app/oracle/product/11.2.0.3/dbhome_1/db_shutdown.log
shutdown immediate;
exit;
EOF


Now set the run levels for the script.


[root@standalone2 ~]# chkconfig --add oracle_db

[root@standalone2 ~]# chkconfig --list oracle_db
oracle_db       0:off   1:off   2:off   3:on    4:off   5:on    6:off

As you can see the run level are set on for 3 and 5 and for the remaining it is off, you can also
verify the symbolic link files.


Now Lets check whether it is working as expected, currently the db is up and running.


[root@standalone2 ~]# init 6


--Once the server is up we could see that the db is up and running.

verifying the logs.

[oracle@standalone2 dbhome_1]$ ls -lrt *.log

-rw-r--r-- 1 oracle oinstall   65 Jun  4 08:07 db_shutdown.log
-rw-r--r-- 1 oracle oinstall  466 Jun  4 08:10 db_startup.log

[oracle@standalone2 dbhome_1]$ cat db_shutdown.log
Database closed.
Database dismounted.
ORACLE instance shut down.


[oracle@standalone2 dbhome_1]$ cat db_startup.log
ORACLE instance started.

Total System Global Area  680607744 bytes
Fixed Size                  2231472 bytes
Variable Size             406848336 bytes
Database Buffers          268435456 bytes
Redo Buffers                3092480 bytes
Database mounted.
Database opened.
ORACLE instance started.


-- Run levels are working fine as expected.










No comments:

Post a Comment