using kgraft with ubuntu
New live kernel patching projects have hit LKML recently here and here, and I’ve taken the opportunity to test drive kGraft with the Ubuntu kernel. This post documents how to get a sample patch working.
First, I had to take the patches and apply them against the ubuntu-utopic kernel, which is based on 3.15-rc8 as of this post. They cherry-picked cleanly and the branch I’m using is stored here. In addition to applying the patches I had to also enable CONFIG_KGRAFT. A pre-built test kernel can be downloaded here.
Next, I created a test VM and installed the test kernel, headers, and build dependencies into that VM and rebooted. Now after a successful reboot, we need to produce an actual patch to test. I’ve created a github project with the sample patch; to make it easy to clone and get started.
sudo apt-get install git build-essential git clone https://github.com/arges/kgraft-examples.git cd kgraft-examples make
The code in kgraft_patcher.c is the example found in samples/kgraft. Now we can build it easily using the Makefile I have in my project by typing make.
Next, the module needs to be inserted using the following:
sudo insmod ./kgraft_patcher.ko
Run the following to see if the module loaded properly:
lsmod | grep kgraft
You’ll notice some messages printed with the following:
[ 211.762563] kgraft_patcher: module verification failed: signature and/or required key missing - tainting kernel [ 216.800080] kgr failed after timeout (30), still in degraded mode [ 246.880146] kgr failed after timeout (30), still in degraded mode [ 276.960211] kgr failed after timeout (30), still in degraded mode
This means that not all processes have entered the kernel and may not have a “new universe” flag set. Run the following to see which processes still needs to be updated.
In order to get all processes to enter the kernel sometimes a signal needs to be sent to get the process to enter the kernel.
An example of this is found in the kgraft-examples called hurryup.sh:
#!/bin/bash for p in $(ls /proc/ | grep '^[0-9]'); do if [[ -e /proc/$p/kgr_in_progress ]]; then if [[ `sudo cat /proc/$p/kgr_in_progress` -eq 1 ]]; then echo $p; sudo kill -SIGCONT $p fi fi done
Here is checks for all processes that have ‘kgr_in_progress’ set and sends a SIGCONT signal to that process.
I’ve noticed that I had to also send a SIGSTOP followed by a SIGCONT to finally get everything synced up.
Eventually you’ll see:
[ 1600.480233] kgr succeeded
Now your kernel is running the new patch without rebooting!