#!/bin/sh

# Where we create our jail, this should be on a handy tmpfs, like /dev
JAIL="/dev/.bootchart"

# This function repeatedly runs a command through the boot process and
# stashes its output into a log file for later parsing.
log_output()
{
    trap '' HUP INT QUIT TERM
    local cmd="$1"
    local logfile="$2"
	
    while :; do
	# Write the uptime in jiffies
	sed -e "s/ [0-9].*//;s/\.//" < /proc/uptime
	eval $cmd 2>/dev/null
	echo

	sleep 0.2
    done >> /log/$logfile
}	

# Spawn off a process to log the various things we want during the boot
# process, these all run in the background so this exits quickly
bottom_half()
{
    trap '' HUP
    log_output "cat /proc/stat" proc_stat.log &
    log_output "cat /proc/diskstats" proc_diskstats.log &
    log_output "cat /proc/*/stat" proc_ps.log &
    sleep 86400
}

# Make a jail filesystem to live in and run ourselves again with the "bottom"
# argument inside it
make_jail()
{
    mkdir -p $JAIL
    mount -n -o mode=0755 -t tmpfs none $JAIL
    mkdir $JAIL/bin

    cp $0 $JAIL/bin/bootchart
    ln -s busybox $JAIL/bin/cat
    ln -s busybox $JAIL/bin/echo
    ln -s busybox $JAIL/bin/sed
    ln -s busybox $JAIL/bin/sleep

    mkdir $JAIL/lib
    cp /lib/ld-* /lib/libc.so.6 $JAIL/lib
    [ -L /lib64 ] && ln -s lib $JAIL/lib64

    mkdir $JAIL/proc
    mount -t proc none $JAIL/proc
    
    mkdir $JAIL/dev
    mknod $JAIL/dev/null c 1 3
    
    mkdir $JAIL/log
    chroot $JAIL /bin/busybox sh /bin/bootchart bottom &
}

grep -q bootchart /proc/cmdline || exit 0

case $1 in
    bottom)
	bottom_half
	;;
    *)
	make_jail
	;;
esac

exit 0

