xref: /linux/lib/test_sysctl.c (revision 6cad1ecd4e3213d892b70afa999a81849d1f0206)
1*6cad1ecdSLuis Chamberlain // SPDX-License-Identifier: GPL-2.0-or-later OR copyleft-next-0.3.1
29308f2f9SLuis R. Rodriguez /*
39308f2f9SLuis R. Rodriguez  * proc sysctl test driver
49308f2f9SLuis R. Rodriguez  *
59308f2f9SLuis R. Rodriguez  * Copyright (C) 2017 Luis R. Rodriguez <mcgrof@kernel.org>
69308f2f9SLuis R. Rodriguez  */
79308f2f9SLuis R. Rodriguez 
89308f2f9SLuis R. Rodriguez /*
92d046981SRandy Dunlap  * This module provides an interface to the proc sysctl interfaces.  This
109308f2f9SLuis R. Rodriguez  * driver requires CONFIG_PROC_SYSCTL. It will not normally be loaded by the
119308f2f9SLuis R. Rodriguez  * system unless explicitly requested by name. You can also build this driver
129308f2f9SLuis R. Rodriguez  * into your kernel.
139308f2f9SLuis R. Rodriguez  */
149308f2f9SLuis R. Rodriguez 
159308f2f9SLuis R. Rodriguez #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
169308f2f9SLuis R. Rodriguez 
179308f2f9SLuis R. Rodriguez #include <linux/init.h>
189308f2f9SLuis R. Rodriguez #include <linux/list.h>
199308f2f9SLuis R. Rodriguez #include <linux/module.h>
209308f2f9SLuis R. Rodriguez #include <linux/printk.h>
219308f2f9SLuis R. Rodriguez #include <linux/fs.h>
229308f2f9SLuis R. Rodriguez #include <linux/miscdevice.h>
239308f2f9SLuis R. Rodriguez #include <linux/slab.h>
249308f2f9SLuis R. Rodriguez #include <linux/uaccess.h>
259308f2f9SLuis R. Rodriguez #include <linux/async.h>
269308f2f9SLuis R. Rodriguez #include <linux/delay.h>
279308f2f9SLuis R. Rodriguez #include <linux/vmalloc.h>
289308f2f9SLuis R. Rodriguez 
299308f2f9SLuis R. Rodriguez static int i_zero;
309308f2f9SLuis R. Rodriguez static int i_one_hundred = 100;
3157b19468STonghao Zhang static int match_int_ok = 1;
329308f2f9SLuis R. Rodriguez 
339308f2f9SLuis R. Rodriguez struct test_sysctl_data {
349308f2f9SLuis R. Rodriguez 	int int_0001;
35eb965edaSLuis R. Rodriguez 	int int_0002;
367c43a657SLuis R. Rodriguez 	int int_0003[4];
37eb965edaSLuis R. Rodriguez 
384f2f682dSVlastimil Babka 	int boot_int;
394f2f682dSVlastimil Babka 
402920fad3SLuis R. Rodriguez 	unsigned int uint_0001;
412920fad3SLuis R. Rodriguez 
429308f2f9SLuis R. Rodriguez 	char string_0001[65];
432ea622b8SEric Sandeen 
442ea622b8SEric Sandeen #define SYSCTL_TEST_BITMAP_SIZE	65536
452ea622b8SEric Sandeen 	unsigned long *bitmap_0001;
469308f2f9SLuis R. Rodriguez };
479308f2f9SLuis R. Rodriguez 
489308f2f9SLuis R. Rodriguez static struct test_sysctl_data test_data = {
499308f2f9SLuis R. Rodriguez 	.int_0001 = 60,
50eb965edaSLuis R. Rodriguez 	.int_0002 = 1,
51eb965edaSLuis R. Rodriguez 
527c43a657SLuis R. Rodriguez 	.int_0003[0] = 0,
537c43a657SLuis R. Rodriguez 	.int_0003[1] = 1,
547c43a657SLuis R. Rodriguez 	.int_0003[2] = 2,
557c43a657SLuis R. Rodriguez 	.int_0003[3] = 3,
567c43a657SLuis R. Rodriguez 
574f2f682dSVlastimil Babka 	.boot_int = 0,
584f2f682dSVlastimil Babka 
592920fad3SLuis R. Rodriguez 	.uint_0001 = 314,
602920fad3SLuis R. Rodriguez 
619308f2f9SLuis R. Rodriguez 	.string_0001 = "(none)",
629308f2f9SLuis R. Rodriguez };
639308f2f9SLuis R. Rodriguez 
649308f2f9SLuis R. Rodriguez /* These are all under /proc/sys/debug/test_sysctl/ */
659308f2f9SLuis R. Rodriguez static struct ctl_table test_table[] = {
669308f2f9SLuis R. Rodriguez 	{
679308f2f9SLuis R. Rodriguez 		.procname	= "int_0001",
689308f2f9SLuis R. Rodriguez 		.data		= &test_data.int_0001,
699308f2f9SLuis R. Rodriguez 		.maxlen		= sizeof(int),
709308f2f9SLuis R. Rodriguez 		.mode		= 0644,
719308f2f9SLuis R. Rodriguez 		.proc_handler	= proc_dointvec_minmax,
729308f2f9SLuis R. Rodriguez 		.extra1		= &i_zero,
739308f2f9SLuis R. Rodriguez 		.extra2         = &i_one_hundred,
749308f2f9SLuis R. Rodriguez 	},
759308f2f9SLuis R. Rodriguez 	{
76eb965edaSLuis R. Rodriguez 		.procname	= "int_0002",
77eb965edaSLuis R. Rodriguez 		.data		= &test_data.int_0002,
78eb965edaSLuis R. Rodriguez 		.maxlen		= sizeof(int),
79eb965edaSLuis R. Rodriguez 		.mode		= 0644,
80eb965edaSLuis R. Rodriguez 		.proc_handler	= proc_dointvec,
81eb965edaSLuis R. Rodriguez 	},
82eb965edaSLuis R. Rodriguez 	{
837c43a657SLuis R. Rodriguez 		.procname	= "int_0003",
847c43a657SLuis R. Rodriguez 		.data		= &test_data.int_0003,
857c43a657SLuis R. Rodriguez 		.maxlen		= sizeof(test_data.int_0003),
867c43a657SLuis R. Rodriguez 		.mode		= 0644,
877c43a657SLuis R. Rodriguez 		.proc_handler	= proc_dointvec,
887c43a657SLuis R. Rodriguez 	},
897c43a657SLuis R. Rodriguez 	{
9057b19468STonghao Zhang 		.procname	= "match_int",
9157b19468STonghao Zhang 		.data		= &match_int_ok,
9257b19468STonghao Zhang 		.maxlen		= sizeof(match_int_ok),
9357b19468STonghao Zhang 		.mode		= 0444,
9457b19468STonghao Zhang 		.proc_handler	= proc_dointvec,
9557b19468STonghao Zhang 	},
9657b19468STonghao Zhang 	{
974f2f682dSVlastimil Babka 		.procname	= "boot_int",
984f2f682dSVlastimil Babka 		.data		= &test_data.boot_int,
994f2f682dSVlastimil Babka 		.maxlen		= sizeof(test_data.boot_int),
1004f2f682dSVlastimil Babka 		.mode		= 0644,
1014f2f682dSVlastimil Babka 		.proc_handler	= proc_dointvec,
1024f2f682dSVlastimil Babka 		.extra1		= SYSCTL_ZERO,
1034f2f682dSVlastimil Babka 		.extra2         = SYSCTL_ONE,
1044f2f682dSVlastimil Babka 	},
1054f2f682dSVlastimil Babka 	{
1062920fad3SLuis R. Rodriguez 		.procname	= "uint_0001",
1072920fad3SLuis R. Rodriguez 		.data		= &test_data.uint_0001,
1082920fad3SLuis R. Rodriguez 		.maxlen		= sizeof(unsigned int),
1092920fad3SLuis R. Rodriguez 		.mode		= 0644,
1102920fad3SLuis R. Rodriguez 		.proc_handler	= proc_douintvec,
1112920fad3SLuis R. Rodriguez 	},
1122920fad3SLuis R. Rodriguez 	{
1139308f2f9SLuis R. Rodriguez 		.procname	= "string_0001",
1149308f2f9SLuis R. Rodriguez 		.data		= &test_data.string_0001,
1159308f2f9SLuis R. Rodriguez 		.maxlen		= sizeof(test_data.string_0001),
1169308f2f9SLuis R. Rodriguez 		.mode		= 0644,
1179308f2f9SLuis R. Rodriguez 		.proc_handler	= proc_dostring,
1189308f2f9SLuis R. Rodriguez 	},
1192ea622b8SEric Sandeen 	{
1202ea622b8SEric Sandeen 		.procname	= "bitmap_0001",
1212ea622b8SEric Sandeen 		.data		= &test_data.bitmap_0001,
1222ea622b8SEric Sandeen 		.maxlen		= SYSCTL_TEST_BITMAP_SIZE,
1232ea622b8SEric Sandeen 		.mode		= 0644,
1242ea622b8SEric Sandeen 		.proc_handler	= proc_do_large_bitmap,
1252ea622b8SEric Sandeen 	},
1269308f2f9SLuis R. Rodriguez 	{ }
1279308f2f9SLuis R. Rodriguez };
1289308f2f9SLuis R. Rodriguez 
1299308f2f9SLuis R. Rodriguez static struct ctl_table_header *test_sysctl_header;
1309308f2f9SLuis R. Rodriguez 
1319308f2f9SLuis R. Rodriguez static int __init test_sysctl_init(void)
1329308f2f9SLuis R. Rodriguez {
13357b19468STonghao Zhang 	int i;
13457b19468STonghao Zhang 
13557b19468STonghao Zhang 	struct {
13657b19468STonghao Zhang 		int defined;
13757b19468STonghao Zhang 		int wanted;
13857b19468STonghao Zhang 	} match_int[] = {
13957b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_ZERO,	.wanted = 0},
14057b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_ONE,		.wanted = 1},
14157b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_TWO,		.wanted = 2},
14257b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_THREE,	.wanted = 3},
14357b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_FOUR,	.wanted = 4},
14457b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_ONE_HUNDRED, .wanted = 100},
14557b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_TWO_HUNDRED,	.wanted = 200},
14657b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_ONE_THOUSAND, .wanted = 1000},
14757b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_THREE_THOUSAND, .wanted = 3000},
14857b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_INT_MAX,	.wanted = INT_MAX},
14957b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_MAXOLDUID,	.wanted = 65535},
15057b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_NEG_ONE,	.wanted = -1},
15157b19468STonghao Zhang 	};
15257b19468STonghao Zhang 
15357b19468STonghao Zhang 	for (i = 0; i < ARRAY_SIZE(match_int); i++)
15457b19468STonghao Zhang 		if (match_int[i].defined != match_int[i].wanted)
15557b19468STonghao Zhang 			match_int_ok = 0;
15657b19468STonghao Zhang 
1572ea622b8SEric Sandeen 	test_data.bitmap_0001 = kzalloc(SYSCTL_TEST_BITMAP_SIZE/8, GFP_KERNEL);
1582ea622b8SEric Sandeen 	if (!test_data.bitmap_0001)
1599308f2f9SLuis R. Rodriguez 		return -ENOMEM;
16004bc883cSLuis Chamberlain 	test_sysctl_header = register_sysctl("debug/test_sysctl", test_table);
1612ea622b8SEric Sandeen 	if (!test_sysctl_header) {
1622ea622b8SEric Sandeen 		kfree(test_data.bitmap_0001);
1632ea622b8SEric Sandeen 		return -ENOMEM;
1642ea622b8SEric Sandeen 	}
1659308f2f9SLuis R. Rodriguez 	return 0;
1669308f2f9SLuis R. Rodriguez }
1672f56f845SMasami Hiramatsu module_init(test_sysctl_init);
1689308f2f9SLuis R. Rodriguez 
1699308f2f9SLuis R. Rodriguez static void __exit test_sysctl_exit(void)
1709308f2f9SLuis R. Rodriguez {
1712ea622b8SEric Sandeen 	kfree(test_data.bitmap_0001);
1729308f2f9SLuis R. Rodriguez 	if (test_sysctl_header)
1739308f2f9SLuis R. Rodriguez 		unregister_sysctl_table(test_sysctl_header);
1749308f2f9SLuis R. Rodriguez }
1759308f2f9SLuis R. Rodriguez 
1769308f2f9SLuis R. Rodriguez module_exit(test_sysctl_exit);
1779308f2f9SLuis R. Rodriguez 
1789308f2f9SLuis R. Rodriguez MODULE_AUTHOR("Luis R. Rodriguez <mcgrof@kernel.org>");
1799308f2f9SLuis R. Rodriguez MODULE_LICENSE("GPL");
180