linux SYSCTL的原理分析

  • 1./proc/sys      support
需要打开内核选项CONFIG_PROC_SYSCTL
fs/proc/root.c
void __init proc_root_init(void)
{
    ...
    proc_sys_init();    //注册/proc/sys
}

#ifdef CONFIG_PROC_SYSCTL
extern int proc_sys_init(void);
extern void sysctl_head_put(struct ctl_table_header *);
#else
static inline void proc_sys_init(void) { }
static inline void sysctl_head_put(struct ctl_table_header *head) { }
#endif

proc-$(CONFIG_PROC_SYSCTL)    += proc_sysctl.o

fs/proc/proc_sysctl.c
int __init proc_sys_init(void)
{
    struct proc_dir_entry *proc_sys_root;
    proc_sys_root = proc_mkdir(" sys ", NULL);
    proc_sys_root->proc_iops = &proc_sys_dir_operations;
    proc_sys_root->proc_fops = &proc_sys_dir_file_operations;
    proc_sys_root->nlink = 0;
    return sysctl_init ();
}


  • 2.实现分析:
kernel/sysctl.c
#ifdef   CONFIG_SYSCTL
int __init sysctl_init(void)
{
    struct ctl_table_header *hdr;
    hdr = register_sysctl_table ( sysctl_base_table );
    kmemleak_not_leak(hdr);
    return 0;
}

#endif /* CONFIG_SYSCTL */

因此可以看出,CONFIG_SYSCTL实际上是在/proc/sys目录下多加一些入口


  • 3.内核需要打开
CONFIG_SYSCTL  配置选项


  • 4.sysctl命令
以前sysctl命令是通过sysctl系统调用实现的,不过新实现的都是通过直接读写proc文件系统实现的
sysctl系统调用的实现:
kernel/sysctl_binary.c
SYSCALL_DEFINE1(sysctl, struct __sysctl_args __user *, args)
{
    do_sysctl();
}


COMPAT_SYSCALL_DEFINE1(sysctl, struct compat_sysctl_args __user *, args)
{
    do_sysctl();
}

static ssize_t do_sysctl (int __user *args_name, int nlen,
    void __user *oldval, size_t oldlen, void __user *newval, size_t newlen)
{
....
    return binary_sysctl (name, nlen, oldval, oldlen, newval, newlen);
}

#ifdef CONFIG_SYSCTL_SYSCALL
binary_sysctl()
{
    pathname = sysctl_getname (name, nlen, &table);
    mnt = task_active_pid_ns(current)-> proc_mnt ;
    file = file_open_root (mnt->mnt_root, mnt, pathname, flags);
........
}
#else /* CONFIG_SYSCTL_SYSCALL */
static ssize_t binary_sysctl(const int *name, int nlen,
    void __user *oldval, size_t oldlen, void __user *newval, size_t newlen)
{
    return -ENOSYS;
}
#endif /* CONFIG_SYSCTL_SYSCALL */

static const struct bin_table *get_sysctl(const int *name, int nlen, char *path)
{
    const struct bin_table *table = & bin_root_table [0];
    int ctl_name;
    /* The binary sysctl tables have a small maximum depth so
     * there is no danger of overflowing our path as it PATH_MAX
     * bytes long.
     */
    memcpy(path, " sys /", 4);
    path += 4;
......
}

因此sysctl系统调用需要CONFIG_SYSCTL_SYSCALL打开,这个系统调用只是把传进来的name根据bin_root_table表转化为/proc/sys下面的路径,然后读写这些文件实现的,而
sysctl_init()则是在/proc/sys下面加入很多入口

可以看出 sysctl系统调用也只是转化了一下路径而已,最终还是得操作/proc/sys下面的文件。



kernel/sysctl_binary.c中可以看到支持的配置目录:
static const struct bin_table bin_root_table [] = {
    { CTL_DIR,    CTL_KERN,    "kernel",     bin_kern_table },      //proc/sys/kernel
    { CTL_DIR,    CTL_VM,        "vm",        bin_vm_table },
    { CTL_DIR,    CTL_NET,    "net",        bin_net_table },             //proc/sys/net
    /* CTL_PROC not used */
    { CTL_DIR,    CTL_FS,        "fs",        bin_fs_table },
    /* CTL_DEBUG "debug" no longer used */
    { CTL_DIR,    CTL_DEV,    "dev",        bin_dev_table },
    { CTL_DIR,    CTL_BUS,    "bus",        bin_bus_table },
    { CTL_DIR,    CTL_ABI,    "abi" },
    /* CTL_CPU not used */
    /* CTL_ARLAN "arlan" no longer used */
    { CTL_DIR,    CTL_S390DBF,    "s390dbf",    bin_s390dbf_table },
    { CTL_DIR,    CTL_SUNRPC,    "sunrpc",    bin_sunrpc_table },
    { CTL_DIR,    CTL_PM,        "pm",        bin_pm_table },
    {}
};


