/sbin/bootchartd is in bootchart2 0.14.4-3.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed 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 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | #!/bin/bash
#
# Bootchart logger script
# Ziga Mahkovec <ziga.mahkovec@klika.si>
# Michael Meeks <michael.meeks@novell.com>
#
# This script is used for data collection for the bootchart2
# boot performance visualization tool.
#
# To profile the boot process, bootchartd should be called instead of
# /sbin/init. Modify the kernel command line to include:
#
# init=/sbin/bootchartd initcall_debug printk.time=y quiet
#
# bootchartd will then start itself in background and exec /sbin/init
# (or an alternative init process if specified using bootchart_init=)
#
# To profile a running system, run:
# $ /sbin/bootchartd start; sleep 30; /sbin/bootchartd stop
#
# Use a directory we know will be there, such that we can mount
# our 'proc' without having to touch a (potentially) read-only
# file-system.
LIBDIR="/lib"
TMPFS="${LIBDIR}/bootchart/tmpfs"
COLLECTOR_BIN="${LIBDIR}/bootchart/bootchart-collector"
# some initrds don't have usleep etc.
USLEEP="$COLLECTOR_BIN --usleep"
# we need to find our tools
PATH="/sbin:/bin:/usr/sbin:/usr/bin:$PATH"
# Defaults, in case we can't find our configuration
SAMPLE_HZ=50
BUILDLOG_DEST=/var/log/bootchart.tgz
AUTO_RENDER="no"
AUTO_RENDER_DIR="/var/log"
AUTO_RENDER_FORMAT="png"
# The processes we have to wait for
EXIT_PROC="kdm_greet xterm konsole gnome-terminal metacity mutter gnome-shell compiz ldm icewm-session enlightenment xfwm4 openbox"
# Read configuration.
CONF="/etc/bootchartd.conf"
if [ -f $PWD/bootchartd.conf ]; then
. $PWD/bootchartd.conf
elif [ -f $CONF ]; then
. $CONF
else
echo "$CONF missing"
fi
# Start the boot logger.
start()
{
# If in init start ourselves in our familiar system
if [ -n "$INIT_PROCESS" ]; then
# echo "bootchartd started in init" >> kmsg
$COLLECTOR_BIN $SAMPLE_HZ
# Otherwise, manually launched to profile something
else
# bail out, if already running
pidof bootchart-collector && exit 0
# echo "bootchartd started manually" >> kmsg
$COLLECTOR_BIN -r $SAMPLE_HZ &
if [ "$#" -gt 0 ]; then
# If a command was passed, run it
# (used for profiling specific applications)
echo "profile.process = $( basename $1 )" >> header
$@
stop
else
echo "no command passed, you need to manually stop the service sometime"
fi
fi
}
# Wait for the boot process to end.
wait_boot()
{
# Wait for /proc first - without it we have issues
while [ ! -e /proc/cmdline ]; do
$USLEEP 5000
done
while true; do
if [ -n "$EXIT_PROC" -a -n "$( pidof $EXIT_PROC )" ]; then
# give an unambiguous settle afterwards - so we get
# more post-login data for slow systems
$USLEEP 20000000
# Write / flush the log files
stop
return
fi
$USLEEP 1000000
done;
}
# Extract the log data from the running bootchart collector
# process (via ptrace) - fun. Store logs into $BOOTLOG_DEST.
stop()
{
tmpdir=`mktemp -d /tmp/bootchart.XXXXXXXXXX`
if [ "z$tmpdir" = "z" ]; then
echo "Failed to generate directory for logging"
exit 1
fi
if ! $COLLECTOR_BIN --dump $tmpdir; then
echo "Can't extract boot chart from collector"
exit 1
fi
cd $tmpdir
if [ ! -e proc_stat.log ]; then
echo "Can't find bootchart output in $tmpdir - aborting"
exit 1
fi
# Archive it all up into the bootchart output
# expect dmesg log only if bootchartd was started as an init process
if [ -n "$INIT_PROCESS" ] ; then
tar -zcf "$BOOTLOG_DEST" header dmesg *.log
else
tar -zcf "$BOOTLOG_DEST" header *.log
fi
rm -Rf $tmpdir
# Render the chart if configured (and the renderer is installed)
if [ "$AUTO_RENDER" = "yes" -a -x /usr/bin/pybootchartgui ]; then
cd $AUTO_RENDER_DIR
/usr/bin/pybootchartgui -o "$AUTO_RENDER_DIR"/bootchart.$AUTO_RENDER_FORMAT -f $AUTO_RENDER_FORMAT "$BOOTLOG_DEST"
fi
# execute custom post-collect (and possibly post-render) command (which could get params from the conf file by itself if needed)
if [ -x "$CUSTOM_POST_CMD" ]; then
"$CUSTOM_POST_CMD"
fi
}
if [ $$ -eq 1 ]; then
# Either started by the kernel - in which case, we start the
# logger in background and exec init [ re-using this pid (1) ]
# Or - started after the initrd has completed, in which case
# we try to do nothing much.
INIT_PROCESS="yes"
echo "Starting bootchart logging"
init="/sbin/init"
# Are we running in the initrd ?
if [ -x /init -o -x /linuxrc ]; then
IN_INITRD="yes"
[ -x /linuxrc ] && init="/linuxrc"
[ -x /init ] && init="/init"
start &
else # running inside the main system
echo "bootchart: no initrd used; starting"
start &
wait_boot &
# wait a little, until the collector is going, before allowing
# the rest of the system to charge ahead, so we catch it
$USLEEP 250000
echo "bootchart continuing boot" >> $TMPFS/kmsg
fi
# Optionally, an alternative init(1) process may be specified using
# the kernel command line (e.g. "bootchart_init=/sbin/initng")
[ -n "$bootchart_init" ] && init="$bootchart_init"
for i in $@; do
if [ "${i%%=*}" = "bootchart_init" ]; then
init="${i#*=}"
break
fi
if [ "${i%%=*}" = "init" ]; then
_init=${i#*=}
if test "$_init" != "/sbin/bootchartd"; then
init="$_init"
break
fi
fi
done
export PATH=$OLDPATH
# switch to - either the initrd's init, or the main system's
exec $init $*
fi
case "$1" in
"start")
# Started by the user
shift
start $@
;;
"wait")
# Wait for boot
wait_boot
;;
"stop")
stop
;;
*)
echo "Usage: $0 {wait|start|stop}"
;;
esac
|