增加了cgroup的学习文档...

This commit is contained in:
gatieme
2016-10-02 18:30:16 +08:00
parent 0d64a31e48
commit 54c9cc02e0
23 changed files with 3537 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
cmd_/home/gatieme/Work/GitHub/LDD-LinuxDeviceDrivers/study/driver/probe/test.ko := ld -r -m elf_x86_64 -T ./scripts/module-common.lds --build-id -o /home/gatieme/Work/GitHub/LDD-LinuxDeviceDrivers/study/driver/probe/test.ko /home/gatieme/Work/GitHub/LDD-LinuxDeviceDrivers/study/driver/probe/test.o /home/gatieme/Work/GitHub/LDD-LinuxDeviceDrivers/study/driver/probe/test.mod.o
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,2 @@
/home/gatieme/Work/GitHub/LDD-LinuxDeviceDrivers/study/driver/probe/test.ko
/home/gatieme/Work/GitHub/LDD-LinuxDeviceDrivers/study/driver/probe/test.o
+78
View File
@@ -0,0 +1,78 @@
# ------------------------------------------------------------------------------
#
# Makefile for the LDD-LinuxDeviceDrivers.
#
# Author: gatieme
# Create: 2016-07-29 15:50:46
# Last modified: 2016-07-29 16:10:29
# Description:
# This program is loaded as a kernel(v2.6.18 or later) module.
# Use "make install" to load it into kernel.
# Use "make remove" to remove the module out of kernel.
#
# ------------------------------------------------------------------------------
ROOT=..
#PLATFORM=$(shell $(ROOT)/systype.sh)
#include $(ROOT)/Make.defines.$(PLATFORM)
# my driver description
DRIVER_VERSION := "1.0.0"
DRIVER_AUTHOR := "Gatieme @ AderStep Inc..."
DRIVER_DESC := "Linux input module for Elo MultiTouch(MT) devices"
DRIVER_LICENSE := "Dual BSD/GPL"
MODULE_NAME := test
ifneq ($(KERNELRELEASE),)
#CFG_FLAGS += -O2 -I./
#EXTRA_CFLAGS += $(C_FLAGS) $(CFG_INC) $(CFG_INC)
obj-m := $(MODULE_NAME).o #print_vmarea.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
modules:
make -C $(KERNELDIR) M=$(PWD) modules
modules_install:
make -C $(KERNELDIR) M=$(PWD) modules_install
insmod:
sudo insmod $(MODULE_NAME).ko
reinsmod:
sudo rmmod $(MODULE_NAME)
sudo insmod $(MODULE_NAME).ko
github:
cd $(ROOT) && make github
rmmod:
sudo rmmod $(MODULE_NAME)
test :
sudo ../injector/memInjector -l stack -m random -t word_0 --time 1 --timeout 3 -p 1
clean:
make -C $(KERNELDIR) M=$(PWD) clean
rm -f modules.order Module.symvers Module.markers
.PHNOY:
modules modules_install clean
endif
View File
@@ -0,0 +1 @@
cmd_/home/gatieme/Work/GitHub/LDD-LinuxDeviceDrivers/study/driver/probe/jprobe/jprobe-exam.ko := ld -r -m elf_x86_64 -T ./scripts/module-common.lds --build-id -o /home/gatieme/Work/GitHub/LDD-LinuxDeviceDrivers/study/driver/probe/jprobe/jprobe-exam.ko /home/gatieme/Work/GitHub/LDD-LinuxDeviceDrivers/study/driver/probe/jprobe/jprobe-exam.o /home/gatieme/Work/GitHub/LDD-LinuxDeviceDrivers/study/driver/probe/jprobe/jprobe-exam.mod.o
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,2 @@
/home/gatieme/Work/GitHub/LDD-LinuxDeviceDrivers/study/driver/probe/jprobe/jprobe-exam.ko
/home/gatieme/Work/GitHub/LDD-LinuxDeviceDrivers/study/driver/probe/jprobe/jprobe-exam.o
+78
View File
@@ -0,0 +1,78 @@
# ------------------------------------------------------------------------------
#
# Makefile for the LDD-LinuxDeviceDrivers.
#
# Author: gatieme
# Create: 2016-07-29 15:50:46
# Last modified: 2016-07-29 16:10:29
# Description:
# This program is loaded as a kernel(v2.6.18 or later) module.
# Use "make install" to load it into kernel.
# Use "make remove" to remove the module out of kernel.
#
# ------------------------------------------------------------------------------
ROOT=..
#PLATFORM=$(shell $(ROOT)/systype.sh)
#include $(ROOT)/Make.defines.$(PLATFORM)
# my driver description
DRIVER_VERSION := "1.0.0"
DRIVER_AUTHOR := "Gatieme @ AderStep Inc..."
DRIVER_DESC := "Linux input module for Elo MultiTouch(MT) devices"
DRIVER_LICENSE := "Dual BSD/GPL"
MODULE_NAME := jprobe-exam
ifneq ($(KERNELRELEASE),)
#CFG_FLAGS += -O2 -I./
#EXTRA_CFLAGS += $(C_FLAGS) $(CFG_INC) $(CFG_INC)
obj-m := $(MODULE_NAME).o #print_vmarea.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
modules:
make -C $(KERNELDIR) M=$(PWD) modules
modules_install:
make -C $(KERNELDIR) M=$(PWD) modules_install
insmod:
sudo insmod $(MODULE_NAME).ko
reinsmod:
sudo rmmod $(MODULE_NAME)
sudo insmod $(MODULE_NAME).ko
github:
cd $(ROOT) && make github
rmmod:
sudo rmmod $(MODULE_NAME)
test :
sudo ../injector/memInjector -l stack -m random -t word_0 --time 1 --timeout 3 -p 1
clean:
make -C $(KERNELDIR) M=$(PWD) clean
rm -f modules.order Module.symvers Module.markers
.PHNOY:
modules modules_install clean
endif
+57
View File
@@ -0,0 +1,57 @@
/* jprobe-exam.c */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/kallsyms.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
static struct jprobe jp;
asmlinkage long jprobe_sys_open(const char __user *filename, int flags, int mode)
{
int len = PATH_MAX;
char * tmpfilename = NULL;
if (TASK_SIZE - (unsigned long) filename < PATH_MAX) {
len = TASK_SIZE - (unsigned long) filename;
}
tmpfilename = kmalloc(len, GFP_ATOMIC);
if (tmpfilename == NULL) return 0;
if (copy_from_user(tmpfilename, filename, len)) return 0;
printk("process '%s' call open('%s', %d, %d)\n", current->comm, tmpfilename, flags, mode);
jprobe_return();
return 0;
}
int init_module(void)
{
int ret;
jp.entry = (kprobe_opcode_t *) jprobe_sys_open;
jp.kp.addr = (kprobe_opcode_t *)kallsyms_lookup_name("sys_open");
if (!jp.kp.addr) {
printk("Couldn't find the address of sys_open\n");
return -1;
}
if ((ret = register_jprobe(&jp)) <0) {
printk("register_jprobe failed, returned %d\n", ret);
return -1;
}
printk("Registered a jprobe.\n");
return 0;
}
void cleanup_module(void)
{
unregister_jprobe(&jp);
printk("jprobe unregistered\n");
}
MODULE_LICENSE("GPL");
@@ -0,0 +1,39 @@
#include <linux/module.h>
#include <linux/vermagic.h>
#include <linux/compiler.h>
MODULE_INFO(vermagic, VERMAGIC_STRING);
__visible struct module __this_module
__attribute__((section(".gnu.linkonce.this_module"))) = {
.name = KBUILD_MODNAME,
.init = init_module,
#ifdef CONFIG_MODULE_UNLOAD
.exit = cleanup_module,
#endif
.arch = MODULE_ARCH_INIT,
};
static const struct modversion_info ____versions[]
__used
__attribute__((section("__versions"))) = {
{ 0xcd71858e, __VMLINUX_SYMBOL_STR(module_layout) },
{ 0xe16b0d30, __VMLINUX_SYMBOL_STR(unregister_jprobe) },
{ 0xb1bedeb7, __VMLINUX_SYMBOL_STR(register_jprobe) },
{ 0xe007de41, __VMLINUX_SYMBOL_STR(kallsyms_lookup_name) },
{ 0x1b9aca3f, __VMLINUX_SYMBOL_STR(jprobe_return) },
{ 0x27e1a049, __VMLINUX_SYMBOL_STR(printk) },
{ 0x4f6b400b, __VMLINUX_SYMBOL_STR(_copy_from_user) },
{ 0xd2b09ce5, __VMLINUX_SYMBOL_STR(__kmalloc) },
{ 0x8bdd5b5d, __VMLINUX_SYMBOL_STR(current_task) },
{ 0x3356b90b, __VMLINUX_SYMBOL_STR(cpu_tss) },
{ 0xbdfb6dbb, __VMLINUX_SYMBOL_STR(__fentry__) },
};
static const char __module_depends[]
__used
__attribute__((section(".modinfo"))) =
"depends=";
MODULE_INFO(srcversion, "D5690A5FB79FCF9F6F9F059");
+1
View File
@@ -0,0 +1 @@
kernel//home/gatieme/Work/GitHub/LDD-LinuxDeviceDrivers/study/driver/probe/jprobe/jprobe-exam.ko
+78
View File
@@ -0,0 +1,78 @@
# ------------------------------------------------------------------------------
#
# Makefile for the LDD-LinuxDeviceDrivers.
#
# Author: gatieme
# Create: 2016-07-29 15:50:46
# Last modified: 2016-07-29 16:10:29
# Description:
# This program is loaded as a kernel(v2.6.18 or later) module.
# Use "make install" to load it into kernel.
# Use "make remove" to remove the module out of kernel.
#
# ------------------------------------------------------------------------------
ROOT=..
#PLATFORM=$(shell $(ROOT)/systype.sh)
#include $(ROOT)/Make.defines.$(PLATFORM)
# my driver description
DRIVER_VERSION := "1.0.0"
DRIVER_AUTHOR := "Gatieme @ AderStep Inc..."
DRIVER_DESC := "Linux input module for Elo MultiTouch(MT) devices"
DRIVER_LICENSE := "Dual BSD/GPL"
MODULE_NAME := kprobe-exam
ifneq ($(KERNELRELEASE),)
#CFG_FLAGS += -O2 -I./
#EXTRA_CFLAGS += $(C_FLAGS) $(CFG_INC) $(CFG_INC)
obj-m := $(MODULE_NAME).o #print_vmarea.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
modules:
make -C $(KERNELDIR) M=$(PWD) modules
modules_install:
make -C $(KERNELDIR) M=$(PWD) modules_install
insmod:
sudo insmod $(MODULE_NAME).ko
reinsmod:
sudo rmmod $(MODULE_NAME)
sudo insmod $(MODULE_NAME).ko
github:
cd $(ROOT) && make github
rmmod:
sudo rmmod $(MODULE_NAME)
test :
sudo ../injector/memInjector -l stack -m random -t word_0 --time 1 --timeout 3 -p 1
clean:
make -C $(KERNELDIR) M=$(PWD) clean
rm -f modules.order Module.symvers Module.markers
.PHNOY:
modules modules_install clean
endif
+87
View File
@@ -0,0 +1,87 @@
https://www.ibm.com/developerworks/cn/linux/l-cn-systemtap1/
kprobe使用实例
本文附带的包包含了三个示例模块,kprobe-exam.c是kprobes使用示例,jprobe-exam.c是jprobes使用示例,kretprobe-exam.c是kretprobes使用示例,读者可以下载该包并执行如下指令来实验这些模块:
$ tar -jxvf kprobes-examples.tar.bz2
$ cd kprobes-examples
$ make
$ su -
$ insmod kprobe-example.ko
$ dmesg
$ rmmod kprobe-example
$ dmesg
$ insmod jprobe-example.ko
$ cat kprobe-example.c
$dmesg
$ rmmod jprobe-example
$ dmesg
$ insmod kretprobe-example.ko
$ dmesg
$ ls -Rla / > /dev/null &
$ dmesg
$ rmmod kretprobe-example
$ dmesg
$
示例模块kprobe-exame.c探测schedule()函数,在探测点执行前后分别输出当前正在运行的进程、所在的CPU以及preempt_count(),当卸载该模块时将输出该模块运行时间以及发生的调度次数。这是该模块在作者系统上的输出:
kprobe registered
current task on CPU#1: swapper (before scheduling), preempt_count = 0
current task on CPU#1: swapper (after scheduling), preempt_count = 0
current task on CPU#0: insmod (before scheduling), preempt_count = 0
current task on CPU#0: insmod (after scheduling), preempt_count = 0
current task on CPU#1: klogd (before scheduling), preempt_count = 0
current task on CPU#1: klogd (after scheduling), preempt_count = 0
current task on CPU#1: klogd (before scheduling), preempt_count = 0
current task on CPU#1: klogd (after scheduling), preempt_count = 0
current task on CPU#1: klogd (before scheduling), preempt_count = 0
Scheduling times is 5918 during of 7655 milliseconds.
kprobe unregistered
示例模块jprobe-exam.c是一个jprobes探测例子,它示例了获取系统调用open的参数,但读者不要试图在实际的应用中这么使用,因为copy_from_user可能导致睡眠,而kprobe并不允许在探测点处理函数中这么做(请参看前面内容了解详细描述)。
这是该模块在作者系统上的输出:
Registered a jprobe.
process 'cat' call open('/etc/ld.so.cache', 0, 0)
process 'cat' call open('/lib/libc.so.6', 0, -524289)
process 'cat' call open('/usr/lib/locale/locale-archive', 32768, 1)
process 'cat' call open('/usr/share/locale/locale.alias', 0, 438)
process 'cat' call open('/usr/lib/locale/en_US.UTF-8/LC_CTYPE', 0, 0)
process 'cat' call open('/usr/lib/locale/en_US.utf8/LC_CTYPE', 0, 0)
process 'cat' call open('/usr/lib/gconv/gconv-modules.cache', 0, 0)
process 'cat' call open('kprobe-exam.c', 32768, 0)
process 'rmmod' call open('/etc/ld.so.cache', 0, 0)
process 'rmmod' call open('/lib/libc.so.6', 0, -524289)
process 'rmmod' call open('/proc/modules', 0, 438)
jprobe unregistered
示例模块kretprobe-exam.c是一个返回探测例子,它探测系统调用open并输出返回值小于0的情况。它也有意设置maxactive为1,以便示例丢失探测运行的情况,当然,只有系统并发运行多个sys_open才可能导致这种情况,因此,读者需要有SMP的系统或者有超线程支持才能看到这种情况。如果读者比较仔细,会看到在前面的命令有”ls -Rla / > /dev/null & ,那是专门为了导致出现丢失探测运行的。
这是该模块在作者系统上的输出:
Registered a return probe.
sys_open returns -2
sys_open returns -2
sys_open returns -2
sys_open returns -2
sys_open returns -2
sys_open returns -2
sys_open returns -2
sys_open returns -2
sys_open returns -2
sys_open returns -2
sys_open returns -2
sys_open returns -2
kretprobe unregistered
Missed 11 sys_open probe instances.
回页首
小结
本文详细地讲解了kprobe的方方面面并给出实际的例子代码帮助读者学习和使用kprobe。本文是系列文章“Linux下的一个全新的性能测量和调式诊断工具 -- Systemtap”之一,有兴趣的读者可以阅读该系列文章之二和三。
+73
View File
@@ -0,0 +1,73 @@
/* kprobe-exam.c */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/kallsyms.h>
#include <linux/sched.h>
#include <linux/time.h>
static struct kprobe kp;
static struct timeval start, end;
static int schedule_counter = 0;
int handler_pre(struct kprobe *p, struct pt_regs *regs)
{
printk("current task on CPU#%d: %s (before scheduling), preempt_count = %d\n", smp_processor_id(), current->comm, preempt_count());
schedule_counter++;
return 0;
}
void handler_post(struct kprobe *p, struct pt_regs *regs, unsigned long flags)
{
printk("current task on CPU#%d: %s (after scheduling), preempt_count = %d\n", smp_processor_id(), current->comm, preempt_count());
}
int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
{
printk("A fault happened during probing.\n");
return 0;
}
int init_module(void)
{
int ret;
kp.pre_handler = handler_pre;
kp.post_handler = handler_post;
kp.fault_handler = handler_fault;
kp.addr = (kprobe_opcode_t*) kallsyms_lookup_name("schedule");
if (kp.addr == NULL)
{
printk("Couldn't get the address of schedule.\n");
return -1;
}
if ((ret = register_kprobe(&kp) < 0))
{
printk("register_kprobe failed, returned %d\n", ret);
return -1;
}
do_gettimeofday(&start);
printk("kprobe registered\n");
return 0;
}
void cleanup_module(void)
{
unregister_kprobe(&kp);
do_gettimeofday(&end);
printk("Scheduling times is %d during of %ld milliseconds.\n", schedule_counter, ((end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec))/1000);
printk("kprobe unregistered\n");
}
MODULE_LICENSE("GPL");
+18
View File
@@ -0,0 +1,18 @@
ifneq ($(KERNELRELEASE),)
obj-m := kretprobe-exam.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
make -C $(KERNELDIR) M=$(PWD) clean
endif
@@ -0,0 +1,48 @@
/*kretprobe-exam.c*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/kallsyms.h>
static struct kretprobe kretp;
static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
// Substitute the appropriate register name for your architecture --
// e.g., regs->rax for x86_64, regs->gpr[3] for ppc64.
int retval = (int) regs->ax;
if (retval < 0) {
printk("sys_open returns %d\n", retval);
}
return 0;
}
int init_module(void)
{
int ret;
kretp.kp.addr = (kprobe_opcode_t *) kallsyms_lookup_name("sys_open");
if (!kretp.kp.addr) {
printk("Couldn't find sys_open.\n");
return -1;
}
kretp.handler = ret_handler,
kretp.maxactive = 1;
if ((ret = register_kretprobe(&kretp)) < 0) {
printk("register_kretprobe failed, returned %d\n", ret);
return -1;
}
printk("Registered a return probe.\n");
return 0;
}
void cleanup_module(void)
{
unregister_kretprobe(&kretp);
printk("kretprobe unregistered\n");
printk("Missed %d sys_open probe instances.\n", kretp.nmissed);
}
MODULE_LICENSE("GPL");
+1
View File
@@ -0,0 +1 @@
kernel//home/gatieme/Work/GitHub/LDD-LinuxDeviceDrivers/study/driver/probe/test.ko
+78
View File
@@ -0,0 +1,78 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
/*
* Jumper probe for do_fork.
* Mirror principle enables access to arguments of the probed routine
* from the probe handler.
*/
/* Proxy routine having the same arguments as actual do_fork() routine */
static long jdo_fork(unsigned long clone_flags, unsigned long stack_start,
struct pt_regs *regs, unsigned long stack_size,
int __user *parent_tidptr, int __user *child_tidptr)
{
printk(KERN_INFO "jprobe: clone_flags = 0x%lx, stack_size = 0x%lx,"
" regs = 0x%p\n",
clone_flags, stack_size, regs);
/* Always end with a call to jprobe_return(). */
jprobe_return();
return 0;
}
asmlinkage __visible void __sched jschedule(void)
{
/* Always end with a call to jprobe_return(). */
jprobe_return();
return 0;
}
static struct jprobe my_jprobe = {
.entry = jschedule,
/* 注意 symbol_name与addr不能同时存在
* 参见kprobe_addr函数--http://lxr.free-electrons.com/source/kernel/kprobes.c#L1359
* 否则会提示参数错误ERR_PTR(-EINVAL);
* 内核中errno的值在http://lxr.free-electrons.com/source/include/uapi/asm-generic/errno-base.h#L25
* */
.kp = {
.symbol_name = "schedule",
//.addr
},
};
static int __init jprobe_init(void)
{
int ret;
//my_jprobe.kp.symbol_name = "_do_fork";
//my_jprobe.kp.addr = kallsyms_lookup_name("_do_fork");
if(my_jprobe.kp.symbol_name == NULL)
{
my_jprobe.kp.addr = (kprobe_opcode_t *)kallsyms_lookup_name("_do_fork");
printk("find _do_fork address at 0x%p\n", my_jprobe.kp.addr);
}
ret = register_jprobe(&my_jprobe);
if (ret < 0) {
printk(KERN_INFO "register_jprobe failed, returned %d\n", ret);
return -1;
}
printk(KERN_INFO "Planted jprobe at %p, handler addr %p\n",
my_jprobe.kp.addr, my_jprobe.entry);
return 0;
}
static void __exit jprobe_exit(void)
{
unregister_jprobe(&my_jprobe);
printk(KERN_INFO "jprobe at %p unregistered\n", my_jprobe.kp.addr);
}
module_init(jprobe_init)
module_exit(jprobe_exit)
MODULE_LICENSE("GPL");
+35
View File
@@ -0,0 +1,35 @@
#include <linux/module.h>
#include <linux/vermagic.h>
#include <linux/compiler.h>
MODULE_INFO(vermagic, VERMAGIC_STRING);
__visible struct module __this_module
__attribute__((section(".gnu.linkonce.this_module"))) = {
.name = KBUILD_MODNAME,
.init = init_module,
#ifdef CONFIG_MODULE_UNLOAD
.exit = cleanup_module,
#endif
.arch = MODULE_ARCH_INIT,
};
static const struct modversion_info ____versions[]
__used
__attribute__((section("__versions"))) = {
{ 0xcd71858e, __VMLINUX_SYMBOL_STR(module_layout) },
{ 0xe16b0d30, __VMLINUX_SYMBOL_STR(unregister_jprobe) },
{ 0xb1bedeb7, __VMLINUX_SYMBOL_STR(register_jprobe) },
{ 0x27e1a049, __VMLINUX_SYMBOL_STR(printk) },
{ 0xe007de41, __VMLINUX_SYMBOL_STR(kallsyms_lookup_name) },
{ 0x1b9aca3f, __VMLINUX_SYMBOL_STR(jprobe_return) },
{ 0xbdfb6dbb, __VMLINUX_SYMBOL_STR(__fentry__) },
};
static const char __module_depends[]
__used
__attribute__((section(".modinfo"))) =
"depends=";
MODULE_INFO(srcversion, "2312B77A1AEAF9D3AA41544");