I'm trying out bootchart2 on an embedded Linux system, using an
initramfs as main rootfs (no harddisk or other permanent storage).
I am having a number of problems with this, as described below. Your
feedback is most welcome.
The standard boot process (without bootchart2) on this system is as follows:
kernel starts /init
/init mounts /dev (devtmpfs)
/init starts /sbin/init
/sbin/init (busybox) reads inittab
inittab has rules to run the init scripts in /etc/init.d
inittab has a rule to start a getty (login prompt)
I have added getty as EXIT_PROC.
When I boot the kernel with rdinit=/sbin/bootchartd
bootchart_init=/init, bootchartd detects it is in the init process,
and also detects it's in an 'initrd'. In this case, the start() method
is called, but wait_boot() is not.
This is my first question: why is wait_boot() not called (and thus:
why is initrd treated differently as a normal system), and how is the
bootchartd stop() method supposed to be called if wait_boot() is not
doing it?
I have currently patched bootchartd such that the initrd exception is
removed, and thus both start() and wait_boot() are called.
Another problem I have with bootchartd is that it spawns a message:
/sbin/bootchartd: line 229: can't open '/dev/null'
where line 229 has just 'fi' (the end of the 'if init process' block).
There is no explicit reference to /dev/null in that script though, and
I have not been able to find out which command is causing that.
The fact that /dev/null is not present is because it is normally
created with devtmpfs, and this is only mounted on /dev through /init,
which has the following commands on my system:
#!/bin/sh
# devtmpfs does not get automounted for initramfs
/bin/mount -t devtmpfs devtmpfs /dev
exec 0</dev/console
exec 1>/dev/console
exec 2>/dev/console
exec /sbin/init $*
So, the order
bootchartd --> /init --> /sbin/init
is not really right. It should rather be
/init --> bootchartd --> /sbin/init
I can get this order by changing the last line of /init so that it
calls bootchartd, and passing bootchart_init=/sbin/init on the kernel
command-line. This fixes the /dev/null problem.
How is this working on other systems using initramfs or initrd?
Any comments on my approach above are welcome.
Now, with the above fix, when bootchart-collector is started,
am_in_initrd() returns true, and the initrd sanity check is called.
This one however, does not find (rd)init=/sbin/bootchartd on the
kernel command line and bails out. Manually patching
bootchart-collector can also fix that problem.
To conclude, to get bootchart2 to output statistics properly, I need to:
change the boot order so that /init runs first and starts
bootchartd, which then starts /sbin/init
patch bootchartd to remove the initrd exception
patch bootchart-collector to remove the initrd specific code
I would like to hear from you what you think of the above, and how we
can fix bootchart2 to cover this type of embedded system. Note that I
am not doing anything exotic: this is a standard busybox-based
embedded system, built with buildroot (www.buildroot.org) and standard
initramfs-based rootfs.
If we can find a good solution for these problems, I will add support
for building bootchart2 in buildroot, so that other developers of such
embedded systems can benefit from it.
From Thomas De Schampheleire:
I'm trying out bootchart2 on an embedded Linux system, using an initramfs as main rootfs (no harddisk or other permanent storage). I am having a number of problems with this, as described below. Your feedback is most welcome.
The standard boot process (without bootchart2) on this system is as follows:
I have added getty as EXIT_PROC.
When I boot the kernel with rdinit=/sbin/bootchartd bootchart_init=/init, bootchartd detects it is in the init process, and also detects it's in an 'initrd'. In this case, the start() method is called, but wait_boot() is not. This is my first question: why is wait_boot() not called (and thus: why is initrd treated differently as a normal system), and how is the bootchartd stop() method supposed to be called if wait_boot() is not doing it? I have currently patched bootchartd such that the initrd exception is removed, and thus both start() and wait_boot() are called.
Another problem I have with bootchartd is that it spawns a message: /sbin/bootchartd: line 229: can't open '/dev/null'
where line 229 has just 'fi' (the end of the 'if init process' block). There is no explicit reference to /dev/null in that script though, and I have not been able to find out which command is causing that. The fact that /dev/null is not present is because it is normally created with devtmpfs, and this is only mounted on /dev through /init, which has the following commands on my system:
So, the order bootchartd --> /init --> /sbin/init is not really right. It should rather be /init --> bootchartd --> /sbin/init
I can get this order by changing the last line of /init so that it calls bootchartd, and passing bootchart_init=/sbin/init on the kernel command-line. This fixes the /dev/null problem.
How is this working on other systems using initramfs or initrd? Any comments on my approach above are welcome.
Now, with the above fix, when bootchart-collector is started, am_in_initrd() returns true, and the initrd sanity check is called. This one however, does not find (rd)init=/sbin/bootchartd on the kernel command line and bails out. Manually patching bootchart-collector can also fix that problem.
To conclude, to get bootchart2 to output statistics properly, I need to:
I would like to hear from you what you think of the above, and how we can fix bootchart2 to cover this type of embedded system. Note that I am not doing anything exotic: this is a standard busybox-based embedded system, built with buildroot (www.buildroot.org) and standard initramfs-based rootfs.
If we can find a good solution for these problems, I will add support for building bootchart2 in buildroot, so that other developers of such embedded systems can benefit from it.