static const struct bin_table bin_kern_table [] = {
    { CTL_STR,    KERN_OSTYPE,            "ostype" },
    { CTL_STR,    KERN_OSRELEASE,            "osrelease" },
    /* KERN_OSREV not used */
    { CTL_STR,    KERN_VERSION,            "version" },
    /* KERN_SECUREMASK not used */
    /* KERN_PROF not used */
    { CTL_STR,    KERN_NODENAME,            "hostname" },
    { CTL_STR,    KERN_DOMAINNAME,        "domainname" },
    { CTL_INT,    KERN_PANIC,            "panic" },
    { CTL_INT,    KERN_REALROOTDEV,        "real-root-dev" },
    { CTL_STR,    KERN_SPARC_REBOOT,        "reboot-cmd" },
    { CTL_INT,    KERN_CTLALTDEL,            " ctrl-alt-del " },
    { CTL_INT,    KERN_PRINTK,            "printk" },
    /* KERN_NAMETRANS not used */
    /* KERN_PPC_HTABRECLAIM not used */
    /* KERN_PPC_ZEROPAGED not used */
    { CTL_INT,    KERN_PPC_POWERSAVE_NAP,        "powersave-nap" },
    { CTL_STR,    KERN_MODPROBE,            "modprobe" },
    { CTL_INT,    KERN_SG_BIG_BUFF,        "sg-big-buff" },
    { CTL_INT,    KERN_ACCT,            "acct" },
    /* KERN_PPC_L2CR "l2cr" no longer used */
    /* KERN_RTSIGNR not used */
    /* KERN_RTSIGMAX not used */
    { CTL_ULONG,    KERN_SHMMAX,            "shmmax" },
    { CTL_INT,    KERN_MSGMAX,            "msgmax" },
    { CTL_INT,    KERN_MSGMNB,            "msgmnb" },
    /* KERN_MSGPOOL not used*/
    { CTL_INT,    KERN_SYSRQ,            "sysrq" },
    { CTL_INT,    KERN_MAX_THREADS,        "threads-max" },
    { CTL_DIR,    KERN_RANDOM,            "random",    bin_random_table },
    { CTL_ULONG,    KERN_SHMALL,            "shmall" },
    { CTL_INT,    KERN_MSGMNI,            "msgmni" },
    { CTL_INT,    KERN_SEM,            "sem" },
    { CTL_INT,    KERN_SPARC_STOP_A,        "stop-a" },
    { CTL_INT,    KERN_SHMMNI,            "shmmni" },
    { CTL_INT,    KERN_OVERFLOWUID,        "overflowuid" },
    { CTL_INT,    KERN_OVERFLOWGID,        "overflowgid" },
    { CTL_STR,    KERN_HOTPLUG,            "hotplug", },
    { CTL_INT,    KERN_IEEE_EMULATION_WARNINGS,    "ieee_emulation_warnings" },
    { CTL_INT,    KERN_S390_USER_DEBUG_LOGGING,    "userprocess_debug" },
    { CTL_INT,    KERN_CORE_USES_PID,        "core_uses_pid" },
    /* KERN_TAINTED "tainted" no longer used */
    { CTL_INT,    KERN_CADPID,            "cad_pid" },
    { CTL_INT,    KERN_PIDMAX,            "pid_max" },
    { CTL_STR,    KERN_CORE_PATTERN,        "core_pattern" },
    { CTL_INT,    KERN_PANIC_ON_OOPS,        "panic_on_oops" },
    { CTL_INT,    KERN_HPPA_PWRSW,        "soft-power" },
    { CTL_INT,    KERN_HPPA_UNALIGNED,        "unaligned-trap" },
    { CTL_INT,    KERN_PRINTK_RATELIMIT,        "printk_ratelimit" },
    { CTL_INT,    KERN_PRINTK_RATELIMIT_BURST,    "printk_ratelimit_burst" },
    { CTL_DIR,    KERN_PTY,            "pty",        bin_pty_table },
    { CTL_INT,    KERN_NGROUPS_MAX,        "ngroups_max" },
    { CTL_INT,    KERN_SPARC_SCONS_PWROFF,    "scons-poweroff" },
    /* KERN_HZ_TIMER "hz_timer" no longer used */
    { CTL_INT,    KERN_UNKNOWN_NMI_PANIC,        "unknown_nmi_panic" },
    { CTL_INT,    KERN_BOOTLOADER_TYPE,        "bootloader_type" },
    { CTL_INT,    KERN_RANDOMIZE,            "randomize_va_space" },
    { CTL_INT,    KERN_SPIN_RETRY,        "spin_retry" },
    /* KERN_ACPI_VIDEO_FLAGS "acpi_video_flags" no longer used */
    { CTL_INT,    KERN_IA64_UNALIGNED,        "ignore-unaligned-usertrap" },
    { CTL_INT,    KERN_COMPAT_LOG,        "compat-log" },
    { CTL_INT,    KERN_MAX_LOCK_DEPTH,        "max_lock_depth" },
    { CTL_INT,    KERN_PANIC_ON_NMI,        "panic_on_unrecovered_nmi" },
    { CTL_INT,    KERN_PANIC_ON_WARN,        "panic_on_warn" },
    {}
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值