- 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" },
{}
}