zoukankan      html  css  js  c++  java
  • sysctl使用方法的变化

    内核版本:3.6

    Author:zhangskd @ csdn blog


    Change


    在v3.4中包含一个patch,提交者Eric W. Biederman描述如下:

    Rewrite of sysctl for speed and charity.

    Insert/remove/Lookup in sysctl are now O(NlogN) operations, and are no longer bottlenecks in the

    process of adding and removing network devices.

    sysctl is now focused on being a filesystem instead of system call and the code can be found in

    fs/proc/proc_sysctl.c. Hopefully this means the code is now approachable.

    可见sysctl的实现发生了较大的变化。


    但是这对sysctl的使用有什么影响呢?再来看另一个相关patch:

    sysctl: Add register_sysctl for normal sysctl users

    The plan is to convert all callers of register_sysctl_table and register_sysctl_paths to register_sysctl.

    The interface to register_sysctl is enough nicer. This should make the callers a bit more readable.

    Additionally after the conversion the 230 lines of backwards compatibility can be removed.


    可见sysctl的注册函数发生了变化,现在是:

    /**
     * register_sysctl - register a sysctl table
     * @path: The path to the directory the sysctl table is in.
     * @table: the table structure
     *
     * Register a sysctl table. @table should be a filled in ctl_table array.
     * A completely 0 filled entry terminates the table.
     *
     * See __register_sysctl_table for more details.
     */
    
    struct ctl_table_header *register_sysctl (const char *path, struct ctl_table *table);

    之前的注册函数为:

    struct ctl_table_header *register_sysctl_table (struct ctl_table *table);

    也就是说现在可以通过注册函数来指定注册的路径,更加方便了。

     

    注销函数不变:

    /**
     * unregister_sysctl_table - unregister a sysctl table hierarchy
     * @header: the header returned from register_sysctl_table
     *
     * Unregisters the sysctl table and all children. proc entires may not actually
     * be removed until they are no longer used by anyone.
     */
    void unregister_sysctl_table (struct ctl_table_header *header);

     

    structure

     

    现在的ctl_table:

    @include/linux/sysctl.h

    /* A sysctl table is an array of struct ctl_table: */
    struct ctl_table
    {
        const char *procname; /* Text ID for /proc/sys, or zero,文件名 */
        void * data;
        int maxlen;
        umode_t mode;
        struct ctl_table *child; /* Deprecated */
        proc_handler *proc_handler; /* Callback for text formatting,读写操作函数 */
        struct ctl_table_poll *poll;
        void *extra1; /*  变量的最小值min */
        void *extra2; /* 变量的最大值max */
    }
    

    proc_handler的常用取值:

    proc_dointvec      /* 读写一个包含一个或多个整数的数组*/

    proc_dostring      /* 读写一个字符串*/

    proc_dointvec_minmax    /* 写的数组必须在min~max范围内*/

    一个instance:

    @net/ipv4/sysctl_net_ipv4.c

    static struct ctl_table ipv4_table[] = {
        ...
        {
            .procname = "tcp_congestion_control",
            .mode = 0644;
            .maxlen = TCP_CA_NAME_MAX,
            .proc_handler = proc_tcp_congestion_control,
        },
        ...
        {
            .procname = "tcp_early_retrans",
            .data = &sysctl_tcp_early_retrans,
            .maxlen = sizeof(int),
            .mode = 0644,
            .proc_handler = proc_dointvec_minmax,
            .extra1 = &zero,
            .extra2 = &two,
        },
        ...
    };

    这些选项的简要说明在:Documentation/networking/ipv4/*

    这些选项的定义在:net/ipv4/tcp_input.c

    command

    sysctl — configure kernel parameters at runtime

    sysctl is used to modify kernel parameters at runtime. The parameters available are those listed under /proc/sys/.

    Procfs is required for sysctl support in Linux. You can use sysctl to both read and write sysctl data.

    使用:

    sysctl net.ipv4.tcp_congestion_control  // read

    sysctl -w net.ipv4.tcp_congestion_control = "cubic"  // write

    example

    这是新的使用方法示例:

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/sysctl.h>
    #include <linux/kernel.h>
    
    static char path[] = "net/test";
    static int zero = 0;
    static int two = 2;
    int sysctl_tcp_new;
    
    static struct ctl_table_header *header;
    
    static struct ctl_table new[] = {
    	{
    		.procname = "tcp_new",
    		.data = &sysctl_tcp_new,
    		.maxlen = sizeof(int),
    		.mode = 0644,
    		.proc_handler = proc_dointvec_minmax,
    		.extra1 = &zero,
    		.extra2 = &two
    	},
    	{ }
    };
    
    static int __init sysctl_module_init(void)
    {
    	header = register_sysctl(path, new);
    	if(!header) {
    		printk(KERN_ERR"register_sysctl() failed.\n");
    		return -1;
    	}
    	return 0;
    }
    
    static void __exit sysctl_module_exit(void)
    {
    	if(header)
    		unregister_sysctl_table(header);
    }
    
    module_init(sysctl_module_init);
    module_exit(sysctl_module_exit);
    MODULE_AUTHOR("zhangsk");
    MODULE_LICENSE("GPL");

    模块加载时,就自动创建目录/proc/sys/net/test/,并在其下创建文件tcp_new,取值可为0、1或2。

    模块卸载时,此目录则会被删除,当然这是在没人使用了之后。

    这是旧的使用方法示例:

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/sysctl.h>
    
    static int zero = 0;
    static int two = 2;
    int sysctl_tcp_new;
    
    static struct ctl_table_header *header;
    
    static struct ctl_table my_table[] = {
            {
                    .procname = "tcp_new",
                    .data = &sysctl_tcp_new,
                    .maxlen = sizeof(int),
                    .mode = 0644,
                    .proc_handler = proc_dointvec_minmax,
                    .extra1 = &zero,
                    .extra2 = &two, },
            {},
    };
    
    static struct ctl_table test_dir_table[] = {
            {
                    .procname = "test",
                    .mode = 0555,
                    .child = my_table,
            },
            {},
    };
    
    static struct ctl_table net_dir_table[] = {
            {
                    .procname = "net",
                    .mode = 0555,
                    .child = test_dir_table,
            },
            {},
    };
    
    static int __init sysctl_module_init(void)
    {
            header = register_sysctl_table(net_dir_table);
            if(!header) {
                    printk(KERN_ERR"register_sysctl_table() failed.\n");
                    return -1;
            }
            return 0;
    }
    
    static void __exit sysctl_module_exit(void)
    {
            if(header)
                    unregister_sysctl_table(header);
    }
    
    module_init(sysctl_module_init);
    module_exit(sysctl_module_exit);
    MODULE_AUTHOR("zhangsk");
    MODULE_LICENSE("GPL");


  • 相关阅读:
    GIT的使用及心得
    XCODE的演变及使用经验分享
    软件工程学习计划
    这只是一个测试,注意,这只是一个测试
    软工实践---个人
    调研Android开发环境的发展演变
    软件工程的实践项目的自我目标
    调研ANDRIOD平台的开发环境的发展演变
    软件工程的实践项目的自我目标
    Leetcode题库——39.组合总和
  • 原文地址:https://www.cnblogs.com/aiwz/p/6333345.html
Copyright © 2011-2022 走看看