Linux内核:读写配置文件、/proc

2019-07-13 06:56发布

一、介绍       Linux 内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构、改变内核设置的机制。       proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。       它以文件系统的方式为访问系统内核数据的操作提供接口。 二、代码       代码,是在/proc/sys/net/ipv4/下创建目录test_server/,创建文件debug_flag;读写/proc/sys/net/ipv4/test_server/debug_flag,在程序中数据debug_flag值是0,还是1(非0)。 每当来一个数据包时,就会输出一个debug_flag值。 rwproc.h: int config_init(void); int config_exit(void); rwproc.c: #include #include #include #include "rwproc.h" // struct platform_device * test_uio_device; u8 test_uio_driver_flag = 0; static struct ctl_table_header * test_sysctl_header = NULL; // u32 debug_flag = 1; static ctl_table test_sysctl_table[] = { { .ctl_name = 1, .procname = "debug_flag", .data = &debug_flag, .maxlen = sizeof(debug_flag), .mode = 0644, .proc_handler = &proc_dointvec }, { .ctl_name = 0 } }; static ctl_table test_ipv4_table[] = { { .ctl_name = 5002, .procname = "test_server", .mode = 0555, .child = test_sysctl_table }, { .ctl_name = 0 } }; static ctl_table test_net_table[] = { { .ctl_name = NET_IPV4, .procname = "ipv4", .mode = 0555, .child = test_ipv4_table }, { .ctl_name = 0 } }; static ctl_table test_root_table[] = { { .ctl_name = CTL_NET, .procname = "net", .mode = 0555, .child = test_net_table }, { .ctl_name = 0 } }; struct uio_info test_uio_info = { .name = "test_update_uio", .version = "1.0", .irq = UIO_IRQ_NONE, }; int test_drv_probe(struct device * dev) { test_uio_info.mem[0].addr = (unsigned long)kmalloc(4096, GFP_KERNEL); if((void *)test_uio_info.mem[0].addr == NULL) { printk(KERN_DEBUG"test_drv_probe fail 1."); return 501; } test_uio_info.mem[0].memtype = UIO_MEM_LOGICAL; test_uio_info.mem[0].size = 4096; if( uio_register_device(dev, &test_uio_info) ) { printk(KERN_DEBUG"test_drv_probe fail 2."); return 502; } return 0; } int test_drv_remove(struct device * dev) { uio_unregister_device(&test_uio_info); return 0; } struct device_driver test_uio_driver = { .name = "test_update_uio", .bus = &platform_bus_type, .probe = test_drv_probe, .remove = test_drv_remove, }; int config_init(void) { int ret; // test_uio_device = platform_device_register_simple("test_update_uio", -1, NULL, 0); // ret = driver_register(&test_uio_driver); if(ret) { printk(KERN_DEBUG"config_init fail 1."); return 503; } test_uio_driver_flag = 1; // test_sysctl_header = register_sysctl_table(test_root_table); if( test_sysctl_header == NULL ) { printk(KERN_DEBUG"config_init fail 2."); return 504; } return 0; } int config_exit(void) { // if(test_uio_driver_flag) { driver_unregister(&test_uio_driver); } // platform_device_unregister(test_uio_device); // if(test_sysctl_header) { unregister_sysctl_table(test_sysctl_header); } return 0; } main.c: #include #include #include #include #include "rwproc.h" MODULE_LICENSE("GPL"); extern u32 debug_flag; unsigned int hook_mark1(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { if (0==debug_flag) { printk(KERN_DEBUG"debug_flag is 0."); } else if (debug_flag) { printk(KERN_DEBUG"debug_flag is 1."); } return NF_ACCEPT; } static struct nf_hook_ops nfho_marker1; static int init_marker(void) { printk(KERN_DEBUG"enter init_marker."); if (0 != config_init()) { config_exit(); printk(KERN_DEBUG"config_init() error."); return -1; } nfho_marker1.hook=hook_mark1; nfho_marker1.hooknum=NF_INET_PRE_ROUTING; nfho_marker1.pf=PF_INET; nfho_marker1.priority=NF_IP_PRI_LAST; nf_register_hook(&nfho_marker1); return 0; } static void exit_marker(void) { nf_unregister_hook(&nfho_marker1); config_exit(); printk(KERN_DEBUG"leave exit_marker."); } module_init(init_marker); module_exit(exit_marker);

参考资料:       Linux下/proc目录简介:http://blog.csdn.net/zdwzzu2006/article/details/7747977