- 2.7 Init scripts¶
- Runlevels¶
- Boot sequence¶
- Init scripts¶
- How init works¶
- What is a runlevel?¶
- Working with init scripts¶
- Using rc-update¶
- What is rc-update?¶
- Adding and removing services¶
- Configuring services¶
- Why do you need extra configuring?¶
- The /etc/conf.d directory¶
- Writing initscripts¶
- Do I really have to?¶
- Layout¶
- Dependencies¶
- Startup order¶
- Standard functions¶
- Adding custom options¶
- Service Configuration Variables¶
- Changing the runlevel behavior¶
- Who benefits from this?¶
- Using softlevel¶
- Using bootlevel¶
- Linux Explore
- Exploring Linux
- All about Linux init script
- What is an init script?
- Writing sample init script
- Explaining and enhancing sample init script
- Start a init script like a simple shell script
- Comment but no comment, chkconfig in comment, to set start and stop in init script
- Functions creation is helpful in init script
- case esac to accept the init script arguments
- Finalize and Execute the init script
- Adding sample init script to start at boot
- Deleting sample init script boot from system boot
- Use of service command with init script
2.7 Init scripts¶
Runlevels¶
Boot sequence¶
When you boot your system, you will notice lots of text floating by. If you pay close attention, you will notice this text is the same every time you reboot your system. The sequence of all these actions is called the boot sequence and is more or less statically defined.
First, your boot loader will load the kernel image you have defined in the boot loader configuration. The kernel is then loaded. When it is loaded and run, it initializes all kernel-specific structures and tasks and starts the init process.
This process then makes sure that all filesystems (defined in /etc/fstab ) are mounted and ready to be used. Then it executes several scripts located in /etc/init.d , which will start the services you need for a successful booting.
Finally, when all scripts are executed, init activates the terminals (in most cases just the virtual consoles which are hidden beneath ALT+F1 , ALT+F2 , etc.), attaching a special process called agetty to each console. This process will then allow you to log on through these terminals by running login .
Init scripts¶
Now init does not run the scripts from /etc/init.d randomly. Even more, it doesn’t run all scripts in /etc/init.d , but only the scripts it is told to execute. It decides which scripts to execute by looking into /etc/runlevels .
First, init runs all scripts from /etc/init.d , that have symbolic links in /etc/runlevels/boot . Usually, it will start the scripts in alphabetical order, but some scripts have dependency information in them, telling the system that another script must be run before they can be started.
When all /etc/runlevels/boot referenced scripts are executed, init continues with running the scripts that have a symbolic link to them in /etc/runlevels/default . Again, it will use the alphabetical order to decide what script to run first, unless a script has dependency information in it, in which case the order is changed to provide a valid start-up sequence.
How init works¶
Of course, init makes no decisions by itself. It needs a configuration file that specifies what actions need to be taken. This configuration file is /etc/inittab .
If you remember the boot sequence we have just described, you will remember that init ‘s first action is to mount all filesystems. This is defined in the following line from /etc/inittab :
This line tells init to run /sbin/rc sysinit in order to initialize the system. The /sbin/rc script takes care of the initialization, so you might say that init does not do much, it delegates the task of initialising the system to another process.
Second, init executes all scripts that have symbolic links in /etc/runlevels/boot . This is defined with the following line:
Again the rc script performs all necessary tasks. Note that the option given to rc (boot) is the same as the subdirectory of /etc/runlevels that is used.
Now init checks its configuration file to see what runlevel it should run. To decide this, it reads the following line from /etc/inittab :
In this case (which will suit the majority of Calculate users) the runlevel id is 3. Using this information, init checks what it has to do to run runlevel 3. Here is an example of runlevels
The line that defines level 3, again, uses the rc script (now with the default argument). Note again that the argument of the rc script is the same as the subdirectory from /etc/runlevels .
When rc has finished, init decides which virtual consoles it should activate and what commands need to be run at each console. Here is an example of how virtual consoles are defined:
What is a runlevel?¶
You have seen that init uses a numbering scheme to decide what runlevel it should activate. A runlevel is a state in which your system is running and contains a collection of scripts (runlevel scripts or init scripts) that must be executed when you enter or leave a runlevel.
Seven runlevels are defined in Calculate: three internal runlevels, and four user-defined runlevels. The internal runlevels are called sysinit, shutdown and reboot. They do exactly what their names imply: initialize the system, powering off the system and rebooting the system.
The user-defined runlevels are those with an accompanying /etc/runlevels subdirectory: boot, default, nonetwork and single. The boot runlevel starts all system-necessary services which all other runlevels use. The remaining three runlevels differ in what services they start: default is used for day-to-day operations, nonetwork is used in case no network connectivity is required, and single is used when you need to fix the system.
Working with init scripts¶
The scripts that the rc process starts are called init scripts. Each script in /etc/init.d can be executed with the arguments start, stop, restart, pause, zap, status, ineed, iuse, needsme, usesme and broken.
To start, stop or restart a service (and all depending services), start , stop and restart should be used. That’s how you start postfix, for example:
Note: Only the services that need the given service are stopped or restarted. The other depending services (those that use the service but don’t need it) are left untouched.
If you want to stop a service, but not the services that depend on it, you can use the pause argument:
If you want to see what status a service has (started, stopped, paused, etc.), you can use the status argument. See an example below:
If the status information tells you that the service is running, but you know that it is not, then you can reset the status information to «stopped» with the zap argument. For postfix, thus, you will have to enter:
If you need to know what are the service’s dependencies, you can use the iuse or the ineed arguments. With ineed , you can see the services that are really necessary for the correct functioning of the service. iuse , on the other hand, shows the services that can be used by the service, but are not necessary for the correct functioning. Once more, let’s apply this to the postfix service, for instance:
Finally, you can ask for the list of the dependencies the service requires that are missing:
Using rc-update¶
What is rc-update?¶
Calculate’s initialization system uses a dependency-tree to decide which services need to be started first. As this is a tedious task our users should not have to do manually, tools were created that ease the administration of the runlevels and init scripts.
With rc-update , you can add and remove init scripts to a runlevel. The rc-update tool will then automatically ask the depscan.sh script to rebuild the dependency tree.
Adding and removing services¶
The rc-update script requires a second argument that defines the action: add, del or show.
To add or remove an init script, just give the rc-update an add or del argument followed by the init script and the runlevel. If you wanted to remove postfix from the default runlevel, you would enter:
If you run rc-update show , a list of all enabled init scripts and their runlevels will be shown:
Configuring services¶
Why do you need extra configuring?¶
Init scripts can be quite complex. It is therefore not really desirable to have the users edit the init script directly, as it would make it more error-prone. It is however important to be able to configure such a service. For instance, you might want to give more options to the service itself.
A second reason to have this configuration outside the init script is to be able to update the init scripts without the risk that your configuration changes will be undone.
The /etc/conf.d directory¶
Calculate provides an easy way to configure such a service: every init script that can be configured has a file in /etc/conf.d . For example, the apache2 (called /etc/init.d/apache2 ) has a configuration file called /etc/conf.d/apache2 , which can contain the options you want to give to the Apache 2 server when it is started. Here is an example of a variable defined in /etc/conf.d/apache2 :
Such a configuration file contains variables and variables alone (like /etc/make.conf), making it very easy to configure services. It also allows us to provide more information about the variables (as comments).
Writing initscripts¶
Do I really have to?¶
No, writing an init script is usually not necessary as Calculate provides ready-to-use init scripts for all provided services. However, you might have installed a service without using Portage, in which case you will most likely have to create an init script.
Layout¶
The basic layout of an init script is shown below.
Any init script requires the start() function to be defined. All the other functions are optional.
Dependencies¶
There are two dependency-alike settings you can define that influence the start-up or sequencing of init scripts: use and need . The need dependency is harder than the use dependency. The name of the service requiring a dependency or a link to a virtual dependency are put after the service’s type.
A virtual dependency is a dependency that a service provides, but that is not provided solely by that service. An init script can depend on a system logger, but there are many system loggers available (metalogd, syslog-ng, sysklogd, . ). As you cannot need every single one of them (no sensible system has all these system loggers installed and running), all these services provide a virtual dependency.
Let us take a look at the dependency information for the postfix service.
As you can see, postfix:
- requires the net service: a virtual dependency provided, for instance, by /etc/init.d/net.eth0 ;
- uses the logger: a virtual dependency provided, for instance, by /etc/init.d/syslog-ng ;
- uses the dns service: a virtual dependency provided, for instance, by /etc/init.d/named ;
- provides the mta service: a virtual dependency common for all mail servers.
Startup order¶
Sometimes you do not need the service itself, but that is be started before (or after) another service, if it is enabled (note the if: this is not a dependency any more) and run in the same runlevel (note that this only about services of the same runlevel). This ordering is handled through the order settings before or after .
Let us have a look at the depend() function in the Portmap service:
You can also use «*» to catch all services in the same runlevel, although this is not advisable. Below is an example of running a script as first script in the runlevel:
Standard functions¶
After the depend() functionality, you will also need to define the start() function. It contains all the commands necessary to initialize your service. It is advisable to use the ebegin and eend functions to inform the user about what is happening. Here is a example of a start() function:
If you need more examples of the start() function, please read the source code of the available init scripts in your /etc/init.d directory. The start-stop-daemon function has an excellent man page available if you need more information. To view the man page on start-stop-daemon enter:
The stop() and the restart() functions can also be defined. You will not have to define them manually, though! Your init system is intelligent enough to fill in this function by itself if you use start-stop-daemon .
Calculate’s init script syntax is based on the Bourne Again Shell (bash), so you are free to use bash-compatible constructs inside your init script.
Adding custom options¶
If you want your init script to support more options than the ones we have already encountered, you should add the option to the opts variable, and create a function with the same name as the option. For instance, to support an option called restartdelay :
Service Configuration Variables¶
You don’t have to do anything to support a configuration file in /etc/conf.d : if your init script is executed, the following files are automatically sourced (i.e. the variables are available to use):
If your init script provides a virtual dependency (such as net ), the file associated with that dependency (such as /etc/conf.d/net ) will be sourced too.
Changing the runlevel behavior¶
Who benefits from this?¶
Many laptop users know the situation: at home you need to start net.eth0 while you don’t want to start net.eth0 while you’re on the road (as there is no network available). With Calculate you can alter the runlevel behaviour to your own will.
For instance you can create a second «default» runlevel which you can boot that has other init scripts assigned to it. You can then select at boottime what default runlevel you want to use.
Using softlevel¶
First of all, create the runlevel directory for your second «default» runlevel. Let us create the «offline» runlevel as an example. We will create the runlevel directory:
Add the necessary init scripts to the newly created runlevel. For instance, if you want to have an exact copy of your current «default» runlevel but without net.eth0 , type in:
Now edit your bootloader configuration and add a new entry for the «offline» runlevel. For instance, add in /boot/grub/grub.conf :
Here you are. If you boot your system and select the newly added entry at boot, the «offline» runlevel will be used instead of the «default» one.
Using bootlevel¶
Using bootlevel is completely analogous to softlevel. The only difference here is that you define a second «boot» runlevel instead of a second «default» runlevel.
Источник
Linux Explore
Exploring Linux
All about Linux init script
What is an init script, what is the use of it, how to write an init script? Lets begin to know the answers.
Declaimer: Use it at your own risk. Writing this topic for learning and knowledge sharing purpose only. You must own root privileges (and authority) on the system where you are trying or applying this topic.
What is an init script?
Keeping it simple, init script is just a shell script which always starts with shebang. It is used to start an application on boot time and stop on shutdown. It can also be used to restart and to send various other instructions to the application.
So how to write this init script?
Writing sample init script
So its a shell script, a simple case esac shell script. Lets take following example:
This is an example init shell script, which is using start, stop as argument. Executing this script with start argument will call start function and stop will call stop function, other than those arguments will give error “invalid argument” and exit with error status 1.
Explaining and enhancing sample init script
Now you have a sample script which is starting at boot time. So its time to understand it part by part and enhance it for some real use.
Start a init script like a simple shell script
Like every shell script, it is also starting with shebang #!/bin/sh and some comments about the script.
Comment but no comment, chkconfig in comment, to set start and stop in init script
In comment line of init script, chkconfig means when to start the service and when to stop and in which runlevel.
2345 after chkconfig: is showing the runlevels 2, 3, 4 and 5 where this init script will be started and other than that, like runlevels 0, 1 and 6, where it will be stopped.
After runlevel, 80 denotes the start sequence and 20 denotes the stop sequence.
So Don’t consider chkconfig as a comment in init script, set the start sequence and stop sequence as per the requirement.
NOTE: If same start and stop sequence is using in other scripts, init will sort them, to execute, by using there names.
Functions creation is helpful in init script
Functions in init script or in any shell script, makes it easy to read and understand. It helps to avoid code repetition.
For example, restart function can be added, which will use stop and start functions to restart the application.
Other important functions can also be added to script by using import method.
/etc/init.d/functions script contains several useful functions for init scripts like daemon (used to daemonize the application), killproc (To kill the running process id), status (to get the current status of running application or process id), etc.
So lets enhance our start and stop functions, by using some useful functions from /etc/init.d/functions script.
NOTE: Lock file creation in start and remove in stop is very important to write a perfect init script, to know more about it check my old post Use of Subsystem Lock Files in Init Scripts.
case esac to accept the init script arguments
Last but very essential part of init script is case esac. It also make init scripts easy to understand the allowed arguments and add more arguments.
So very easily two new cases, restart and status, are added to init script, which will allow start, stop, restart and status as init script arguments. Other than these arguments, it will goes to default section (*), where it will just show the usage to init script and exit.
Finalize and Execute the init script
Sample init script is explained and enhanced step by step, so lets collaborate all and prepare the final script.
Adding sample init script to start at boot
This init script can be added to start at boot time, by using following steps:
- Save this init script to /etc/init.d/ directory with a name let say sample-init, where all Linux init scripts stores.
- Don’t forget to make it executable, by using Linux chmod command.
- Use Following Linux chkconfig command, to add in boot startup.
When the chkconfig –add command will be executed, it will create the following softlinks in /etc/rcN.d directory, where N denoted the all runlevels from 0 to 6. All softlinks will be linked to /etc/init.d/sample-init script.
- /etc/rc0.d/K20sample-init
- /etc/rc1.d/K20sample-init
- /etc/rc2.d/S80sample-init
- /etc/rc3.d/S80sample-init
- /etc/rc4.d/S80sample-init
- /etc/rc5.d/S80sample-init
- /etc/rc6.d/K20sample-init
These softlinks will be executed during boot at system runlevel. Softlink starts with S80 will execute with start argument (with 80 priority) and softlink starts with K20 will execute with stop argument (with 20 priority) on respective runlevel.
- Verify the added init script.
After 4th step, it start showing 2:on, 3:on, 4:on, 5:on, means it is ready to start on boot at runlevel 2, 3, 4 and 5. All the priority and runlevel setting is the effect of chkconfig in comment section, described in above sectiosn.
You can now reboot your system and check its running.
Deleting sample init script boot from system boot
Following chkconfig command will be used to delete the sample-init script from system boot.
All the softlinks created in add will be removed, that will stop it to execute on boot.
Use of service command with init script
service command can be used to pass the argument to init script, as follows:
Using any other argument, it will show usage:
Источник