From 4b5b3d28409eeaa43e560e2edbcb8fa5fbe5a255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=98=95?= Date: Tue, 30 Jul 2019 18:47:21 +0800 Subject: [PATCH] =?UTF-8?q?Mod=20=20aaa-12=20=E5=A2=9E=E5=8A=A0=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=E7=AE=A1=E7=90=86=E6=A8=A1=E5=9D=97=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E5=8A=9F=E8=83=BD=20RCA=EF=BC=9A=20SOL?= =?UTF-8?q?=EF=BC=9A=20=E4=BF=AE=E6=94=B9=E4=BA=BA=EF=BC=9Ahuangxin=20?= =?UTF-8?q?=E6=A3=80=E8=A7=86=E4=BA=BA=EF=BC=9Ahuangxin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Product/modules/object_manager/Makefile | 4 +- Product/modules/object_manager/obj_api.c | 277 ++++++++++++++++++-- Product/modules/object_manager/obj_api.h | 33 ++- Product/modules/object_manager/server_obj.c | 111 ++++++++ Product/modules/proc_api/proc_api.c | 1 - Product/modules/proc_api/proc_api.h | 2 + 6 files changed, 398 insertions(+), 30 deletions(-) create mode 100644 Product/modules/object_manager/server_obj.c diff --git a/Product/modules/object_manager/Makefile b/Product/modules/object_manager/Makefile index 04538ca99..682958295 100755 --- a/Product/modules/object_manager/Makefile +++ b/Product/modules/object_manager/Makefile @@ -1,6 +1,6 @@ ifneq ($(KERNELRELEASE), ) -obj-m := object.o -object-objs += obj_api.o +obj-m := isg_object.o +isg_object-objs += obj_api.o server_obj.o else #KDIR ?= /opt/fsl-kernel/x86/linux-4.9.140 KDIR ?= /home/hx/raspberrypi/linux diff --git a/Product/modules/object_manager/obj_api.c b/Product/modules/object_manager/obj_api.c index 18525ccc0..2b16afb7b 100644 --- a/Product/modules/object_manager/obj_api.c +++ b/Product/modules/object_manager/obj_api.c @@ -2,54 +2,287 @@ #include #include +#include +#include +#include +#include +#include +#include +#include #include "../proc_api/proc_api.h" #include "obj_api.h" -#define VERSION ("obj0.0.0.2") +#define OBJ_DEV_MAJOR (220) +#define OBJ_DEV_NAME ("isg_objs") +#define VERSION ("obj0.0.0.2") +#define SHM_MEM_SIZE (1024 * 1024) +#define OBJ_DBG_DIR ("obj") -const char* obj_version(void) +typedef struct { + struct class *dev_class; + atomic_t ref_count; + unsigned int mem_size; + unsigned char *mem_buf; +} OBJECT_DRV, *POBJECT_DRV; + +static OBJECT_DRV g_obj_device; +static PCMHI_OBJECT g_obj_data[OBJ_TYPE_MAX] = {NULL, NULL, NULL}; + +static int server_obj_show(struct seq_file *seq, void *token) { - return VERSION; + PCMHI_OBJECT obj, tmp; + PSERVER_OBJ_CONTENT req = NULL; + + seq_printf(seq, "Total server items: %u\n", HASH_COUNT(g_obj_data[OBJ_TYPE_SERVER])); + seq_printf(seq, "API root direcotry: /proc/%s/\n", PROC_API_DIR_NAME); + + HASH_ITER(hh, g_obj_data[OBJ_TYPE_SERVER], obj, tmp) { + seq_printf(seq, " Name: %s\n", obj->name); + seq_printf(seq, " Type: %d\n", obj->type); + seq_printf(seq, " RefCount: %d\n", atomic_read(&obj->ref_count)); + + list_for_each_entry(req, &obj->data->content, list) { + seq_printf(seq, " Min Port: %d\n", req->min_port); + seq_printf(seq, " Max Port: %d\n", req->max_port); + seq_printf(seq, " Pro Port: %d\n", req->pro_type); + } + } + + + + +#if 0 + PPROC_INFO pInfo = NULL, tmp = NULL; + int i = 0; + seq_printf(seq, "Total API items: %u\n", HASH_COUNT(g_proc_items)); + seq_printf(seq, "API root direcotry: /proc/%s/\n", PROC_API_DIR_NAME); + seq_puts(seq, "-------------------------------------" + "-------------------------------------\n"); + seq_puts(seq, "| ID | Direcotry | Name | Show | IOCtrl | Help |\n"); + seq_puts(seq, "|------------------------------------" + "------------------------------------|\n"); + + read_lock(&g_proc_lock); + HASH_ITER(hh, g_proc_items, pInfo, tmp) { + seq_printf(seq, "| %03d | %14s | %14s | %1s | %1s | %1s |\n", + i++, + pInfo->dir_name ? pInfo->dir_name : "", + pInfo->data->name, + pInfo->data->show ? "*" : "-", + pInfo->data->ioctl ? "*" : "-", + pInfo->data->help ? "*" : "-"); + } + read_unlock(&g_proc_lock); +#endif + seq_puts(seq, "-------------------------------------" + "-------------------------------------\n"); + return 0; +} + +static int server_obj_ioctl(struct seq_file *seq, void *token) +{ + PDBGFS_PRIV priv = (PDBGFS_PRIV)(seq->private); + + seq_printf(seq, "Run Command [%s] with (%s)\n", priv->cmd, priv->cmd_data); + return 0; +} + +static int server_obj_help(struct seq_file *seq, void *token) +{ + PDBGFS_PRIV priv = (PDBGFS_PRIV)(seq->private); + seq_puts(seq, "==============Options Helps=============\n"); + seq_printf(seq, "usage: echo \"\" > /proc/%s/%s/%s\n", + PROC_API_DIR_NAME, OBJ_DBG_DIR, priv->name); + + return 0; +} + +static DBGFS_PRIV g_DbgConfig[] = { + { + "server", 0, 0L, NULL, NULL, + server_obj_show, server_obj_ioctl, server_obj_help + }, +}; + +static PROC_API g_object_dbg = { + OBJ_DBG_DIR, g_DbgConfig, sizeof(g_DbgConfig) / sizeof(g_DbgConfig[0]), +}; + +static int obj_proc_init(void) +{ + if(proc_api_register(&g_object_dbg) != ERR_DBGFS_NO_ERROR) { + printk(KERN_ERR "Regisetr %s Error\n", g_object_dbg.dir_name); + return -EINVAL; + } + + return 0; +} + +static int obj_proc_uninit(void) +{ + return proc_api_unregister(&g_object_dbg); +} + +const char *obj_version(void) +{ + return VERSION; +} + +PCMHI_OBJECT new_object(void) +{ + PCMHI_OBJECT obj = (PCMHI_OBJECT)kmalloc(sizeof(CMHI_OBJECT), GFP_KERNEL); + + if(obj == NULL) { + printk(KERN_ERR "Malloc CMHI_OBJECT Error\n"); + } else { + memset(obj, 0, sizeof(CMHI_OBJECT)); + rwlock_init(&obj->lock); + atomic_set(&obj->ref_count, 0); + } + + return obj; +} + +void free_object(PCMHI_OBJECT pObj) +{ + if(pObj) { + kfree(pObj); + } } void object_init(void) { -#if 0 - PCMHI_OBJECT obj, tmp; - int i; - for(i = 0; i < 10; i++) - { - memset(&obj_array[i], 0, sizeof(CMHI_OBJECT)); - sprintf(obj_array[i].name, "obj_%02d", i); - atomic_add(i, &obj_array[i].ref_count); - HASH_ADD_STR(g_objects, name, &obj_array[i]); - } + PCMHI_OBJECT pObj = create_server_object("list1", OBJ_TYPE_SERVER); - HASH_ITER(hh, g_objects, obj, tmp) - { - int val = atomic_read(&(obj->ref_count)); - printk(KERN_ERR "Name = %s, ref_count = %d\n", obj->name, val); - HASH_DEL(g_objects, obj); - } -#endif + if(!pObj) { + printk(KERN_ERR "%s(%d): Create Object Error\n", __FUNCTION__, __LINE__); + return; + } + + HASH_ADD_STR(g_obj_data[OBJ_TYPE_SERVER], name, pObj); + + if(add_server_obj_data(pObj, 10000, 20000, IPPROTO_IP) != 0) { + printk(KERN_ERR "%s(%d): Add Server Object error\n", __FUNCTION__, __LINE__); + return; + } + + if(add_server_obj_data(pObj, 80, 80, IPPROTO_TCP) != 0) { + printk(KERN_ERR "%s(%d): Add Server Object error\n", __FUNCTION__, __LINE__); + return; + } + + if(add_server_obj_data(pObj, 443, 443, IPPROTO_UDP) != 0) { + printk(KERN_ERR "%s(%d): Add Server Object error\n", __FUNCTION__, __LINE__); + return; + } } +void object_uninit(void) +{ + PCMHI_OBJECT obj, tmp; + + HASH_ITER(hh, g_obj_data[OBJ_TYPE_SERVER], obj, tmp) { + HASH_DEL(g_obj_data[OBJ_TYPE_SERVER], obj); + cleanup_server_object(obj); + } +} + +static int obj_open(struct inode *inode, struct file *filp) +{ + atomic_inc(&g_obj_device.ref_count); + return 0; +} + +static int obj_release(struct inode *inode, struct file *filp) +{ + atomic_dec(&g_obj_device.ref_count); + return 0; +} + +int obj_mmap(struct file *fd, struct vm_area_struct *vma) +{ + int ret = remap_pfn_range(vma, vma->vm_start, + virt_to_phys(g_obj_device.mem_buf) >> PAGE_SHIFT, + g_obj_device.mem_size, + PAGE_SHARED); + return ret; +} + +static struct file_operations obj_fops = { + .open = obj_open, + .release = obj_release, + .mmap = obj_mmap, +}; + static int object_module_init(void) { - printk(KERN_ALERT "Hello ISG objects manager version: %s\n", VERSION); + struct page *p = NULL; + printk(KERN_INFO "Hello ISG objects manager version: %s\n", VERSION); + + memset(&g_obj_device, 0, sizeof(OBJECT_DRV)); + atomic_set(&g_obj_device.ref_count, 0); + g_obj_device.mem_size = PAGE_ALIGN(SHM_MEM_SIZE); + g_obj_device.mem_buf = (unsigned char *)__get_free_pages(GFP_KERNEL, get_order(g_obj_device.mem_size)); + + if(g_obj_device.mem_buf == NULL) { + printk(KERN_ERR "Malloc %d pages error\n", get_order(g_obj_device.mem_size)); + return -ENOMEM; + } + + for(p = virt_to_page(g_obj_device.mem_buf); + p < virt_to_page(g_obj_device.mem_buf + g_obj_device.mem_size); + p++) { + SetPageReserved(virt_to_page(p)); + } + + memset(g_obj_device.mem_buf, 0, g_obj_device.mem_size); + register_chrdev(OBJ_DEV_MAJOR, OBJ_DEV_NAME, &obj_fops); + g_obj_device.dev_class = class_create(THIS_MODULE, "obj"); + device_create(g_obj_device.dev_class, NULL, MKDEV(OBJ_DEV_MAJOR, 0), NULL, "obj/dev%d", 0); /* if(proc_api_register(&g_ProcApi) != ERR_DBGFS_NO_ERROR) { printk(KERN_ERR "Regisetr %s Error\n", g_ProcApi.dir_name); } */ + obj_proc_init(); + + object_init(); return 0; } module_init(object_module_init); static void __exit object_module_exit(void) { - printk(KERN_ALERT "Bye ISG objects manager version: %s\n", VERSION); + struct page *p = NULL; + + printk(KERN_INFO "Bye ISG objects manager version: %s\n", VERSION); + + object_uninit(); + + if(atomic_read(&g_obj_device.ref_count) != 0) { + printk(KERN_ERR "Device used, please close it first.\n"); + + while(atomic_read(&g_obj_device.ref_count) != 0) { + schedule(); + } + } + + obj_proc_uninit(); + + if(g_obj_device.mem_buf) { + for(p = virt_to_page(g_obj_device.mem_buf); + p < virt_to_page(g_obj_device.mem_buf + g_obj_device.mem_size); + p++) { + ClearPageReserved(virt_to_page(g_obj_device.mem_buf)); + } + + free_pages((unsigned long)g_obj_device.mem_buf, get_order(g_obj_device.mem_size)); + } + + device_destroy(g_obj_device.dev_class, MKDEV(OBJ_DEV_MAJOR, 0)); + class_destroy(g_obj_device.dev_class); + unregister_chrdev(OBJ_DEV_MAJOR, OBJ_DEV_NAME); // proc_api_unregister(&g_ProcApi); } module_exit(object_module_exit); diff --git a/Product/modules/object_manager/obj_api.h b/Product/modules/object_manager/obj_api.h index de0709d89..cc36e5e87 100644 --- a/Product/modules/object_manager/obj_api.h +++ b/Product/modules/object_manager/obj_api.h @@ -3,26 +3,49 @@ #ifdef __KERNEL__ #include #include +#include #include "../../common/common.h" #include "../../common/uthash.h" +typedef int (*belong_server_objs)(__be32, int); + typedef enum { OBJ_TYPE_ADDR = 0, OBJ_TYPE_SERVER, - OBJ_TYPE_DATETIME + OBJ_TYPE_DATETIME, + OBJ_TYPE_MAX } OBJ_TYPES; +typedef struct { + __be16 min_port; + __be16 max_port; + int pro_type; + struct list_head list; +} SERVER_OBJ_CONTENT, *PSERVER_OBJ_CONTENT; + +typedef struct { + struct list_head content; + + belong_server_objs callback; +} OBJECT_DATA, *POBJECT_DATA; + typedef struct { char name[MAX_NAME_LEN]; OBJ_TYPES type; - void* data; + POBJECT_DATA data; atomic_t ref_count; - struct semaphore lock; - struct list_head list; + rwlock_t lock; + UT_hash_handle hh; } CMHI_OBJECT, *PCMHI_OBJECT; -const char* obj_version(void); +const char *obj_version(void); void object_init(void); +void free_object(PCMHI_OBJECT pObj); +PCMHI_OBJECT new_object(void); + +PCMHI_OBJECT create_server_object(const char *name, OBJ_TYPES type); +void cleanup_server_object(PCMHI_OBJECT pObj); +int add_server_obj_data(PCMHI_OBJECT pObj, __be16 minPort, __be32 maxPort, int proType); #endif #endif \ No newline at end of file diff --git a/Product/modules/object_manager/server_obj.c b/Product/modules/object_manager/server_obj.c new file mode 100644 index 000000000..b8651e5c3 --- /dev/null +++ b/Product/modules/object_manager/server_obj.c @@ -0,0 +1,111 @@ +#ifdef __KERNEL__ + +#include +#include + +#include "obj_api.h" + +static int server_objs_cmp(__be32 port, int proType) +{ + return 0; +} + +static PSERVER_OBJ_CONTENT new_server_content(__be16 minPort, __be16 maxPort, int proType) +{ + PSERVER_OBJ_CONTENT dt = (PSERVER_OBJ_CONTENT)kmalloc(sizeof(SERVER_OBJ_CONTENT), GFP_KERNEL); + + if(!dt) { + printk(KERN_ERR "new_server_data error\n"); + } else { + memset(dt, 0, sizeof(SERVER_OBJ_CONTENT)); + dt->min_port = minPort; + dt->max_port = maxPort; + dt->pro_type = proType; + } + + return dt; +} + +static POBJECT_DATA new_server_object(void) +{ + POBJECT_DATA obj = (POBJECT_DATA)kmalloc(sizeof(POBJECT_DATA), GFP_KERNEL); + + if(obj == NULL) { + printk(KERN_ERR "Malloc CMHI_OBJECT Error\n"); + return NULL; + } + + memset(obj, 0, sizeof(CMHI_OBJECT)); + + obj->callback = server_objs_cmp; + return obj; +} + +int add_server_obj_data(PCMHI_OBJECT pObj, __be16 minPort, __be32 maxPort, int proType) +{ + PSERVER_OBJ_CONTENT dt; + + if(pObj == NULL) { + printk(KERN_ERR "Input pObj is NULL\n"); + return -EINVAL; + } + + dt = new_server_content(minPort, maxPort, proType); + + if(dt == NULL) { + printk(KERN_ERR "Malloc SERVER_OBJ_CONTENT Error\n"); + return -ENOMEM; + } + + write_lock(&pObj->lock); + list_add_tail(&dt->list, &pObj->data->content); + write_unlock(&pObj->lock); + + return 0; +} + +PCMHI_OBJECT create_server_object(const char *name, OBJ_TYPES type) +{ + POBJECT_DATA pObjData = NULL; + PCMHI_OBJECT pObj = new_object(); + + if(!pObj) { + printk(KERN_ERR "create_server_object error\n"); + return NULL; + } + + pObjData = new_server_object(); + + if(!pObjData) { + printk(KERN_ERR "new_server_object error\n"); + kfree(pObj); + return NULL; + } + + strncpy(pObj->name, name, MAX_NAME_LEN - 1); + pObj->type = type; + pObj->data = pObjData; + INIT_LIST_HEAD(&pObj->data->content); + + return pObj; +} + +void cleanup_server_object(PCMHI_OBJECT pObj) +{ + PSERVER_OBJ_CONTENT req = NULL, temp_req = NULL; + + if(!pObj) { + return; + } + + write_lock(&pObj->lock); + list_for_each_entry_safe(req, temp_req, &pObj->data->content, list) { + list_del(&req->list); + kfree(req); + } + kfree(pObj->data); + write_unlock(&pObj->lock); + + kfree(pObj); +} +#endif // __KERNEL__ diff --git a/Product/modules/proc_api/proc_api.c b/Product/modules/proc_api/proc_api.c index 670dfb7cb..62beff988 100644 --- a/Product/modules/proc_api/proc_api.c +++ b/Product/modules/proc_api/proc_api.c @@ -24,7 +24,6 @@ #define HELP_BITS (31) #define IOCTL_BITS (30) -#define PROC_API_DIR_NAME ("isgobj") #define PROC_API_DBG_DIR ("api") typedef struct { diff --git a/Product/modules/proc_api/proc_api.h b/Product/modules/proc_api/proc_api.h index 2cd1a2f80..dba9059d3 100644 --- a/Product/modules/proc_api/proc_api.h +++ b/Product/modules/proc_api/proc_api.h @@ -6,6 +6,8 @@ #include "../../common/common.h" +#define PROC_API_DIR_NAME ("isg") + typedef enum { ERR_DBGFS_NO_ERROR = 0, ERR_PARA_OUTOFRANGE,