How To: Boot Fedora Faster

Note: These tricks apply to any Linux based OS. But I have tested them only on Fedora, so can’t say whether they’ll work on other Linux(s).

My current Fedora installation is now almost one and a half years old. Yes. I am still using Fedora 7 😀 I have Fedora 10 on my other machine. Coming to the agenda, my Fedora installation has grown beyond control and I have services from named, squid, drbl, privoxy, vsftpd, vbox*, smb and what not on a personal desktop. These services really force my system startup to slow down to more than two minutes. While shutting down, its very easy to just cut the power supply but while booting up I can’t help and it frustrates me. And what frustrates me further that I have 4GB DDR2 RAM and AMD64 X2 5600+ (2.8GHz x 2) and booting time is still more than two minutes.

Agenda

  • Boot Fedora faster using whatever techniques possible.

Remove the services from normal order and delay their execution to a later stage. So, services like network, squid, privoxy, named, vsftpd, smb etc. doesn’t make sense unless I am not logged in and using them. Let us start them after we have login screen.

Turn off all the services by using the command

[root@bordeaux ~]# chkconfig service_name off

where service_name is the service you want to turn off.

Now create a file /etc/startup.sh. Enter a line like this

[root@bordeaux ~]# service service_name start

for every service that you have turned off in the Step 1.1 and you want it to be running after your machine starts up. Now, your startup.sh file should look like this

service network start &
service sshd start &
modprobe it87 &
modprobe k8temp &
/usr/bin/iptraf -s eth0 -B &
/usr/bin/iptraf -s lo -B &
service squid start &
service privoxy start &
service httpd start &
service mysqld start &
service named start &
service smb start &
service vboxdrv start &
service vboxnet start &
service vsftpd start &

Add the following line to /etc/rc.local file

/bin/bash /etc/startup.sh &

Done!!! Notice the &s in both files. They are for execution in background so that a process can block boot process. You’ll observe a drop of 10-20 seconds in system startup time.

Problem with Hack #1 : The execution is not really parallel. It executes like a process in the background. So we can’t get the real advantage of parallel execution.

Hack #2 solves this problem. Now we don’t put processes in background. We use daemon forking to fork a separate daemon process which will start all the services for us in parallel. Here we’ll get the real advantage and startup time will decrease further.

This step is totally similar to Step 1.1. So skipping it.

This step is also similar to Step 1.2. The /etc/startup.sh file should look like this.

service network start
service xinetd start
service crond start
service anacron start
service atd start
service sshd start
service rpcbind start
service rpcgssd start
service rpcimapd start
modprobe it87
modprobe k8temp
/usr/bin/iptraf -s eth0 -B
/usr/bin/iptraf -s lo -B
service nasd start
service squid start
service privoxy start
service httpd start
service iptables start
service lm_sensors start
service mysqld start
service named start
service nfs start
service nfslock start
service smb start
service vboxdrv start
service vboxnet start
service vsftpd start
service autofs start
service smartd start

Notice the absence of &s in the file.

Download the attached startup.py file attached at the end of this post or copy paste the following code to /etc/startup.py file.

#!/usr/bin/env python
# (C) Copyright 2008 Kulbir Saini
# License : GPL
import os
import sys
def fork_daemon(f):
    """This function forks a daemon."""
    # Perform double fork
    r = ''
    if os.fork(): # Parent
        # Wait for the child so that it doesn't defunct
        os.wait()
        # Return a function
        return  lambda *x, **kw: r
    # Otherwise, we are the child
    # Perform second fork
    os.setsid()
    os.umask(077)
    os.chdir('/')
    if os.fork():
        os._exit(0)
    def wrapper(*args, **kwargs):
        """Wrapper function to be returned from generator.
        Executes the function bound to the generator and then
        exits the process"""
        f(*args, **kwargs)
        os._exit(0)
    return wrapper
 
def start_services(startup_file):
    command = '/bin/bash ' + startup_file + ' > /dev/null 2> /dev/null '
    os.system(command)
    return
 
if __name__ == '__main__':
    forkd = fork_daemon(start_services)
    forkd(sys.argv[1])
    print 'Executing ', sys.argv[1], '[  OK  ]'

Add the following line to your /etc/rc.local file.

/usr/bin/python /etc/startup.py /etc/startup.sh

Thats it. Done!!! Now you’ll experience a boost of about 25-30 seconds of decrease in boot time.

Stats of my machine

With all services started in normal order : 2minutes.
With Hack #1 : 1minute 42 seconds.
With Hack #2 : 1minute.

Warning : These hacks may break your system and can make it unusable. Use at your own risk.

 

Hack: Mange Fluctuating Wireless

I am trying this small script with a so called gui 😉 . This helps managing my wireless in the extreme conditions. Just a shell script. Run the script as root otherwise it’ll not work.

Get the script here or copy the code below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/bin/bash
#
#	Author - Kulbir Saini, IIIT Hyderabad.
#	Home - http://saini.co.in/
#	KWirelessManger - Just for fun.(It works ... its not just fun).
#
 
