Skip to content

Instantly share code, notes, and snippets.

@sameo
Last active November 19, 2024 14:31
Show Gist options
  • Save sameo/0647d6aaa36e73e6b536b51c29db1ead to your computer and use it in GitHub Desktop.
Save sameo/0647d6aaa36e73e6b536b51c29db1ead to your computer and use it in GitHub Desktop.

Measuring Firecracker boot time

Firecracker comes with an internal way of logging a timestamp that measures time elapsed between the very start of the guest VM and the moment a specific IO port has been written to.

That allows for marking specific moment along the boot process by having code writing to this port.

Artifacts build

Here we're going to measure the time it takes for a Firecracker guest VM to reach userspace. To do so we're going to build 3 components:

  1. Firecracker
  2. A guest kernel
  3. A rootfs image.

We assume you created a dedicated build directory and export it to FC_BUILD. For example

export FC_BUILD=~/fc-build
mkdir -p $FC_BUILD

Firecracker

pushd $FC_BUILD
git clone https://github.com/firecracker-microvm/firecracker.git
cd firecracker
./tools/devtool/build
popd $FC_BUILD

The firecracker binary is going to be at $FC_BUILD/firecracker/build/debug/firecracker

Guest Kernel

pushd $FC_BUILD
git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git linux-stable
cd linux-stable
git reset --hard v4.14.72
curl https://raw.githubusercontent.com/firecracker-microvm/firecracker/master/resources/microvm-kernel-config -o .config
make oldconfig
make vmlinux -j `nproc`
popd $FC_BUILD

The Firecracker guest kernel is going to be at $FC_BUILD/linux-stable/vmlinux

Rootfs

See Firecracker rootfs preparation instructions

  1. First we create an empty ext4 rootfs image:
export ROOTFS_DIR=$FC_BUILD/rootfs
mkdir -p $ROOTFS_DIR
dd if=/dev/zero of=$ROOTFS_DIR/fc-rootfs.ext4 bs=1M count=50
mkfs.ext4 $ROOTFS_DIR/fc-rootfs.ext4
mkdir /tmp/fc-rootfs
sudo mount $ROOTFS_DIR/fc-rootfs.ext4 /tmp/fc-rootfs
  1. We can now populate it with an Alpine Linux image:
sudo docker run -it --rm -v /tmp/fc-rootfs:/fc-rootfs alpine

# You are now inside the container.
# First we will add an init system and some utilities
apk add openrc
apk add util-linux

# Set up a login terminal on the serial console (ttyS0):
ln -s agetty /etc/init.d/agetty.ttyS0
echo ttyS0 > /etc/securetty
rc-update add agetty.ttyS0 default

# Make sure special file systems are mounted on boot:
rc-update add devfs boot
rc-update add procfs boot

# Then, copy the newly configured system to the rootfs image:
for d in bin etc lib root sbin usr; do tar c "/$d" | tar x -C /fc-rootfs; done
for dir in dev proc run sys var; do mkdir /fc-rootfs/${dir}; done

# All done, exit docker shell
exit
  1. Now we want to add a small utility that poke the Firecracker debug io port as soon as we reach userspace.

We first need to build a small piece of code to do so:

pushd $FC_BUILD
git clone https://github.com/sameo/firecracker-magic-port.git
cd firecracker-magic-port/
make
popd

Then we copy this binary into our rootfs:

sudo cp fc-magic-port /tmp/fc-rootfs/sbin/
  1. The final step is to create a custom init command to have it first calling into fc-magic-port and then starting the regular init:
sudo bash
cat <<EOM >/tmp/fc-rootfs/init
#!/bin/sh
/sbin/fc-magic-port
exec /sbin/init
EOM
chmod a+x /tmp/fc-rootfs/init
exit
  1. We can now unmount the rootfs
sudo umount /tmp/fc-rootfs

The Firecracker guest rootfs is now at $FC_BUILD/rootfs/fc-rootfs.ext4

Artifacts summary

Artifact Location
Firecracker VMM $FC_BUILD/firecracker/build/debug/firecracker
Guest kernel $FC_BUILD/linux-stable/vmlinux
Guest rootfs $FC_BUILD/rootfs/fc-rootfs.ext4

Running and measuring

  1. Start a Firecracker instance:
rm -rf /tmp/firecracker.socket && $FC_BUILD/firecracker/build/debug/firecracker --seccomp-level 0
  1. On another terminal, start a Firecracker guest:
$FC_BUILD/firecracker-magic-port/start_instance-debug.sh /tmp/firecracker.socket

Then the guest boot time timestamp can be found in the Firecracker log pipe:

grep Guest-boot-time /tmp/logs.fifo
2019-05-30T12:15:18.698648314 [anonymous-instance] Guest-boot-time = 279446 us 279 ms, 272485 CPU us 272 CPU ms
@DoniaGhazy1
Copy link

@simonis @sameo I have tried the above changes and even updating the deprecated URLs, however, it did not work. The Guest-boot-time is not shown in the logs.

@simonis
Copy link

simonis commented Nov 19, 2024

@DoniaGhazy1, you have to execute the program I posted above (based on Firecracker's init.c utility) inside the Firecracker container in order to trigger a "Guest-boot-time" entry in the Firecracker log. Have you done that?

Firecracker has an integration test for this functionality so I'm pretty sure it still works (see tests/integration_tests/performance/test_boottime.py).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment