Mod aaa-12 增加对象管理模块服务对象功能
RCA: SOL: 修改人:huangxin 检视人:huangxin
This commit is contained in:
parent
ec916db6fb
commit
4b5b3d2840
|
@ -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
|
||||
|
|
|
@ -2,54 +2,287 @@
|
|||
|
||||
#include <linux/init.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 "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)
|
||||
{
|
||||
#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);
|
||||
|
|
|
@ -3,26 +3,49 @@
|
|||
#ifdef __KERNEL__
|
||||
#include <asm/atomic.h>
|
||||
#include <linux/semaphore.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#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
|
|
@ -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__
|
|
@ -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 {
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "../../common/common.h"
|
||||
|
||||
#define PROC_API_DIR_NAME ("isg")
|
||||
|
||||
typedef enum {
|
||||
ERR_DBGFS_NO_ERROR = 0,
|
||||
ERR_PARA_OUTOFRANGE,
|
||||
|
|
Loading…
Reference in New Issue