#!/bin/bash # # This script provides a wrapper around /sbin/init that demonstrates # bug plymouth bug 71996 https://bugs.freedesktop.org/show_bug.cgi?id=71996 # (aka http://pad.lv/1235231 and http://pad.lv/682831) # # Call the script with 'install ' to wrap /sbin/init inside # with this program. Then, on boot this program will start writing output # to its standard out (/dev/console) every NAPLEN seconds. and will # also record information into LOGNAME. # # You should generally be able to just install this script as /sbin/init # and then reboot, and check logs of /dev/console to verify data is missing. # # To reproduce on ubuntu 13.10 within lxc: # sudo apt-get --quiet --assume-yes install lxc # sudo lxc-create -t ubuntu-cloud -n source-precise-amd64 -- \ # --arch=amd64 --release=precise # # sudo lxc-clone -o source-precise-amd64 -n test1 # sudo bash ./bug71996-init-logger install /var/lib/lxc/test1/rootfs # sudo lxc-start -n test1 # # This should result in 'XX: i=N' messages for all values of N > 0 and < 150. # In lxc, I will often lose writes 0 - 6. # # You can also reproduce this in a ubuntu cloud image via kvm # http://tinyurl.com/k5v4ff6 # or on an instance in EC2 or openstack. # export NAPLEN=".2" MAX="150" LOGNAME="/run/my.log" # call with 'install target' to install into root at target # ie, install / if [ "$1" = "install" ]; then [ "$(id -u)" = "0" ] || { echo "must be root"; exit 1; } target=${2:-""} target=${target%/} [ -e "$target/sbin/init.real" ] || mv "$target/sbin/init" "$target/sbin/init.real" || { echo "failed mv $target/sbin/init"; exit 1; } [ "$0" -ef "$target/sbin/init" ] && { echo "already good"; exit 0; } cp "$0" "$target/sbin/init" || { echo "failed cp $0 $target/sbin/init"; exit 1; } chmod 755 "$target/sbin/init" || { echo "failed chmod 755 $target/sbin/init"; exit 1; } echo "installed into $target/sbin/init" exit elif [ "$1" = "uninstall" ]; then [ "$(id -u)" = "0" ] || { echo "must be root"; exit 1; } target=${2:-""} mv "$target/sbin/init.real" "$target/sbin/init" echo "uninstalled wraper around $target/sbin/init" exit fi if [ "$0" = "/sbin/init" ]; then sh -c ' LOG="" say() { local pre="XX:" up="" idle="" ret="" if [ "$1" = "UPTIME:" ]; then read up idle < /proc/uptime shift; fi ret="${up:+${up} }$*" if [ -z "$LOG" ]; then if sh -fc "echo $upmsg > \"$LOGNAME\"" >/dev/null 2>&1; then LOG="$LOGNAME" echo "$UPMSG" >> "$LOG" say "initialized log at $up" fi else echo $pre $ret >> "$LOG" fi echo $pre $ret _RET="$ret" } i=0 say UPTIME: "first up" UPMSG="$_RET" while [ $i -lt $MAX ]; do say "i=$i" i=$(($i+1)) sleep $NAPLEN done read up idle < /proc/uptime say UPTIME: "finished. i=$i" ' bug71996-logger & else unset NAPLEN MAX LOGNAME fi exec -a /sbin/init "/sbin/init.real" "$@"