Compiling lockstat with 2.6.x kernel

I wanted to use lockstat/lockmeter on a 2.6.16 kernel, but the lockstat userland tool wouldn’t compile.  I googled fruitlessly for a while and found a few posts from people with the same problem, but never any replies, which always means that you are doing something so mindlessly stupid that both the poster and the reader didn’t want to reply and embarrass anyone.  I resolved to post the answer even if it made me out to be an idiot.  Fortunately, only one part of the answer was mindlessly stupid, and the other was a minor header file issue.

For the mindlessly stupid part, it helps to define LINUX_INC_ROOT as the actual path to the include/ directory of your kernel source.  I managed to get this wrong about three times, so do an ls of it just to double-check.  The slightly intelligent part is that getsetdata.c wasn’t including the definition of CONFIG_LOCKMETER.  The current coolest way to include this appears to be using -include as part of compilation arguments, and it worked, so here ya go:

diff -ur lockstat/Makefile lockstat.new/Makefile
— lockstat/Makefile   2004-09-13 19:01:41.000000000 -0400
+++ lockstat.new/Makefile       2007-10-08 19:25:16.000000000 -0400
@@ -10,7 +10,7 @@

 PROGS  = lockstat
 CC     = gcc
-CFLAGS = -O2 -fomit-frame-pointer -I$(LINUX_INC_ROOT)
+CFLAGS = -O2 -fomit-frame-pointer -I$(LINUX_INC_ROOT) -include $(LINUX_INC_ROOT)/linux/autoconf.h

 default all: $(PROGS)

Fabulous!  And now I can run lockstat and get… a segfault!  Stay tuned!

Update:

The segfault appears to be because time_t was defined as something other than the one that ctime() would like to receive, and so ctime() was returning NULL instead of a nicely formatted string -> try to printf that -> boom.  The following fixed it:

diff -ur lockstat/lockstat.c lockstat.new/lockstat.c
— lockstat/lockstat.c 2004-09-13 19:01:41.000000000 -0400
+++ lockstat.new/lockstat.c     2007-10-08 20:34:13.000000000 -0400
@@ -36,7 +36,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <sys/time.h>
+#include <time.h>
 #include <linux/lockmeter.h>

 extern void    closeFiles(void);