Can't access super_blocks list from kernel module: undefined!
I'm trying to write a kernel module, which prints some information about the objects in the VFS subsystem. That way I want to learn how the VFS works and what structures it uses.
However, I can't manage to iterate the super_blocks
list, because of this compiler warning:
WARNING: "super_blocks" [/path/to/module/vfsinfo.ko] undefined!
If I still try to insert the module, insmod fails and returns a similar message.
开发者_StackOverflowHere is the relevant part of my code:
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/list.h>
#include <linux/fs.h>
#define PRINT(...) printk(KERN_ALERT __VA_ARGS__)
/*
* Print all super blocks
*/
static void vfsinfo_print_super_blocks(void) {
struct super_block *s;
list_for_each_entry(s, &super_blocks, s_list) {
PRINT("%s\n", s->s_type->name);
}
}
What am I doing wrong?
It seems super_blocks is not exported with EXPORT_SYMBOL() to modules. See
http://www.kernel.org/doc/htmldocs/kernel-hacking.html#symbols
for more information.
Even after some research I couldn't find any helpful list_head
or function that is exported for kernel modules. Since this project should just help me to learn the VFS data structures, I decided to create a pointer to a struct list_head
and assign it the address to the "real" list_head super_blocks
.
For this purpose I first looked up the address in the System.map
file.
$ grep super_blocks /boot/System.map-2.6.36
ffffffff81a22650 D super_blocks
Then I set up my list_head
and started working with it:
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/list.h>
#include <linux/fs.h>
#define PRINT(...) printk(KERN_ALERT __VA_ARGS__)
/*
* Print all super blocks
*/
static void vfsinfo_print_super_blocks(void) {
struct list_head *super_blocks = 0xffffffff81a22650;
struct super_block *s;
list_for_each_entry(s, super_blocks, s_list) {
PRINT("%s\n", s->s_type->name);
}
}
Now I am able to access all my super blocks :)
[ 1218.356475] sysfs
[ 1218.357066] rootfs
[ 1218.358450] bdev
[ 1218.359600] proc
[ 1218.360368] tmpfs
[ 1218.361612] sockfs
[ 1218.362388] debugfs
[ 1218.363090] pipefs
[ 1218.363752] anon_inodefs
[ 1218.364076] devpts
[ 1218.365077] hugetlbfs
[ 1218.365654] mqueue
[ 1218.366459] selinuxfs
[ 1218.367060] usbfs
[ 1218.367489] ext2
[ 1218.368065] sysfs
[ 1218.369076] tmpfs
Bye
精彩评论