TITLE: Setting up LFS to have BSD-style (Slackware) init. LFS VERSION: 2.4+ AUTHOR: Marc Heerdink SYNOPSIS: This hint deals with an alternative way of booting your system. HINT: TABLE OF CONTENTS: 1. Preface 2. Setting up the inittab 3. Creating the boot scripts 4. The rc.local issue 5. The words of wisdom 6. The end 1. PREFACE Since LFS uses SYSV init scripts by default, about everybody who has an LFS system uses this kind of init. But a few days ago, i read about someone on the mailing list who wanted to setup BSD style init. Since i was using this since the beginning i decided to write a hint for everybody who wants to use BSD style init (or just wants to try it). BSD init uses the normal SYSV init program, but a different inittab and has the boot scripts arranged different. BSD boots your system in a much less complicated way, so the scripts are easier to maintain. I think one should read this hint before installing either init, because the decision should preferably made before the first boot. This HINT will be never complete, comments can be sent to marc@koelkast.net. I'm working on a hint for a mixed-mode init like I used on my first LFS system (I currently have only BSD style init scripts). 2. SETTING UP THE INITTAB The inittab resides in /etc and configures your init. Before you start writing it, you should realize that a wrong inittab will probably result (in the worst case) in a kernel panic, but at least a lot of trouble booting your system. You'll have to choose what runlevels you want to use before you begin, too. I have the following setup (this example is quite good and will be used during the rest of this hint): RUNLEVEL: DESCRIPTION: 0 Power down the system S Single user mode 1 Alias for S 2 Multi user runlevel with console login 3 Multi user runlevel with graphical login 4 Alias for 2 5 Alias for 2 6 Reboot the system I don't recommend changing the purpose of runlevels 0, 6 and S because they should be configured like this for many programs. So we'll stick with their function. Because I use only 3 modes for booting (Single User, Console Multi User and Graphical Multi User) runlevels 4 and 5 are aliases for runlevel 2 (default). You can change their purpose to whatever you like, but I suggest you'll do that after you finished this hint. Now let's get to business! Put this in your /etc/inittab: -------------------------------/etc/inittab---------------------------------- id:2:initdefault: si:S:sysinit:/etc/rc.d/rc.sysinit l0:0:wait:/etc/rc.d/rc.0 l1:1:wait:/etc/rc.d/rc.1 l2:2:wait:/etc/rc.d/rc.2 l3:3:wait:/etc/rc.d/rc.3 l4:4:wait:/etc/rc.d/rc.4 l5:5:wait:/etc/rc.d/rc.5 l6:6:wait:/etc/rc.d/rc.6 ca:12345:ctrlaltdel:/sbin/shutdown -t1 -r now su:S1:respawn:/sbin/sulogin c1:2345:respawn:/sbin/agetty tty1 38400 linux c2:2345:respawn:/sbin/agetty tty2 38400 linux c3:2345:respawn:/sbin/agetty tty3 38400 linux c4:2345:respawn:/sbin/agetty tty4 38400 linux c5:2345:respawn:/sbin/agetty tty5 38400 linux c6:2345:respawn:/sbin/agetty tty6 38400 linux ----------------------------end of /etc/inittab------------------------------ This is a pretty basic configuration but should do for about everybody. As you can see, init first starts /etc/rc.d/rc.sysinit and then loads the needed file for the default runlevel (/etc/rc.d/rc.2). 3. CREATING THE BOOT SCRIPTS Let's create /etc/rc.d/rc.sysinit first: -----------------------------/etc/rc.d/rc.sysinit---------------------------- #!/bin/sh echo "Mounting root device read-only..." /bin/mount -n -o remount,ro / echo "Initializing swap partitions..." /sbin/swapon -a /sbin/fsck -A -a -C if [ $? -gt 1 ]; then echo echo "ERROR:" echo "Your filesystem has been severely damaged. You can probably correct this" echo "problem by running e2fsck manually (eg. with the -v and -y options). After" echo "you logout, the system will reboot." echo PS1="(Repair filesystem)# " export PS1 /sbin/sulogin /bin/umount -a -r /sbin/reboot -f fi echo "Remounting root device read-write..." /bin/mount -n -v -o remount,rw / echo "" >/etc/mtab /bin/mount -f -o remount,rw / echo "Mounting other local filesystems..." /bin/mount -a -v -tnonfs echo "Setting up hostname..." /bin/hostname `cat /etc/HOSTNAME |cut -d . -f1` /bin/domainname `cat /etc/HOSTNAME |cut -d . -f2-` if [ -f "/tmp/random-seed" ]; then echo "Initializing random number generator..." /bin/cat /tmp/random-seed >/dev/urandom rm -f /tmp/random-seed fi echo "Loading keymap..." /usr/bin/loadkeys -d echo "Setting system time from hardware clock..." /sbin/hwclock --hctosys --utc echo "Starting system and kernel log daemons...." /usr/sbin/syslogd /usr/sbin/klogd -c3 echo "Updating module dependencies..." /sbin/depmod -a -------------------------end of /etc/rc.d/rc.sysinit------------------------- To make the hostname lines work as expected, create a file /etc/HOSTNAME which holds your fqdn (Full Qualified Domain Name). That is, for example, foo.bar.com or gimli.gimli.org. The last line is optional and is only useful if you're using modules. A last note on the hwclock command: if your system clock isn't configured for using UTC (that means you're using local time) you should drop the --utc options from that line. Read the Time hint for more information. Now let's create the script for the single user runlevel. Since this runlevel won't be used very often to boot in, but instead to fall back to if something happens to the system, all running programs will be killed so you're in a very clean environment when running in single user mode. --------------------------------/etc/rc.d/rc.1------------------------------- #!/bin/sh echo "Unmounting remote filesystems..." /bin/umount -a -tnfs # insert a line for each network card you use here. This is an example for # a single network card set-up (configured as eth0): # # echo "Bringing down network interface eth0..." # /sbin/ifconfig eth0 down echo "Sending all processes the TERM signal..." /sbin/killall5 -15 sleep 1 echo "Sending all processes the KILL signal..." /sbin/killall5 -9 ----------------------------end of /etc/rc.d/rc.1---------------------------- If this script has run, no daemons have been left except the kernel daemons and init. After it has finished sulogin will be started (that's what the line "su:S1:respawn:/sbin/sulogin" is for :) so only root can use the system. All virtual consoles will be disabled. Let's get on to the next script, /etc/rc.d/rc.2. This file has many common options in it, eg. to set up networking and start network daemons. Remove every line you won't use, but don't add anything before you read chapter 4. --------------------------------/etc/rc.d/rc.2------------------------------- #!/bin/sh # In this example, the network card is configured with 192.168.0.2 as ip # address and a netmask of 255.255.255.0. This network card uses 192.168.0.1 # as the default gateway. This is the set up you would use if the box # 192.168.0.1 would be the gateway. # NOTE: # The "window 16384" option in the route command is optional but will # your network speed. echo "Setting up networking..." /sbin/ifconfig eth0 192.168.0.2 broadcast 192.168.0.255 netmask 255.255.255.0 /sbin/route add -net default gw 192.168.0.1 netmask 0.0.0.0 window 16384 metric 1 echo "Mounting remote filesystems..." /bin/mount -a -v -tnfs if [ -x /etc/rc.d/rc.local ]; then /etc/rc.d/rc.local fi ----------------------------end of /etc/rc.d/rc.2---------------------------- Now copy /etc/rc.d/rc.2 to /etc/rc.d/rc.3 and add the following to the bottom of the file: ------------------------------------snip------------------------------------- echo "Starting graphical login manager..." if [ -x /opt/kde/bin/kdm ]; then /opt/kde/bin/kdm -nodaemon elif [ -x /usr/bin/gdm ]; then /usr/bin/gdm -nodaemon elif [ -x /usr/X11R6/bin/xdm ]; then /usr/X11R6/bin/xdm -nodaemon else echo "You chose to start graphical login mode, but you don't have either KDM or" echo "GDM or XDM installed. This script looks for these display managers in the" echo "following locations:" echo echo " KDM /opt/kde/bin/kdm" echo " GDM /usr/bin/gdm" echo " XDM /usr/X11R6/bin/xdm" echo echo "This message will go away in 10 seconds, and after that you will be dropped" echo "in runlevel 2." sleep 10 /sbin/telinit 2 fi ----------------------------end of /etc/rc.d/rc.3---------------------------- The script is pretty self-explaining. It looks for the most commonly used display manages in their default locations. If none of them is found, a warning will be displayed and the system will change to runlevel 2 with a normal console login screen. Now we have created all bootscripts except /etc/rc.d/rc.0 and /etc/rc.d/rc.6. Since they both perform pretty much the same function, we'll create it only once: --------------------------------/etc/rc.d/rc.0------------------------------- #!/bin/sh echo "Sending all processes the TERM signal..." /sbin/killall5 -15 sleep 1 echo "Sending all processes the KILL signal..." /sbin/killall5 -9 sleep 1 echo "Deactivating swap partitions..." /sbin/swapoff -a echo "Saving random seed to a temporary file..." /bin/dd if=/dev/urandom of=/tmp/random-seed count=1 bs=512 2>/dev/null echo "Saving the system time to hardware clock..." /sbin/hwclock --systohc --utc echo "Unmounting remote filesystems..." /bin/umount -a -f -tnfs case "$0" in *6) /sbin/reboot -w ;; *0) /sbin/halt -w ;; esac echo "Remounting root filesystem read-only..." /bin/mount -n -o remount,ro / echo "Unmounting local filesystems..." /bin/umount -a -tnonfs echo "Flushing filesystem buffers..." /bin/sync case "$0" in *6) echo "Please stand by while rebooting..." /sbin/reboot -d -f -i ;; *0) echo "Bye..." /sbin/halt -d -f -p ;; esac ----------------------------end of /etc/rc.d/rc.0---------------------------- Some notes on this file: the hwclock should be configured like the one in /etc/rc.d/rc.sysinit (no --utc if your hardware clock uses local time). The case "$0" in *6) /sbin/reboot -w ;; *0) /sbin/halt -w ;; esac construction writes some status information to /etc/wtmp. It's a good idea to do this, but you can safely remove it. At about two-third of the file, I call /bin/sync. This program flushes the filesystem buffers so you won't loose any data. Like the construction above, this is optional but I recommend it. Now we have create all the required files, some changes have to made to make them work. Run the following commands to do this: chmod 755 /etc/rc.d/rc.0 /etc/rc.d/rc.1 /etc/rc.d/rc.2 chmod 755 /etc/rc.d/rc.3 /etc/rc.d/rc.sysinit ln -s /etc/rc.d/rc.2 /etc/rc.d/rc.4 ln -s /etc/rc.d/rc.2 /etc/rc.d/rc.5 ln -s /etc/rc.d/rc.0 /etc/rc.d/rc.6 You've done it! Take a deep breath and type (as root) "reboot" and watch your system boot with BSD style init scripts! If you have troubles using these scripts, drop me a line: marc@koelkast.net. 4. THE RC.LOCAL ISSUE As you probably know, it is common to have a /etc/rc.d/rc.local file where you put commands in that will be executen at the end of the boot process. You can use it to create for example up-to-date issue files or to pick a random message of the day. But since you created all bootscripts yourself, you can change them as much as you like, and you probably won't need this script. So what's it going to be? I personally recommend you create this script, for the purpose of portability. Many daemons write one or two lines to this file, and it saves you trouble if it's already present. This is how you create one: Put this in a file /etc/rc.d/rc.local: -------------------------------/etc/rc.d/rc.local---------------------------- #!/bin/sh -----------------------------end /etc/rc.d/rc.local-------------------------- No, I didn't make a typo... :) I can't make this file for you, because you have to decide for yourself what you want to put in it (and, of course, what you don't want in it). Make this script executable by doing this: chmod 755 /etc/rc.d/rc.local It is very easy for you to disable /etc/rc.d/rc.local; just remove the executable flag from the script and it will be skipped at boot time. 5. THE WORDS OF WISDOM I suppose you want to adapt these scripts to your personal needs. Before you do that, I would like to give you some advice on where to put the programs you start and what programs you shouldn't use. Let's start with the kernel modules. These are often loaded in a very early stage, so we'll do that too. I suggest you insert modprobe lines after the depmod line in /etc/rc.d/rc.sysinit. One exception should be made for network cards, especially on machines with much traffic or machines with l337 h4x0r5 as clients. To be sure you're safe, you should load the network card modules from /etc/rc.d/rc.2 and /etc/rc.d/rc.3, since they're only needed in multi user modes. In case of a system error, you can reboot your system safely in single user mode without networking. Many people use hdparm to tweak their hard drives. I run hdparm from the system initialization script, because I want a fast hard drive in single user mode too :). It doesn't make too much sense to me to run hdparm when everything else is already loaded, since booting the system is quite hard disk intensive and a faster hard drive will really boost it. Networking daemons, such as name servers, apache and mysql should obviously be loaded from the multi user startup scripts, since you won't need them in single user environments. If you have installed netkit-base for your network card, you will probably want a loopback device available for many programs. To get one, put the following in /etc/rc.d/rc.sysinit just before setting up the hostname: ---------------------------------------------------------------------------- echo "Setting up loopback networking..." /sbin/ifconfig lo 127.0.0.1 /sbin/route add -net 127.0.0.0 netmask 255.0.0.0 lo ---------------------------------------------------------------------------- As a final tip in this section, I would like to point out to you that I have often had a multi-user environment without networking. It would be a good practice for you to set up this environment on, for example, runlevel 5 and set it up in a secure way. This implies you have to decide whether you really need a service or not, to avoid any damage that may be caused by your ignorance. 6. THE END I hope you learnt from this hint how a BSD style init works. Although this setup is not the same as Slackwares or BSDs setup, the idea is basically the same. If you have comments on this hint, or you just liked it, please mail me at marc@koelkast.net. Bye for now, and watch out for hint updates. __END__