#Give the popup life.
POPUP_LIFE="10"
#kdialog --passivepopup "Welcome to 'KWirelessManager'"  ${POPUP_LIFE} &
#Give your device name for proceeding further. It may be one of wlan0, ra0, eth0, ipw2200 etc...
WLAN_DEVICE="wlan0"
#Give your WLAN host to be connected.
WLAN_HOST="IIIT WLAN"
CONNECTED=0
while [[ 1 ]];
do
	iwlist ${WLAN_DEVICE} scanning 2> /dev/null > /tmp/iwlist.aps
	grep -e "Cell" /tmp/iwlist.aps | tr " " "\t" | cut -f15 > /tmp/iwlist.apadd
	ACCESS_POINTS_IN_RANGE=`wc -l /tmp/iwlist.apadd`
	for ACCESS_POINT_ADDRESS in `cat /tmp/iwlist.apadd`
	do
		iwconfig ${WLAN_DEVICE} ap ${ACCESS_POINT_ADDRESS}
		#kdialog --passivepopup "Connceting to Access Point ${ACCESS_POINT_ADDRESS} ..." ${POPUP_LIFE} &
		echo "Connceting to Access Point ${ACCESS_POINT_ADDRESS} ..."
		WLAN_STATUS=`service network restart | tail -1 | grep "FAILED"`
		if [[ ${WLAN_STATUS} == "" ]];
		then
			#kdialog --passivepopup "You are connected to ${WLAN_HOST}." ${POPUP_LIFE} &
			echo "You are connected to ${WLAN_HOST}."
			CONNECTED=1
			break
		else
			#kdialog --passivepopup "Failed to connect to the Access Point ${ACCESS_POINT_ADDRESS} :(" ${POPUP_LIFE} &
			echo "Failed to connect to the Access Point ${ACCESS_POINT_ADDRESS} :("
			CONNECTED=0
		fi
	done
	if [[ ${CONNECTED} == 1 ]];
	then
		sleep 180;
	fi
done

Please suggest any optimization and do tell if u like it.

 

Hack: Mail Filter – Shell Script

This is an attempt by me to filter mails on a Linux machine. You can run this file on your home directory at mail server and it will help you to sort mails on the basis of

  • From which user the mail has come or from which domain it came,
  • to which user or domain mail was sent and
  • the keywords in the subject part of the mail.

Actually its very slow as shell is very slow , I cant help it . It scan your entire mbox file in the home directory by default. Copy the code and paste in a file say filter.sh and change its permissions to executable. Place it in you home directory at the mail server and run.

Example
You want to see all mails from username@gmail.com just run and it will ask for input,
press 1
From: username [Enter]
It will display all the mails from that are lying there in your mbox one by one.

Get the script here or copy the code below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#!/bin/bash
#################################
#   Author - Kulbir Saini       #
#   Home - http://sain.ico.in/  #
#################################
 
#shell script to filter mails.
echo -e -n "\033[32mWelcome to the mail filter system \nWhat do you want to do? \nCheck mails on basis of \n1) Sender... \n2) Receiver... \n3) Subject... \n4) Quit... \nPress(1,2,3,4): \033[0m"
read int <&2
while [[ 1 ]];do
while [[ 1 ]];do
count=0;	line=""
if [[ $int == 1 ]];then
	echo -n -e "\033[32mFrom:\033[0m "
	read from <&2
	i=0
	clear
	while read line ;do
	loopbreak=0;	nextmessagestatus=1;	mailtostatus=1;		mailsubstatus=1;	stat=1;
	toecho=`echo $line | grep -E "^From:+" | grep -E "${from}"`
	if [ "$toecho" != "" ];then
		i=`expr $i + 1`
		echo -e "${toecho}"
		while read line ; do
		mailto=`echo $line | grep -E "^To:+"`
		mailsub=`echo $line | grep -E "^Subject:+"`
		if [[ "$mailto" != "" ]] && [[ $mailtostatus == 1 ]];then
			echo $mailto
			mailtostatus=0
		fi
		if [[ "$mailsub" != "" ]] && [[ $mailsubstatus == 1 ]];then
			echo $mailsub
			mailsubstatus=0
		fi
		if [[ $mailtostatus == 0 ]] && [[ $mailsubstatus == 0 ]] && [[ $stat == 1 ]];then
			echo -e "\033[33mStarting of the Message${i}:\033[0m"
			stat=0
		fi
		fromstatus=`echo $line | grep -E "^X-UID:+"`
			if [[ $fromstatus != "" ]];then
			while read line; do
				loopstatus=`echo $line | grep -E "^From +"`
				if [[ $loopstatus != "" ]];then
				loopbreak=1
				break
				fi
				echo $line
			done
			if [[ $loopbreak == 1 ]];then
			echo -e -n "\033[33mEnd of the Message${i}.\nDisplay next message(y/n):\033[0m"
			read messagestatus <&2
			if [[ "$messagestatus" == "y" ]];then
				clear
			else
				nextmessagestatus=0
			fi
			break
			fi
			fi
		done
		count=`expr $count + 1`
	fi
	if [[ $nextmessagestatus == 0 ]];then
		break
	fi
	done
	if [[ $count == 0 ]];then
		echo -e "\033[32mNo mail(s) From: ${from}.\n\033[0m"
	else
		echo -e "\033[32mTotal $count mail(s) From: ${from}.\n\033[0m"
	fi
