diff --git a/Makefile b/Makefile index 923d9b7..01d4d25 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ KDIR=/usr/src/kernels/$(shell uname -r) obj-m += demo.o +obj-m += blk_kprobe.o all: make -C $(KDIR) M=$(shell pwd) modules diff --git a/blk_kprobe.c b/blk_kprobe.c new file mode 100644 index 0000000..5403394 --- /dev/null +++ b/blk_kprobe.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include +#include + +static int submit_bio_pre(struct kprobe *p, struct pt_regs *regs) { + struct bio *bio = (struct bio *)regs->di; + struct bio_vec bvec; + struct bvec_iter iter; + + printk(KERN_INFO "submit_bio: bi_vec: bi_vcnt is %d, operation is %s\n", bio->bi_vcnt, blk_op_str(bio_op(bio))); + bio_for_each_bvec(bvec, bio, iter) { + printk(KERN_INFO " idx=%d, sector=%lld, size=%d, done=%d, bv_page=0x%lx, bv_len=%u, bv_offset=%u\n", + iter.bi_idx, iter.bi_sector, iter.bi_size, iter.bi_bvec_done, (unsigned long)bvec.bv_page, bvec.bv_len, bvec.bv_offset); + } + + if (bio->bi_vcnt != 1) + dump_stack(); + + return 0; +} + +static struct kprobe submit_bio_kp = { + .symbol_name = "submit_bio", + .pre_handler = submit_bio_pre, +}; + +static struct kprobe *kprobes[] = { + &submit_bio_kp, +}; + +static int __init kprobe_init(void) { + int ret; + + ret = register_kprobes(kprobes, ARRAY_SIZE(kprobes)); + if (ret < 0) { + printk(KERN_INFO "kprobe registration failed\n"); + return ret; + } + printk(KERN_INFO "kprobemodule loaded\n"); + + return 0; +} + +static void __exit kprobe_exit(void) { + unregister_kprobes(kprobes, ARRAY_SIZE(kprobes)); + printk(KERN_INFO "kprobemodule unloaded\n"); +} + +module_init(kprobe_init); +module_exit(kprobe_exit); +MODULE_LICENSE("GPL"); +