From c91dde40bb04569fb796f073be90d51acb416dc7 Mon Sep 17 00:00:00 2001 From: jouyouyun Date: Sat, 9 Jan 2021 21:25:52 +0800 Subject: [PATCH] kernel:module: add radix-tree example --- kernel/modules/radix-tree/Makefile | 11 +++ kernel/modules/radix-tree/radix_tree.c | 131 +++++++++++++++++++++++++ kernel/modules/template/Makefile | 11 +++ kernel/modules/template/template.c | 36 +++++++ misc/struct_pointer.c | 73 ++++++++++++++ 5 files changed, 262 insertions(+) create mode 100644 kernel/modules/radix-tree/Makefile create mode 100644 kernel/modules/radix-tree/radix_tree.c create mode 100644 kernel/modules/template/Makefile create mode 100644 kernel/modules/template/template.c create mode 100644 misc/struct_pointer.c diff --git a/kernel/modules/radix-tree/Makefile b/kernel/modules/radix-tree/Makefile new file mode 100644 index 0000000..e160e9c --- /dev/null +++ b/kernel/modules/radix-tree/Makefile @@ -0,0 +1,11 @@ +obj-m := radix_tree.o +ccflags-y := -std=gnu99 -Wno-declaration-after-statement -O3 +cwd := $(shell pwd) + +kdir := /lib/modules/$(shell uname -r)/build + +all: + make -C ${kdir} M=${cwd} modules + +clean: + make -C ${kdir} M=${cwd} clean diff --git a/kernel/modules/radix-tree/radix_tree.c b/kernel/modules/radix-tree/radix_tree.c new file mode 100644 index 0000000..b267675 --- /dev/null +++ b/kernel/modules/radix-tree/radix_tree.c @@ -0,0 +1,131 @@ +/** + * Copyright (C) 2021 jouyouyun + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * radix_tree.c -- kernel radix-tree example + * + * Written on 星期一, 4 一月 2021. + */ + +#include +#include +#include +#include +#include + +#define FLAG_R 1 << 0 +#define FLAG_W 1 << 1 +#define FLAG_D 1 << 2 + +struct file_node { + unsigned long id; + unsigned int flag; + char *file; +}; + +#define MOD_NAME "radix_tree" +#define DEFAULT_FLAG (FLAG_R | FLAG_W) + +static char *_files[] = { + "/opt/dlp/data/wps/file1.doc", + "/opt/dlp/data/wpa/config.ini", + NULL, +}; + +static unsigned long id_list[2] = {0}; + +RADIX_TREE(_root, 0); + +static struct file_node *make_file_node(const char *file, const int flag) +{ + static size_t node_len = sizeof(struct file_node); + int len = strlen(file); + struct file_node *node = kzalloc(node_len, GFP_KERNEL); + + if (unlikely(node == NULL)) + return NULL; + + node->file = kzalloc(len+1, GFP_KERNEL); + if (unlikely(node->file == NULL)) + goto free; + + node->id = (unsigned long)node; + node->flag = flag; + memcpy(node->file, file, len); + + return node; +free: + kfree(node); + return NULL; +} + +static void free_file_node(struct file_node *node) +{ + kfree(node->file); + kfree(node); +} + +static void lookup_file_node(unsigned long id) +{ + struct file_node *node = NULL; + + node = (struct file_node *)radix_tree_lookup(&_root, id); + if (unlikely(node == NULL)) { + printk("[%s] failed to lookup node: 0x%lx", MOD_NAME, id); + return; + } + + printk("[%s] node value: id(0x%lx), flag(%u), file(%s)", MOD_NAME, node->id, + node->flag, node->file); +} + +int __init mod_init(void) { + int i = 0; + + printk("[%s] init", MOD_NAME); + while (_files[i] != NULL) { + struct file_node *node = make_file_node(_files[i], DEFAULT_FLAG); + if (unlikely(node == NULL)) { + printk("[%s] failed to make file_node for '%s'", MOD_NAME, _files[i]); + i++; + continue; + } + + printk("[%s] insert node: 0x%lx", MOD_NAME, node->id); + radix_tree_insert(&_root, node->id, (void *)node); + id_list[i] = node->id; + i++; + } + + lookup_file_node(id_list[1]); + lookup_file_node(12334); + return 0; +} + +void __exit mod_exit(void) +{ + void **node_ptr = NULL; + struct radix_tree_iter iter; + + printk("[%s] exit", MOD_NAME); + radix_tree_for_each_slot(node_ptr, &_root, &iter, 0) { + struct file_node *node = (struct file_node*)(*node_ptr); + printk("[%s] iter node value: id(0x%lx), flag(%u), file(%s)", MOD_NAME, node->id, + node->flag, node->file); + radix_tree_delete(&_root, node->id); + free_file_node(node); + node = NULL; + } + + printk("[%s] empty: %d", MOD_NAME, radix_tree_empty(&_root)); +} + +module_init(mod_init); +module_exit(mod_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("jouyouyun"); +MODULE_DESCRIPTION("a kernel radix-tree example"); diff --git a/kernel/modules/template/Makefile b/kernel/modules/template/Makefile new file mode 100644 index 0000000..ccfa7ba --- /dev/null +++ b/kernel/modules/template/Makefile @@ -0,0 +1,11 @@ +obj-m := template.o +ccflags-y := -std=gnu99 -Wno-declaration-after-statement -O3 +cwd := $(shell pwd) + +kdir := /lib/modules/$(shell uname -r)/build + +all: + make -C ${kdir} M=${cwd} modules + +clean: + make -C ${kdir} M=${cwd} clean diff --git a/kernel/modules/template/template.c b/kernel/modules/template/template.c new file mode 100644 index 0000000..7cfec8f --- /dev/null +++ b/kernel/modules/template/template.c @@ -0,0 +1,36 @@ +/** + * Copyright (C) 2021 jouyouyun + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * template.c -- template + * + * Written on 星期一, 4 一月 2021. + */ + +#include +#include +#include +#include + +#define MOD_NAME "template" + +int __init mod_init(void) +{ + printk("[%s] init", MOD_NAME); + return 0; +} + +void __exit mod_exit(void) +{ + printk("[%s] exit", MOD_NAME); +} + +module_init(mod_init); +module_exit(mod_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("jouyouyun"); +MODULE_DESCRIPTION("template"); diff --git a/misc/struct_pointer.c b/misc/struct_pointer.c new file mode 100644 index 0000000..e028a8e --- /dev/null +++ b/misc/struct_pointer.c @@ -0,0 +1,73 @@ +#include +#include +#include + +#define FLAG_R 1 << 0 +#define FLAG_W 1 << 1 +#define FLAG_D 1 << 2 + +struct foo1 { + unsigned long id; + unsigned int flag; + char *value; +}; + +static char *files[] = { + "/opt/dlp/data/app1/file1", + "/opt/dlp/data/app2/file1", + NULL, +}; + +#define DEFAULT_FLAG (FLAG_R|FLAG_W|FLAG_D) + +static struct foo1 *make_foo1(const char *filename, unsigned int flag) +{ + struct foo1 *ret = NULL; + int len = strlen(filename); + + ret = calloc(1, sizeof(struct foo1)); + if (!ret) + return NULL; + + ret->value = calloc(len+1, sizeof(char)); + if (!ret->value) + goto free; + + ret->id = (unsigned long)ret; + memcpy(ret->value, filename, len); + ret->flag = flag; + + return ret; +free: + free(ret); + return NULL; +} + +static void free_foo1(struct foo1 *node) +{ + free(node->value); + free(node); + node = NULL; +} + +int main() +{ + int i = 0; + + while (files[i] != NULL) { + struct foo1 *node = make_foo1(files[i], DEFAULT_FLAG); + if (!node) { + printf("failed to make node for '%s'\n", files[i]); + i++; + continue; + } + + printf("node addr: %p\n", node); + printf("node value: 0x%lx, %u, %s\n", node->id, node->flag, node->value); + free_foo1(node); + printf("node free success\n"); + i++; + } + + return 0; +}