⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysctl.c

📁 Kernel code of linux kernel
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef CONFIG_NUMA	{		.ctl_name	= VM_ZONE_RECLAIM_MODE,		.procname	= "zone_reclaim_mode",		.data		= &zone_reclaim_mode,		.maxlen		= sizeof(zone_reclaim_mode),		.mode		= 0644,		.proc_handler	= &proc_dointvec,		.strategy	= &sysctl_intvec,		.extra1		= &zero,	},	{		.ctl_name	= VM_MIN_UNMAPPED,		.procname	= "min_unmapped_ratio",		.data		= &sysctl_min_unmapped_ratio,		.maxlen		= sizeof(sysctl_min_unmapped_ratio),		.mode		= 0644,		.proc_handler	= &sysctl_min_unmapped_ratio_sysctl_handler,		.strategy	= &sysctl_intvec,		.extra1		= &zero,		.extra2		= &one_hundred,	},	{		.ctl_name	= VM_MIN_SLAB,		.procname	= "min_slab_ratio",		.data		= &sysctl_min_slab_ratio,		.maxlen		= sizeof(sysctl_min_slab_ratio),		.mode		= 0644,		.proc_handler	= &sysctl_min_slab_ratio_sysctl_handler,		.strategy	= &sysctl_intvec,		.extra1		= &zero,		.extra2		= &one_hundred,	},#endif#ifdef CONFIG_SMP	{		.ctl_name	= CTL_UNNUMBERED,		.procname	= "stat_interval",		.data		= &sysctl_stat_interval,		.maxlen		= sizeof(sysctl_stat_interval),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,		.strategy	= &sysctl_jiffies,	},#endif#ifdef CONFIG_SECURITY	{		.ctl_name	= CTL_UNNUMBERED,		.procname	= "mmap_min_addr",		.data		= &mmap_min_addr,		.maxlen         = sizeof(unsigned long),		.mode		= 0644,		.proc_handler	= &proc_doulongvec_minmax,	},#endif#ifdef CONFIG_NUMA	{		.ctl_name	= CTL_UNNUMBERED,		.procname	= "numa_zonelist_order",		.data		= &numa_zonelist_order,		.maxlen		= NUMA_ZONELIST_ORDER_LEN,		.mode		= 0644,		.proc_handler	= &numa_zonelist_order_handler,		.strategy	= &sysctl_string,	},#endif#if (defined(CONFIG_X86_32) && !defined(CONFIG_UML))|| \   (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL))	{		.ctl_name	= VM_VDSO_ENABLED,		.procname	= "vdso_enabled",		.data		= &vdso_enabled,		.maxlen		= sizeof(vdso_enabled),		.mode		= 0644,		.proc_handler	= &proc_dointvec,		.strategy	= &sysctl_intvec,		.extra1		= &zero,	},#endif#ifdef CONFIG_HIGHMEM	{		.ctl_name	= CTL_UNNUMBERED,		.procname	= "highmem_is_dirtyable",		.data		= &vm_highmem_is_dirtyable,		.maxlen		= sizeof(vm_highmem_is_dirtyable),		.mode		= 0644,		.proc_handler	= &proc_dointvec_minmax,		.strategy	= &sysctl_intvec,		.extra1		= &zero,		.extra2		= &one,	},#endif/* * NOTE: do not add new entries to this table unless you have read * Documentation/sysctl/ctl_unnumbered.txt */	{ .ctl_name = 0 }};#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)static struct ctl_table binfmt_misc_table[] = {	{ .ctl_name = 0 }};#endifstatic struct ctl_table fs_table[] = {	{		.ctl_name	= FS_NRINODE,		.procname	= "inode-nr",		.data		= &inodes_stat,		.maxlen		= 2*sizeof(int),		.mode		= 0444,		.proc_handler	= &proc_dointvec,	},	{		.ctl_name	= FS_STATINODE,		.procname	= "inode-state",		.data		= &inodes_stat,		.maxlen		= 7*sizeof(int),		.mode		= 0444,		.proc_handler	= &proc_dointvec,	},	{		.procname	= "file-nr",		.data		= &files_stat,		.maxlen		= 3*sizeof(int),		.mode		= 0444,		.proc_handler	= &proc_nr_files,	},	{		.ctl_name	= FS_MAXFILE,		.procname	= "file-max",		.data		= &files_stat.max_files,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec,	},	{		.ctl_name	= CTL_UNNUMBERED,		.procname	= "nr_open",		.data		= &sysctl_nr_open,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_minmax,		.extra1		= &sysctl_nr_open_min,		.extra2		= &sysctl_nr_open_max,	},	{		.ctl_name	= FS_DENTRY,		.procname	= "dentry-state",		.data		= &dentry_stat,		.maxlen		= 6*sizeof(int),		.mode		= 0444,		.proc_handler	= &proc_dointvec,	},	{		.ctl_name	= FS_OVERFLOWUID,		.procname	= "overflowuid",		.data		= &fs_overflowuid,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_minmax,		.strategy	= &sysctl_intvec,		.extra1		= &minolduid,		.extra2		= &maxolduid,	},	{		.ctl_name	= FS_OVERFLOWGID,		.procname	= "overflowgid",		.data		= &fs_overflowgid,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_minmax,		.strategy	= &sysctl_intvec,		.extra1		= &minolduid,		.extra2		= &maxolduid,	},	{		.ctl_name	= FS_LEASES,		.procname	= "leases-enable",		.data		= &leases_enable,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec,	},#ifdef CONFIG_DNOTIFY	{		.ctl_name	= FS_DIR_NOTIFY,		.procname	= "dir-notify-enable",		.data		= &dir_notify_enable,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec,	},#endif#ifdef CONFIG_MMU	{		.ctl_name	= FS_LEASE_TIME,		.procname	= "lease-break-time",		.data		= &lease_break_time,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_minmax,		.strategy	= &sysctl_intvec,		.extra1		= &zero,		.extra2		= &two,	},	{		.procname	= "aio-nr",		.data		= &aio_nr,		.maxlen		= sizeof(aio_nr),		.mode		= 0444,		.proc_handler	= &proc_doulongvec_minmax,	},	{		.procname	= "aio-max-nr",		.data		= &aio_max_nr,		.maxlen		= sizeof(aio_max_nr),		.mode		= 0644,		.proc_handler	= &proc_doulongvec_minmax,	},#ifdef CONFIG_INOTIFY_USER	{		.ctl_name	= FS_INOTIFY,		.procname	= "inotify",		.mode		= 0555,		.child		= inotify_table,	},#endif	#endif	{		.ctl_name	= KERN_SETUID_DUMPABLE,		.procname	= "suid_dumpable",		.data		= &suid_dumpable,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec,	},#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)	{		.ctl_name	= CTL_UNNUMBERED,		.procname	= "binfmt_misc",		.mode		= 0555,		.child		= binfmt_misc_table,	},#endif/* * NOTE: do not add new entries to this table unless you have read * Documentation/sysctl/ctl_unnumbered.txt */	{ .ctl_name = 0 }};static struct ctl_table debug_table[] = {#if defined(CONFIG_X86) || defined(CONFIG_PPC)	{		.ctl_name	= CTL_UNNUMBERED,		.procname	= "exception-trace",		.data		= &show_unhandled_signals,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= proc_dointvec	},#endif	{ .ctl_name = 0 }};static struct ctl_table dev_table[] = {	{ .ctl_name = 0 }};static DEFINE_SPINLOCK(sysctl_lock);/* called under sysctl_lock */static int use_table(struct ctl_table_header *p){	if (unlikely(p->unregistering))		return 0;	p->used++;	return 1;}/* called under sysctl_lock */static void unuse_table(struct ctl_table_header *p){	if (!--p->used)		if (unlikely(p->unregistering))			complete(p->unregistering);}/* called under sysctl_lock, will reacquire if has to wait */static void start_unregistering(struct ctl_table_header *p){	/*	 * if p->used is 0, nobody will ever touch that entry again;	 * we'll eliminate all paths to it before dropping sysctl_lock	 */	if (unlikely(p->used)) {		struct completion wait;		init_completion(&wait);		p->unregistering = &wait;		spin_unlock(&sysctl_lock);		wait_for_completion(&wait);		spin_lock(&sysctl_lock);	} else {		/* anything non-NULL; we'll never dereference it */		p->unregistering = ERR_PTR(-EINVAL);	}	/*	 * do not remove from the list until nobody holds it; walking the	 * list in do_sysctl() relies on that.	 */	list_del_init(&p->ctl_entry);}void sysctl_head_get(struct ctl_table_header *head){	spin_lock(&sysctl_lock);	head->count++;	spin_unlock(&sysctl_lock);}void sysctl_head_put(struct ctl_table_header *head){	spin_lock(&sysctl_lock);	if (!--head->count)		kfree(head);	spin_unlock(&sysctl_lock);}struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head){	if (!head)		BUG();	spin_lock(&sysctl_lock);	if (!use_table(head))		head = ERR_PTR(-ENOENT);	spin_unlock(&sysctl_lock);	return head;}void sysctl_head_finish(struct ctl_table_header *head){	if (!head)		return;	spin_lock(&sysctl_lock);	unuse_table(head);	spin_unlock(&sysctl_lock);}static struct ctl_table_set *lookup_header_set(struct ctl_table_root *root, struct nsproxy *namespaces){	struct ctl_table_set *set = &root->default_set;	if (root->lookup)		set = root->lookup(root, namespaces);	return set;}static struct list_head *lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces){	struct ctl_table_set *set = lookup_header_set(root, namespaces);	return &set->list;}struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces,					    struct ctl_table_header *prev){	struct ctl_table_root *root;	struct list_head *header_list;	struct ctl_table_header *head;	struct list_head *tmp;	spin_lock(&sysctl_lock);	if (prev) {		head = prev;		tmp = &prev->ctl_entry;		unuse_table(prev);		goto next;	}	tmp = &root_table_header.ctl_entry;	for (;;) {		head = list_entry(tmp, struct ctl_table_header, ctl_entry);		if (!use_table(head))			goto next;		spin_unlock(&sysctl_lock);		return head;	next:		root = head->root;		tmp = tmp->next;		header_list = lookup_header_list(root, namespaces);		if (tmp != header_list)			continue;		do {			root = list_entry(root->root_list.next,					struct ctl_table_root, root_list);			if (root == &sysctl_table_root)				goto out;			header_list = lookup_header_list(root, namespaces);		} while (list_empty(header_list));		tmp = header_list->next;	}out:	spin_unlock(&sysctl_lock);	return NULL;}struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev){	return __sysctl_head_next(current->nsproxy, prev);}void register_sysctl_root(struct ctl_table_root *root){	spin_lock(&sysctl_lock);	list_add_tail(&root->root_list, &sysctl_table_root.root_list);	spin_unlock(&sysctl_lock);}#ifdef CONFIG_SYSCTL_SYSCALL/* Perform the actual read/write of a sysctl table entry. */static int do_sysctl_strategy(struct ctl_table_root *root,			struct ctl_table *table,			int __user *name, int nlen,			void __user *oldval, size_t __user *oldlenp,			void __user *newval, size_t newlen){	int op = 0, rc;	if (oldval)		op |= MAY_READ;	if (newval)		op |= MAY_WRITE;	if (sysctl_perm(root, table, op))		return -EPERM;	if (table->strategy) {		rc = table->strategy(table, name, nlen, oldval, oldlenp,				     newval, newlen);		if (rc < 0)			return rc;		if (rc > 0)			return 0;	}	/* If there is no strategy routine, or if the strategy returns	 * zero, proceed with automatic r/w */	if (table->data && table->maxlen) {		rc = sysctl_data(table, name, nlen, oldval, oldlenp,				 newval, newlen);		if (rc < 0)			return rc;	}	return 0;}static int parse_table(int __user *name, int nlen,		       void __user *oldval, size_t __user *oldlenp,		       void __user *newval, size_t newlen,		       struct ctl_table_root *root,		       struct ctl_table *table){	int n;repeat:	if (!nlen)		return -ENOTDIR;	if (get_user(n, name))		return -EFAULT;	for ( ; table->ctl_name || table->procname; table++) {		if (!table->ctl_name)			continue;		if (n == table->ctl_name) {			int error;			if (table->child) {				if (sysctl_perm(root, table, MAY_EXEC))					return -EPERM;				name++;				nlen--;				table = table->child;				goto repeat;			}			error = do_sysctl_strategy(root, table, name, nlen,						   oldval, oldlenp,						   newval, newlen);			return error;		}	}	return -ENOTDIR;}int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp,	       void __user *newval, size_t newlen){	struct ctl_table_header *head;	int error = -ENOTDIR;	if (nlen <= 0 || nlen >= CTL_MAXNAME)		return -ENOTDIR;	if (oldval) {		int old_len;		if (!oldlenp || get_user(old_len, oldlenp))			return -EFAULT;	}	for (head = sysctl_head_next(NULL); head;			head = sysctl_head_next(head)) {		error = parse_table(name, nlen, oldval, oldlenp, 					newval, newlen,					head->root, head->ctl_table);		if (error != -ENOTDIR) {			sysctl_head_finish(head);			break;		}	}	return error;}asmlinkage long sys_sysctl(struct __sysctl_args __user *args){	struct __sysctl_args tmp;	int error;	if (copy_from_user(&tmp, args, sizeof(tmp)))		return -EFAULT;	error = deprecated_sysctl_warning(&tmp);	if (error)		goto out;	lock_kernel();	error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp,			  tmp.newval, tmp.newlen);	unlock_kernel();out:	return error;}#endif /* CONFIG_SYSCTL_SYSCALL *//* * sysctl_perm does NOT grant the superuser all rights automatically, because

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -