Runlevels , rc.d Scripts and Copy System Logs to S3

Prabhu Rajendran
Everything at Once
Published in
7 min readOct 9, 2019

As you might have read about How Linux Boots it uses runlevels to determine what to do.Lets study runlevels and rc scripts in detail.

Runlevels:

Runlevels are the state to which computer intends to go or it intends to reach.

There are total 7 runlevels.

  1. Runlevel 0: Halt or Shutdown
  2. Runlevel 1: Single-user mode
  3. Runlevel 2: Basic Multi-user mode but without networking
  4. Runlevel 3: Full text-based Multi-user mode (includes networking)
  5. Runlevel 4: X11 with session managers (Generally not used by most of the operating systems and is customizable)
  6. Runlevel 5: Full GUI based Multi-user mode
  7. Runlevel 6: Reboot

These are basic definitions what each runlevel is responsible for.

For Example : if an operating system is required to shutdown , then it go for runlevel 0. we can switch between runlevels using init command.(init 0).

init 0 system to shutdown

init 0 will shutdown the system. And Each System has a default runlevel to which it boots. To see which runlevel you are in type runlevel in terminal.

Runlevel and target file have the following relation:

  1. runlevel 0: poweroff.target
  2. runlevel 1: rescue.target
  3. runlevel 2: multi-user.target
  4. runlevel 3: multi-user.target
  5. runlevel 4: multi-user.target
  6. runlevel 5: graphical.target
  7. runlevel 6: reboot.target

We should never mess with the default runlevels unless you are absolutely sure with what you’re doing.Like, if you manage to set runlevel 0 or 6 as default you will end up in a loop kind of condition. Your PC will shut down( or reboot depending on what runlevel you set) as soon as it has booted.

rc Scripts :

When a computer entered into specific runlevel,it runs scripts according to the runlevel it’s in.The rc here comes from use in the older computers which had rc files to contain commands that run at start up.

These files are called runcom (RunCommand) files.

Our Script Must contain the line before any command executes.

. /etc/init.d/functions

This is because , our script might be executed at a time when nothing is loaded, not even file system (though it can be specified in boot facilities in “Required-Start” in LSB styled stanzas). So we cannot say that each command we write will already be present — Remember that each command is executed from a SCRIPT present in path variable from our system). hence in order for those commands to work, we need the functions file to be loaded as the first step.

This function file contains the function that a shell script might use.(files are located in /etc folder) The folders containing these scripts are:

/etc/init.d
/etc/rc.d/rc0.d
/etc/rc.d/rc1.d
/etc/rc.d/rc2.d
/etc/rc.d/rc3.d
/etc/rc.d/rc4.d
/etc/rc.d/rc5.d
/etc/rc.d/rc6.d

And, folders with the same name also exist in /etc but they are actually symbolic links of there corresponding folders in /etc/rc.d For example:

/etc/rc0.d (Symbolic link of /etc/rc.d/rc0.d)

Each of these folders contain symbolic links of scripts that are actually stored in init.d for the runlevel they have in their name. Like /etc/rc.d/rc0.d contains a symbolic link for scripts in /etc/init.d that are required to be run at shutdown.

Now if you open any of these folders you’d find out weird names with the structure like

S|K[01-99]filename where filename is the name of the script in /etc/int.d

Like K50netconsole. Now let’s see what these names mean.

Demystifying the symlink names:

The terms have their meaning as follows:

  1. S: start the service, if it’s not already started.
  2. K: Kill the service, if it’s running.

01–99 is the priority for that start or kill task.

filename is the exact same name of the file in /etc/init.d folder.(Remember that it’s actually /etc/init.d that actually houses those scripts. Rest of the folders just have symlinks to these.)

So, If a file named shutdown-script is to be run at shutdown all times with a priority of 90 then the file shutdown-script should be present in init.d folder. And a symlink to it must be created in /etc/rc.d/rc0.d with the name S90shutdown-script, rest of the folders rc[1-6] can have K90shutdown-script. If 90 is the priority required to shut down.

Priority Of these scripts:

Essentially, it can be better thought of as a position, and think of them being executed downwards from 01 to 99. For example, if you have a script that requires the network to be switched on then the network script should be at a higher position or priority than your script. Like the network, a script can have a priority of 01 and your script can have any number greater than it. So that it’s executed after the network script.

The chkconfig:

the chkconfig command here deserves the ‘The’ in the heading for how easy it makes to manage these scripts and runlevels! Yes, this command just needs your source script file and manages creation deletion, the setting of S or D and also the priority level!

chkconfig has an amazing man page and here are the basic commands that will get you going.

chkconfig --list

This prints the System V services, and that will do for us.

chkconfig --add

Is used to add your file for management by chkconfig. BUT wait. This command won’t run unless you have some things set with your script.

First and foremost, your script should exist in the home of all scripts, and that is:

/etc/init.d

Paste your script here.

Secondly, your file must have certain comment lines so that it can be managed by chkconfig.

It must have these comment lines, though the description is not absolutely necessary and the script would work without it, it’s recommended. So that anyone who intends to clean up the unnecessary services knows if this script is essential or not:

# chkconfig: 235 29 88
# description: The description of the script like what it does

The first line here has some numbers ahead chkconfig: like 235, 29 and 88.

here the First number is the runlevels it’s required to run on combined into a string. Like 235 here means it’s supposed to run in runlevel 2,3 and 5.

The next two numbers are the priority for start and stop respectively. So in this example, start priority is 29 and stop priority is 88.

you can use backslash for a multi line comment though you still require a #, in the beginning, to identify it as a comment.

This is how it creates the symlinks with required priorities.

Another way you can do this is enter LSB(Linux Standard Base) style init stanzas instead of these two comments. For it you can do it like:

### BEGIN INIT INFO
# Provides: scriptA
# Required-Start: scriptB
# Default-Start: 2 3 5
# Default-Stop: 0 1 6
# Description: Description of what the script does
### END INIT INFO

This one gives you more ease though it just looks a bit more complicated.

In this, Required-Start is the script that is required to start this script. That is, it should be running before the current script gets up. Provides: It tells about the boot facilities that this script provides so that those will be counted as already present when another script requires it. Hence priorities will be set accordingly to what is required to be already present and what it'll provide. Default-Start or Stop tells which runlevel should this start on and stopped(if running) respectively.

And don’t forget a shebang at the beginning of the file.

Now we are all set to go with these things done. Let’s execute this command to add it to the management of chkconfig:

chkconfig --add $filename

like for a file named ec2-copylog in init.d it would be:

chkconfig --add ec2-copylog

Now most probably your file will be visible with a status of on under the respective runlevels when you run

chkconfig --list

And if it’s not or you want to change runlevels you can go like:

chkconfig ec2-copylog --level 0 on

Will make it run on runlevel 0 that is at shutdown.

Similarly off argument will kill it if present in that level. If no level is specified then these act on level 2,3,4 and 5. You can also specify multiple levels like --level 26 for level 2 and 6.

chkconfig --del ec2-copylog

will delete its symlinks from all rc folders but not from the init.d folder. That is required to be done manually. Ad chkconfig generally doesn’t modify the content of init.d but rc folders.

Example ec2-copy log : (under /etc/init.d/ec2-copylog)

#!/bin/sh
#
# ec2-copylog
#
# chkconfig: 3 11 01
# Description: This script is responsible for copying logs S3
# as a daemon
#
### BEGIN INIT INFO
# Provides: ec2-shutdown-hook
# Required-Start: network
# Required-Stop: network
# Default-Start: 3
# Default-Stop:
# Description: This script is responsible for copying logs S3
# as a daemon.
### END INIT INFO

. /etc/init.d/functions

copylog() {
echo -n $"Starting Copying logs: "
HOSTIP=${HOSTNAME:-default}
SOURCEFOLDER="$directory from where we need to copy"
BUCKETTOCOPY="$bukcetname"
CURRENTDATE=$(date +"%d-%m-%Y")
DIRECTORY="${HOSTIP}-${CURRENTDATE}"
echo Copying from $SOURCEFOLDER to Bucket $BUCKETTOCOPY Directory $DIRECTORY
aws s3 cp $SOURCEFOLDER s3://$BUCKETTOCOPY/$DIRECTORY --recursive
}

case "$1" in
start)
touch /var/lock/subsys/ec2-shutdown-log
;;
restart|force-reload|stop)
copylog
rm -f /var/lock/subsys/ec2-shutdown-log
;;
*)
copylog
rm -f /var/lock/subsys/ec2-shutdown-log
exit 0
esac

Thank you for reading!

--

--