Line 0
Link Here
|
0 |
- |
1 |
#!/bin/bash |
|
|
2 |
# |
3 |
# Bootchart logger script |
4 |
# Ziga Mahkovec <ziga.mahkovec@klika.si> |
5 |
# Michael Meeks <michael.meeks@novell.com> |
6 |
# |
7 |
# This script is used for data collection for the bootchart2 |
8 |
# boot performance visualization tool. |
9 |
# |
10 |
# To profile the boot process, bootchartd should be called instead of |
11 |
# /sbin/init. Modify the kernel command line to include: |
12 |
# |
13 |
# init=/sbin/bootchartd initcall_debug printk.time=y quiet |
14 |
# |
15 |
# bootchartd will then start itself in background and exec /sbin/init |
16 |
# (or an alternative init process if specified using bootchart_init=) |
17 |
# |
18 |
# To profile a running system, run: |
19 |
# $ /sbin/bootchartd start; sleep 30; /sbin/bootchartd stop |
20 |
# |
21 |
|
22 |
# Use a directory we know will be there, such that we can mount |
23 |
# our 'proc' without having to touch a (potentially) read-only |
24 |
# file-system. |
25 |
LIBDIR="@LIBDIR@" |
26 |
TMPFS="${LIBDIR}/bootchart/tmpfs" |
27 |
COLLECTOR_BIN="${LIBDIR}/bootchart/bootchart-collector" |
28 |
|
29 |
# some initrds don't have usleep etc. |
30 |
USLEEP="$COLLECTOR_BIN --usleep" |
31 |
|
32 |
# we need to find our tools |
33 |
PATH="/sbin:/bin:/usr/sbin:/usr/bin:$PATH" |
34 |
|
35 |
# Defaults, in case we can't find our configuration |
36 |
SAMPLE_HZ=50 |
37 |
BUILDLOG_DEST=/var/log/bootchart.tgz |
38 |
AUTO_RENDER="no" |
39 |
AUTO_RENDER_DIR="/var/log" |
40 |
AUTO_RENDER_FORMAT="png" |
41 |
|
42 |
# The processes we have to wait for |
43 |
EXIT_PROC="kdm_greet xterm konsole gnome-terminal metacity mutter compiz ldm icewm-session enlightenment" |
44 |
|
45 |
# Read configuration. |
46 |
CONF="/etc/bootchartd.conf" |
47 |
if [ -f $PWD/bootchartd.conf ]; then |
48 |
. $PWD/bootchartd.conf |
49 |
elif [ -f $CONF ]; then |
50 |
. $CONF |
51 |
else |
52 |
echo "$CONF missing" |
53 |
fi |
54 |
|
55 |
# Start the boot logger. |
56 |
start() |
57 |
{ |
58 |
# If in init start ourselves in our familiar system |
59 |
if [ -n "$INIT_PROCESS" ]; then |
60 |
# echo "bootchartd started in init" >> kmsg |
61 |
$COLLECTOR_BIN $SAMPLE_HZ |
62 |
|
63 |
# Otherwise, manually launched to profile something |
64 |
else |
65 |
# bail out, if already running |
66 |
pidof bootchart-collector && exit 0 |
67 |
# echo "bootchartd started manually" >> kmsg |
68 |
$COLLECTOR_BIN -r $SAMPLE_HZ & |
69 |
|
70 |
if [ "$#" -gt 0 ]; then |
71 |
# If a command was passed, run it |
72 |
# (used for profiling specific applications) |
73 |
echo "profile.process = $( basename $1 )" >> header |
74 |
$@ |
75 |
stop |
76 |
else |
77 |
echo "no command passed, you need to manually stop the service sometime" |
78 |
fi |
79 |
fi |
80 |
} |
81 |
|
82 |
# Wait for the boot process to end. |
83 |
wait_boot() |
84 |
{ |
85 |
# Wait for /proc first - without it we have issues |
86 |
while [ ! -e /proc/cmdline ]; do |
87 |
$USLEEP 5000 |
88 |
done |
89 |
|
90 |
while true; do |
91 |
if [ -n "$EXIT_PROC" -a -n "$( pidof $EXIT_PROC )" ]; then |
92 |
# give an unambiguous settle afterwards - so we get |
93 |
# more post-login data for slow systems |
94 |
$USLEEP 20000000 |
95 |
|
96 |
# Write / flush the log files |
97 |
stop |
98 |
return |
99 |
fi |
100 |
$USLEEP 1000000 |
101 |
done; |
102 |
} |
103 |
|
104 |
# Extract the log data from the running bootchart collector |
105 |
# process (via ptrace) - fun. Store logs into $BOOTLOG_DEST. |
106 |
stop() |
107 |
{ |
108 |
tmpdir=`mktemp -d /tmp/bootchart.XXXXXXXXXX` |
109 |
if [ "z$tmpdir" = "z" ]; then |
110 |
echo "Failed to generate directory for logging" |
111 |
exit 1 |
112 |
fi |
113 |
|
114 |
if ! $COLLECTOR_BIN --dump $tmpdir; then |
115 |
echo "Can't extract boot chart from collector" |
116 |
exit 1 |
117 |
fi |
118 |
|
119 |
cd $tmpdir |
120 |
if [ ! -e proc_stat.log ]; then |
121 |
echo "Can't find bootchart output in $tmpdir - aborting" |
122 |
exit 1 |
123 |
fi |
124 |
|
125 |
# Archive it all up into the bootchart output |
126 |
tar -zcf "$BOOTLOG_DEST" header dmesg *.log |
127 |
|
128 |
rm -Rf $tmpdir |
129 |
|
130 |
# Render the chart if configured (and the renderer is installed) |
131 |
if [ "$AUTO_RENDER" = "yes" -a -x /usr/bin/pybootchartgui ]; then |
132 |
cd $AUTO_RENDER_DIR |
133 |
/usr/bin/pybootchartgui -o "$AUTO_RENDER_DIR"/bootchart.$AUTO_RENDER_FORMAT -f $AUTO_RENDER_FORMAT "$BOOTLOG_DEST" |
134 |
fi |
135 |
} |
136 |
|
137 |
if [ $$ -eq 1 ]; then |
138 |
# Either started by the kernel - in which case, we start the |
139 |
# logger in background and exec init [ re-using this pid (1) ] |
140 |
# Or - started after the initrd has completed, in which case |
141 |
# we try to do nothing much. |
142 |
INIT_PROCESS="yes" |
143 |
echo "Starting bootchart logging" |
144 |
|
145 |
init="/sbin/init" |
146 |
|
147 |
# Are we running in the initrd ? |
148 |
if [ -x /init -o -x /linuxrc ]; then |
149 |
IN_INITRD="yes" |
150 |
[ -x /linuxrc ] && init="/linuxrc" |
151 |
[ -x /init ] && init="/init" |
152 |
start & |
153 |
else # running inside the main system |
154 |
echo "bootchart: no initrd used; starting" |
155 |
start & |
156 |
wait_boot & |
157 |
# wait a little, until the collector is going, before allowing |
158 |
# the rest of the system to charge ahead, so we catch it |
159 |
$USLEEP 250000 |
160 |
echo "bootchart continuing boot" >> $TMPFS/kmsg |
161 |
fi |
162 |
|
163 |
# Optionally, an alternative init(1) process may be specified using |
164 |
# the kernel command line (e.g. "bootchart_init=/sbin/initng") |
165 |
for i in $@; do |
166 |
if [ "${i%%=*}" = "bootchart_init" ]; then |
167 |
init="${i#*=}" |
168 |
break |
169 |
fi |
170 |
if [ "${i%%=*}" = "init" ]; then |
171 |
_init=${i#*=} |
172 |
if test "$_init" != "/sbin/bootchartd"; then |
173 |
init="$_init" |
174 |
break |
175 |
fi |
176 |
fi |
177 |
done |
178 |
export PATH=$OLDPATH |
179 |
|
180 |
# switch to - either the initrd's init, or the main system's |
181 |
exec $init $* |
182 |
fi |
183 |
|
184 |
case "$1" in |
185 |
"start") |
186 |
# Started by the user |
187 |
shift |
188 |
start $@ |
189 |
;; |
190 |
"wait") |
191 |
# Wait for boot |
192 |
wait_boot |
193 |
;; |
194 |
"stop") |
195 |
stop |
196 |
;; |
197 |
*) |
198 |
echo "Usage: $0 {init|start|stop}" |
199 |
;; |
200 |
esac |
201 |
|