elif [[ $int == 2 ]];then
	echo -n -e "\033[32mTo: \033[0m"
	read to <&2
	i=0
	clear
	while read line ;do
	loopbreak=0;	nextmessagestatus=1
	toecho=`echo $line | grep -E "^To:+" | grep -E "${to}"`
	if [[ "$toecho" != "" ]];then
		echo -e "$toecho"
		i=`expr $i + 1`
		while read line; do
			tostatus=`echo $line | grep -E "^X-UID:+"`
			if [[ $tostatus != "" ]];then
			echo -e "\033[33mStarting of the Message${i}:\033[0m"
			while read line; do
				loopstatus=`echo $line | grep -E "^From +"`
				if [[ $loopstatus != "" ]];then
				loopbreak=1
				break
				fi
				echo $line
			done
			if [[ $loopbreak == 1 ]];then
			echo -e -n "\033[33mEnd of the Message${i}. \nDisplay next message(y/n): \033[0m"
			read messagestatus <&2
			if [[ $messagestatus == "y" ]];then
				clear
			else
				nextmessagestatus=0
			fi
			break
			fi
			fi
		done
		count=`expr $count + 1`
	fi
	if [[ $nextmessagestatus == 0 ]];then
		break
	fi
	done
	if [[ $count == 0 ]];then
		echo -e "\033[32mNo mail(s) to: ${to}.\n\033[0m"
	else 
		echo -e "\033[32mTotal $count mail(s) To: ${to}.\n\033[0m"
	fi
elif [[ $int == 3 ]];then
	echo -n -e "\033[32mSubject:\033[0m "
 
	read subject <&2
	clear
	i=0
	while read line ;do
	loopbreak=0;	nextmessagestatus=1
	toecho=`echo $line | grep -E "^Subject:+" | grep -E "${subject}"`
	if [[ "$toecho" != "" ]];then
		echo "$toecho"
		i=`expr $i + 1`
		while read line; do
		substatus=`echo $line | grep -E "^X-UID:+"`
		if [[ $substatus != "" ]];then
		echo -e "\033[33mStarting of the Message${i}:\033[0m"
		while read line ; do
			loopstatus=`echo $line | grep -E "^From +"`
			if [[ $loopstatus != "" ]];then
			loopbreak=1
			break
			fi
			echo $line
		done
		if [[ $loopbreak == 1 ]];then
		echo -e -n "\033[33mEnd of the message${i}. \nDisplay next message(y/n): \033[0m"
		read messagestatus <&2
		if [[ $messagestatus == "y" ]];then
			clear
		else
			nextmessagestatus=0
		fi
		break
		fi
		fi
		done
		count=`expr $count + 1`
	fi
	if [[ $nextmessagestatus == 0 ]];then
		break
	fi
	done
	if [[ $count == 0 ]];then
		echo -e "\033[32mNo mail(s) with Subject: ${subject}.\n\033[0m"
	else
		echo -e "\033[32mTotal $count mail(s) with Subject: ${subject}.\033[0m\n"
	fi
elif [[ $int == 4 ]];then
	echo -e "\033[32mThank you for using this utility. \nPlease visit again.\033[0m"
	exit
else
	echo -e "\033[32mI could not understand that. \nPlease try again.\033[0m\n"
fi
echo -e -n "\033[32m1) Sender... \n2) Receiver... \n3) Subject... \n4) Quit... \nPress(1,2,3,4):\033[0m "
read int <&2
break
done < mbox 
done
 

How To: Troubleshoot SCP Command

Some times we face problems in transferring the data from one machine to other machine using scp. Actually the scp command is executed successfully but the data is not transferred. As the .bashrc and not the .bash_profile file of the system to which the data is being transferred is executed. If the .bashrc of the remote system contains any command or executable which output some data to the standard output then that command is executed and the output is flushed on the local machine and the scp command is terminated and data is not transferred.

For example if the remote machine has any ‘echo’ or ‘nfrm’ command in .bashrc file, the scp of the data will not be possible.
Also suppose the remote machine has a lines in .bashrc like this

./test.sh

where test.sh contains the data as below:-

1
2
#/usr/bin/sh
echo "Kulbir Saini"

Then also the scp will not be possible.

So if you are facing such problems please try to remove such lines from your .bashrc file and scp the data you want.
Anyway you can keep those lines in your .bash_profile because it is not executed while transferring the data.

Please report any other cases in which scp is not possible.