Mod aaa-12 增加对象管理模块服务对象功能

RCA:
SOL:
修改人:huangxin
检视人:huangxin
This commit is contained in:
黄昕 2019-07-30 18:47:21 +08:00
parent ec916db6fb
commit 4b5b3d2840
6 changed files with 398 additions and 30 deletions

View File

@ -1,6 +1,6 @@
ifneq ($(KERNELRELEASE), ) ifneq ($(KERNELRELEASE), )
obj-m := object.o obj-m := isg_object.o
object-objs += obj_api.o isg_object-objs += obj_api.o server_obj.o
else else
#KDIR ?= /opt/fsl-kernel/x86/linux-4.9.140 #KDIR ?= /opt/fsl-kernel/x86/linux-4.9.140
KDIR ?= /home/hx/raspberrypi/linux KDIR ?= /home/hx/raspberrypi/linux

View File

@ -2,54 +2,287 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/fs.h>
#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/device.h>
#include <linux/in.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include "../proc_api/proc_api.h" #include "../proc_api/proc_api.h"
#include "obj_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 \"<params>\" > /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) void object_init(void)
{ {
#if 0 PCMHI_OBJECT pObj = create_server_object("list1", OBJ_TYPE_SERVER);
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]);
}
HASH_ITER(hh, g_objects, obj, tmp) if(!pObj) {
{ printk(KERN_ERR "%s(%d): Create Object Error\n", __FUNCTION__, __LINE__);
int val = atomic_read(&(obj->ref_count)); return;
printk(KERN_ERR "Name = %s, ref_count = %d\n", obj->name, val); }
HASH_DEL(g_objects, obj);
} HASH_ADD_STR(g_obj_data[OBJ_TYPE_SERVER], name, pObj);
#endif
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) 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) { /* if(proc_api_register(&g_ProcApi) != ERR_DBGFS_NO_ERROR) {
printk(KERN_ERR "Regisetr %s Error\n", g_ProcApi.dir_name); printk(KERN_ERR "Regisetr %s Error\n", g_ProcApi.dir_name);
} */ } */
obj_proc_init();
object_init();
return 0; return 0;
} }
module_init(object_module_init); module_init(object_module_init);
static void __exit object_module_exit(void) 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); // proc_api_unregister(&g_ProcApi);
} }
module_exit(object_module_exit); module_exit(object_module_exit);

View File

@ -3,26 +3,49 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <asm/atomic.h> #include <asm/atomic.h>
#include <linux/semaphore.h> #include <linux/semaphore.h>
#include <linux/types.h>
#include "../../common/common.h" #include "../../common/common.h"
#include "../../common/uthash.h" #include "../../common/uthash.h"
typedef int (*belong_server_objs)(__be32, int);
typedef enum { typedef enum {
OBJ_TYPE_ADDR = 0, OBJ_TYPE_ADDR = 0,
OBJ_TYPE_SERVER, OBJ_TYPE_SERVER,
OBJ_TYPE_DATETIME OBJ_TYPE_DATETIME,
OBJ_TYPE_MAX
} OBJ_TYPES; } 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 { typedef struct {
char name[MAX_NAME_LEN]; char name[MAX_NAME_LEN];
OBJ_TYPES type; OBJ_TYPES type;
void* data; POBJECT_DATA data;
atomic_t ref_count; atomic_t ref_count;
struct semaphore lock; rwlock_t lock;
struct list_head list; UT_hash_handle hh;
} CMHI_OBJECT, *PCMHI_OBJECT; } CMHI_OBJECT, *PCMHI_OBJECT;
const char* obj_version(void); const char *obj_version(void);
void object_init(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
#endif #endif

View File

@ -0,0 +1,111 @@
#ifdef __KERNEL__
#include <linux/init.h>
#include <linux/module.h>
#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__

View File

@ -24,7 +24,6 @@
#define HELP_BITS (31) #define HELP_BITS (31)
#define IOCTL_BITS (30) #define IOCTL_BITS (30)
#define PROC_API_DIR_NAME ("isgobj")
#define PROC_API_DBG_DIR ("api") #define PROC_API_DBG_DIR ("api")
typedef struct { typedef struct {

View File

@ -6,6 +6,8 @@
#include "../../common/common.h" #include "../../common/common.h"
#define PROC_API_DIR_NAME ("isg")
typedef enum { typedef enum {
ERR_DBGFS_NO_ERROR = 0, ERR_DBGFS_NO_ERROR = 0,
ERR_PARA_OUTOFRANGE, ERR_PARA_OUTOFRANGE,